Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Хованский Дмитрий. Задача 2. Вариант 16. Ленточная вертикальная схема. #395

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

Kvoks
Copy link
Contributor

@Kvoks Kvoks commented Nov 29, 2024

Задача умножения матрицы на вектор заключается в том, чтобы вычислить результирующий вектор, каждый элемент которого представляет собой скалярное произведение строки матрицы на входной вектор. При использовании ленточной вертикальной схемы элементы матрицы распределяются между процессами по колонкам. Алгоритм предполагает распределение данных и вычислений для повышения производительности.

Описание последовательной задачи:

  1. Инициализация данных:
    Матрица и вектор загружаются в память из входных данных. Проверяется согласованность размеров.

  2. Вычисление результата:
    Выполняется обход строк матрицы. Для каждой строки происходит умножение её элементов на соответствующий элемент входного вектора и суммирование результата.

  3. Сохранение результата:
    Результирующий вектор сохраняется и передаётся в выходные данные.

Описание MPI задачи:

  1. Разделение данных:
    Процесс с рангом 0 делит матрицу вертикально по колонкам, распределяя блоки между всеми процессами. Вектор, который участвует в умножении, также передаётся всем процессам.

  2. Передача данных:
    Матрица и вектор пересылаются всем процессам с использованием механизма broadcast. Каждый процесс получает свои столбцы матрицы для дальнейших вычислений.

  3. Вычисления на процессах:
    Каждый процесс умножает полученные столбцы матрицы на входной вектор, формируя локальные частичные результаты.

  4. Сбор результатов:
    Локальные результаты суммируются в процессе с рангом 0 с использованием операции reduce. Итоговый вектор формируется как сумма всех частичных результатов.

  5. Сохранение результата:
    Процесс с рангом 0 сохраняет окончательный результат во выходные данные.

@codecov-commenter
Copy link

codecov-commenter commented Nov 29, 2024

Codecov Report

Attention: Patch coverage is 61.81818% with 42 lines in your changes missing coverage. Please review.

Project coverage is 95.96%. Comparing base (b456b24) to head (71f11f2).

Files with missing lines Patch % Lines
...khovansky_d_ribbon_vertical_scheme/src/ops_mpi.cpp 51.21% 33 Missing and 7 partials ⚠️
...ansky_d_ribbon_vertical_scheme/include/ops_mpi.hpp 50.00% 1 Missing ⚠️
...khovansky_d_ribbon_vertical_scheme/src/ops_seq.cpp 96.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #395      +/-   ##
==========================================
- Coverage   96.31%   95.96%   -0.36%     
==========================================
  Files         437      441       +4     
  Lines       11236    11346     +110     
  Branches     4739     4782      +43     
==========================================
+ Hits        10822    10888      +66     
- Misses        136      170      +34     
- Partials      278      288      +10     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@venn2713 venn2713 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Наработки неплохие, но вот момент с передачей матрицы и вектора через бродкаст смущает. Возможно на неэффективный алгоритм потянет. А там можно было бы хранить матрицу в столбцовом виде, тоесть не {1, 2, 3, 4, 5, 6, 7, 8, 9} матрицу 3x3 а {1, 4, 7, 2, 5, 8, 3, 6, 9 } и тогда можно было бы рассчитать так же sizes и displs и воспользоваться scatterv, каждый воркер обработал бы свой массив данных. Тоесть для обработки первого столбца тебе было бы достаточно передать от матрицы {1, 4, 7} и от вектора первый элемент. Так ты сэкономил бы сильно по памяти

Comment on lines 130 to 133
boost::mpi::broadcast(world, rows_count, 0);
boost::mpi::broadcast(world, columns_count, 0);
boost::mpi::broadcast(world, rows_per_process, 0);
boost::mpi::broadcast(world, rows_offsets, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вам не следует использовать mpi функции внутри pre_processing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx, fixed

Comment on lines 135 to 139
if (world.rank() != 0) {
hello_matrix.resize(columns_count * rows_count, 0);
hello_vector.resize(rows_count, 0);
goodbye_vector.resize(columns_count, 0);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не считаю это корректным, вы уже ранее заполнили вектора через assign

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx, fixed

Comment on lines +145 to +146
boost::mpi::broadcast(world, hello_matrix, 0);
boost::mpi::broadcast(world, hello_vector, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ваша реализация не соответствует заданию, передавая всю матрицу вы не выполняете ленточное вертикальное разбиение. Если процесс 0 обрабатывает первые 2 столбца, то их он и должен получить

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the comment, but I don't fully agree. Despite the full transfer of matrix data, each process processes only the part allocated to it, thus the logic of partitioning and parallelization is observed.

taskDataSeq->outputs_count.emplace_back(result.size());

khovansky_d_ribbon_vertical_scheme_seq::RibbonVerticalSchemeSeq ribbonVerticalSchemeSeq(taskDataSeq);
ASSERT_EQ(ribbonVerticalSchemeSeq.validation(), false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Последняя функция внутри TEST желательно чтобы была EXPECT, и есть EXPECT_FALSE и аналогично для TRUE если вы их ожидаете.
Далее по документу по аналогии для всех тестов

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx, fixed

Comment on lines 22 to 41
if (proc_count > rows_count) {
for (int i = 0; i < rows_count; ++i) {
rows_offsets[i] = i * columns_count;
rows_per_process[i] = columns_count;
}
} else {
int rows_count_per_proc = rows_count / proc_count;
int remainder = rows_count % proc_count;
int offset = 0;
for (int i = 0; i < proc_count; ++i) {
if (remainder > 0) {
rows_per_process[i] = (rows_count_per_proc + 1) * columns_count;
--remainder;
} else {
rows_per_process[i] = rows_count_per_proc * columns_count;
}
rows_offsets[i] = offset;
offset += rows_per_process[i];
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move duplicate code into a separate function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx, fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants