From 2dacdc36d9a5a7a91443e2fbdd076d7c98f611bc Mon Sep 17 00:00:00 2001 From: ivan-sannikov Date: Thu, 13 Nov 2025 11:33:57 +0300 Subject: [PATCH 01/15] compleate task --- .../common/include/common.hpp | 16 +++ tasks/sannikov_i_column_sum/data/pic.jpg | Bin 0 -> 15356 bytes tasks/sannikov_i_column_sum/info.json | 9 ++ .../mpi/include/ops_mpi.hpp | 22 ++++ .../sannikov_i_column_sum/mpi/src/ops_mpi.cpp | 99 ++++++++++++++++++ tasks/sannikov_i_column_sum/report.md | 0 .../seq/include/ops_seq.hpp | 22 ++++ .../sannikov_i_column_sum/seq/src/ops_seq.cpp | 44 ++++++++ tasks/sannikov_i_column_sum/settings.json | 7 ++ tasks/sannikov_i_column_sum/tests/.clang-tidy | 13 +++ .../tests/functional/main.cpp | 81 ++++++++++++++ .../tests/performance/main.cpp | 50 +++++++++ 12 files changed, 363 insertions(+) create mode 100644 tasks/sannikov_i_column_sum/common/include/common.hpp create mode 100644 tasks/sannikov_i_column_sum/data/pic.jpg create mode 100644 tasks/sannikov_i_column_sum/info.json create mode 100644 tasks/sannikov_i_column_sum/mpi/include/ops_mpi.hpp create mode 100644 tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp create mode 100644 tasks/sannikov_i_column_sum/report.md create mode 100644 tasks/sannikov_i_column_sum/seq/include/ops_seq.hpp create mode 100644 tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp create mode 100644 tasks/sannikov_i_column_sum/settings.json create mode 100644 tasks/sannikov_i_column_sum/tests/.clang-tidy create mode 100644 tasks/sannikov_i_column_sum/tests/functional/main.cpp create mode 100644 tasks/sannikov_i_column_sum/tests/performance/main.cpp diff --git a/tasks/sannikov_i_column_sum/common/include/common.hpp b/tasks/sannikov_i_column_sum/common/include/common.hpp new file mode 100644 index 0000000000..32f5d69a25 --- /dev/null +++ b/tasks/sannikov_i_column_sum/common/include/common.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include +#include +#include + +#include "task/include/task.hpp" + +namespace sannikov_i_column_sum { + +using InType = std::vector>; +using OutType = std::vector; +using TestType = std::tuple>, std::string>; +using BaseTask = ppc::task::Task; + +} // namespace sannikov_i_column_sum diff --git a/tasks/sannikov_i_column_sum/data/pic.jpg b/tasks/sannikov_i_column_sum/data/pic.jpg new file mode 100644 index 0000000000000000000000000000000000000000..34458023494a39d66880a98aa5dcad18eb14b249 GIT binary patch literal 15356 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 + +#include +#include + +#include "sannikov_i_column_sum/common/include/common.hpp" +#include "util/include/util.hpp" + + + +namespace sannikov_i_column_sum { + +SannikovIColumnSumMPI::SannikovIColumnSumMPI(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; + GetOutput().clear(); +} + +bool SannikovIColumnSumMPI::ValidationImpl() { + return (!GetInput().empty()) && (GetInput().front().size() != 0) && (GetOutput().empty()); +} + +bool SannikovIColumnSumMPI::PreProcessingImpl() { + int rank = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + int columns = 0; + if (rank == 0) { + if (GetInput().empty()) return false; + columns = (GetInput().front().size()); + } + MPI_Bcast(&columns, 1, MPI_INT, 0, MPI_COMM_WORLD); + if (columns <= 0) return false; + GetOutput().resize((columns), 0); + return !GetOutput().empty(); +} + +bool SannikovIColumnSumMPI::RunImpl() { + if (GetInput().empty()) { + return false; + } + int rank = 0; + int size = 1; + size_t rows = 0; + size_t columns = (GetOutput().size()); + + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + if (rank == 0) { + if (GetInput().empty() || (size_t)GetInput().front().size() != columns) + return false; + rows = (GetInput().size()); + } + + MPI_Bcast(&rows, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast(&columns, 1, MPI_INT, 0, MPI_COMM_WORLD); + if (rows <= 0 || columns <= 0) return false; + size_t rem = rows % size; + size_t pad = (rem == 0) ? 0 : (size - rem); + size_t total_rows = rows +pad; + size_t rows_per_proc = total_rows / size; + std::vector sendbuf; + if(rank == 0){ + sendbuf.resize((total_rows*columns)); + for(size_t i=0;i recvbuf((rows_per_proc*columns), 0); + MPI_Scatter(rank == 0 ? sendbuf.data() : nullptr, rows_per_proc*columns, MPI_INT, recvbuf.data(), rows_per_proc*columns, MPI_INT, 0, MPI_COMM_WORLD); + std::vector sum((columns), 0); + for(size_t i = 0; i < rows_per_proc; i++){ + int local_id = i *columns; + for(size_t j = 0; j +#include + +#include "sannikov_i_column_sum/common/include/common.hpp" +#include "util/include/util.hpp" + +namespace sannikov_i_column_sum { + +SannikovIColumnSumSEQ::SannikovIColumnSumSEQ(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; + GetOutput().clear(); +} + +bool SannikovIColumnSumSEQ::ValidationImpl() { + return (!GetInput().empty()) && (GetInput().front().size() != 0) && (GetOutput().empty()); +} + +bool SannikovIColumnSumSEQ::PreProcessingImpl() { + GetOutput().resize(GetInput().front().size(), 0); + return !GetOutput().empty(); +} + +bool SannikovIColumnSumSEQ::RunImpl() { + if (GetInput().empty()) { + return false; + } + + for (size_t i = 0; i < (size_t)GetInput().size(); i++) { + for (size_t j = 0; j < (size_t)GetInput()[i].size(); j++) { + GetOutput()[j] += GetInput()[i][j]; + } + } + + return !GetOutput().empty(); +} + +bool SannikovIColumnSumSEQ::PostProcessingImpl() { + return !GetOutput().empty(); +} + +} // namespace sannikov_i_column_sum diff --git a/tasks/sannikov_i_column_sum/settings.json b/tasks/sannikov_i_column_sum/settings.json new file mode 100644 index 0000000000..b1a0d52574 --- /dev/null +++ b/tasks/sannikov_i_column_sum/settings.json @@ -0,0 +1,7 @@ +{ + "tasks_type": "processes", + "tasks": { + "mpi": "enabled", + "seq": "enabled" + } +} diff --git a/tasks/sannikov_i_column_sum/tests/.clang-tidy b/tasks/sannikov_i_column_sum/tests/.clang-tidy new file mode 100644 index 0000000000..ef43b7aa8a --- /dev/null +++ b/tasks/sannikov_i_column_sum/tests/.clang-tidy @@ -0,0 +1,13 @@ +InheritParentConfig: true + +Checks: > + -modernize-loop-convert, + -cppcoreguidelines-avoid-goto, + -cppcoreguidelines-avoid-non-const-global-variables, + -misc-use-anonymous-namespace, + -modernize-use-std-print, + -modernize-type-traits + +CheckOptions: + - key: readability-function-cognitive-complexity.Threshold + value: 50 # Relaxed for tests diff --git a/tasks/sannikov_i_column_sum/tests/functional/main.cpp b/tasks/sannikov_i_column_sum/tests/functional/main.cpp new file mode 100644 index 0000000000..1def6a4f0e --- /dev/null +++ b/tasks/sannikov_i_column_sum/tests/functional/main.cpp @@ -0,0 +1,81 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sannikov_i_column_sum/common/include/common.hpp" +#include "sannikov_i_column_sum/mpi/include/ops_mpi.hpp" +#include "sannikov_i_column_sum/seq/include/ops_seq.hpp" +#include "util/include/func_test_util.hpp" +#include "util/include/util.hpp" + +namespace sannikov_i_column_sum { + +class SannikovIColumnSumFuncTests : public ppc::util::BaseRunFuncTests { + public: + static std::string PrintTestParam(const TestType &test_param) { + return std::get<1>(test_param); + } + + protected: + void SetUp() override { + TestType params = std::get(ppc::util::GTestParamIndex::kTestParams)>(GetParam()); + input_data_ = std::get<0>(params); + } + + bool CheckTestOutputData(OutType &output_data) final { + OutType sums_vec(input_data_.front().size(), 0); + for (size_t i = 0; i < (size_t)input_data_.size(); i++) { + for (size_t j = 0; j < (size_t)input_data_[i].size(); j++) { + sums_vec[j] += input_data_[i][j]; + } + } + return (sums_vec == output_data); + } + + InType GetTestInputData() final { + return input_data_; + } + + private: + InType input_data_ {}; +}; + +namespace { + +TEST_P(SannikovIColumnSumFuncTests, MatmulFromPic) { + ExecuteTest(GetParam()); +} + +const std::array kTestParam = { + std::make_tuple(std::vector>{{1,2,3},{4,5,6},{7,8,9}}, "matrix3x3"), + std::make_tuple(std::vector>{{-1,-2,-3},{-4,-5,-6},{-7,-8,-9}}, "matrix3x3negative"), + std::make_tuple(std::vector>{{1,2},{1,2},{1,2}, {1,2}}, "matrix4x2"), + std::make_tuple(std::vector>{{0}}, "matrix1x1zero"), + std::make_tuple(std::vector>{{0,0,0},{0,0,0},{0,0,0}}, "matrix3x3zero"), + std::make_tuple(std::vector>{{1,10,15,19,90,3}}, "matrix1x6"), + std::make_tuple(std::vector>{{1037,2385,8543},{286,629,1094},{8306,6290,375}}, "matrix3x3big_nums"), + std::make_tuple(std::vector>{{1037,-2385,8543},{-286,629,-1094},{8306,6290,-375}}, "matrix3x3big_nums_with_negative")}; + +const auto kTestTasksList = + std::tuple_cat(ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_sannikov_i_column_sum), + ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_sannikov_i_column_sum)); + +const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList); + +const auto kPerfTestName = SannikovIColumnSumFuncTests::PrintFuncTestName; + +INSTANTIATE_TEST_SUITE_P(PicMatrixTests, SannikovIColumnSumFuncTests, kGtestValues, kPerfTestName); + +} // namespace + +} // namespace sannikov_i_column_sum diff --git a/tasks/sannikov_i_column_sum/tests/performance/main.cpp b/tasks/sannikov_i_column_sum/tests/performance/main.cpp new file mode 100644 index 0000000000..30f81ef1df --- /dev/null +++ b/tasks/sannikov_i_column_sum/tests/performance/main.cpp @@ -0,0 +1,50 @@ +#include + +#include "sannikov_i_column_sum/common/include/common.hpp" +#include "sannikov_i_column_sum/mpi/include/ops_mpi.hpp" +#include "sannikov_i_column_sum/seq/include/ops_seq.hpp" +#include "util/include/perf_test_util.hpp" + +namespace sannikov_i_column_sum { + +class SannikovIColumnSumPerfTests : public ppc::util::BaseRunPerfTests { + InType input_data_{}; + + void SetUp() override { + input_data_ = InType(10000, std::vector(10000)); + for (size_t i = 0; i < 10000; i++) { + for (size_t j = 0; j < 10000; j++) { + input_data_[i][j] = (size_t)(i*14 + j*21); + } + } + } + + bool CheckTestOutputData(OutType &output_data) final { + OutType sums_vec(input_data_.front().size(), 0); + for (size_t i = 0; i < (size_t)input_data_.size(); i++) { + for (size_t j = 0; j < (size_t)input_data_[i].size(); j++) { + sums_vec[j] += input_data_[i][j]; + } + } + return sums_vec == output_data; + } + + InType GetTestInputData() final { + return input_data_; + } +}; + +TEST_P(SannikovIColumnSumPerfTests, RunPerfModes) { + ExecuteTest(GetParam()); +} + +const auto kAllPerfTasks = + ppc::util::MakeAllPerfTasks(PPC_SETTINGS_sannikov_i_column_sum); + +const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); + +const auto kPerfTestName = SannikovIColumnSumPerfTests::CustomPerfTestName; + +INSTANTIATE_TEST_SUITE_P(RunModeTests, SannikovIColumnSumPerfTests, kGtestValues, kPerfTestName); + +} // namespace sannikov_i_column_sum From 7ec95fe0274f72f906faded520373da771cfc395 Mon Sep 17 00:00:00 2001 From: ivan-sannikov Date: Thu, 13 Nov 2025 08:55:23 +0000 Subject: [PATCH 02/15] Apply clang-format style --- scripts/build/perf_stat_dir/perf_log.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 scripts/build/perf_stat_dir/perf_log.txt diff --git a/scripts/build/perf_stat_dir/perf_log.txt b/scripts/build/perf_stat_dir/perf_log.txt new file mode 100644 index 0000000000..e69de29bb2 From 876df22450f14f2cbc01217dc952886e543a6fdb Mon Sep 17 00:00:00 2001 From: ivan-sannikov Date: Thu, 13 Nov 2025 09:00:58 +0000 Subject: [PATCH 03/15] apply --- .../sannikov_i_column_sum/mpi/src/ops_mpi.cpp | 54 ++++++++++--------- .../tests/functional/main.cpp | 30 ++++++----- .../tests/performance/main.cpp | 10 ++-- 3 files changed, 50 insertions(+), 44 deletions(-) diff --git a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp index fa3bb9d745..aa5c040cad 100644 --- a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp +++ b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp @@ -8,8 +8,6 @@ #include "sannikov_i_column_sum/common/include/common.hpp" #include "util/include/util.hpp" - - namespace sannikov_i_column_sum { SannikovIColumnSumMPI::SannikovIColumnSumMPI(const InType &in) { @@ -28,11 +26,15 @@ bool SannikovIColumnSumMPI::PreProcessingImpl() { int columns = 0; if (rank == 0) { - if (GetInput().empty()) return false; + if (GetInput().empty()) { + return false; + } columns = (GetInput().front().size()); } MPI_Bcast(&columns, 1, MPI_INT, 0, MPI_COMM_WORLD); - if (columns <= 0) return false; + if (columns <= 0) { + return false; + } GetOutput().resize((columns), 0); return !GetOutput().empty(); } @@ -49,44 +51,48 @@ bool SannikovIColumnSumMPI::RunImpl() { MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank == 0) { - if (GetInput().empty() || (size_t)GetInput().front().size() != columns) + if (GetInput().empty() || (size_t)GetInput().front().size() != columns) { return false; + } rows = (GetInput().size()); } MPI_Bcast(&rows, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(&columns, 1, MPI_INT, 0, MPI_COMM_WORLD); - if (rows <= 0 || columns <= 0) return false; + if (rows <= 0 || columns <= 0) { + return false; + } size_t rem = rows % size; size_t pad = (rem == 0) ? 0 : (size - rem); - size_t total_rows = rows +pad; + size_t total_rows = rows + pad; size_t rows_per_proc = total_rows / size; std::vector sendbuf; - if(rank == 0){ - sendbuf.resize((total_rows*columns)); - for(size_t i=0;i recvbuf((rows_per_proc*columns), 0); - MPI_Scatter(rank == 0 ? sendbuf.data() : nullptr, rows_per_proc*columns, MPI_INT, recvbuf.data(), rows_per_proc*columns, MPI_INT, 0, MPI_COMM_WORLD); + std::vector recvbuf((rows_per_proc * columns), 0); + MPI_Scatter(rank == 0 ? sendbuf.data() : nullptr, rows_per_proc * columns, MPI_INT, recvbuf.data(), + rows_per_proc * columns, MPI_INT, 0, MPI_COMM_WORLD); std::vector sum((columns), 0); - for(size_t i = 0; i < rows_per_proc; i++){ - int local_id = i *columns; - for(size_t j = 0; j { public: static std::string PrintTestParam(const TestType &test_param) { - return std::get<1>(test_param); + return std::get<1>(test_param); } protected: @@ -47,7 +47,7 @@ class SannikovIColumnSumFuncTests : public ppc::util::BaseRunFuncTests kTestParam = { - std::make_tuple(std::vector>{{1,2,3},{4,5,6},{7,8,9}}, "matrix3x3"), - std::make_tuple(std::vector>{{-1,-2,-3},{-4,-5,-6},{-7,-8,-9}}, "matrix3x3negative"), - std::make_tuple(std::vector>{{1,2},{1,2},{1,2}, {1,2}}, "matrix4x2"), - std::make_tuple(std::vector>{{0}}, "matrix1x1zero"), - std::make_tuple(std::vector>{{0,0,0},{0,0,0},{0,0,0}}, "matrix3x3zero"), - std::make_tuple(std::vector>{{1,10,15,19,90,3}}, "matrix1x6"), - std::make_tuple(std::vector>{{1037,2385,8543},{286,629,1094},{8306,6290,375}}, "matrix3x3big_nums"), - std::make_tuple(std::vector>{{1037,-2385,8543},{-286,629,-1094},{8306,6290,-375}}, "matrix3x3big_nums_with_negative")}; - -const auto kTestTasksList = - std::tuple_cat(ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_sannikov_i_column_sum), - ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_sannikov_i_column_sum)); + std::make_tuple(std::vector>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, "matrix3x3"), + std::make_tuple(std::vector>{{-1, -2, -3}, {-4, -5, -6}, {-7, -8, -9}}, "matrix3x3negative"), + std::make_tuple(std::vector>{{1, 2}, {1, 2}, {1, 2}, {1, 2}}, "matrix4x2"), + std::make_tuple(std::vector>{{0}}, "matrix1x1zero"), + std::make_tuple(std::vector>{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, "matrix3x3zero"), + std::make_tuple(std::vector>{{1, 10, 15, 19, 90, 3}}, "matrix1x6"), + std::make_tuple(std::vector>{{1037, 2385, 8543}, {286, 629, 1094}, {8306, 6290, 375}}, + "matrix3x3big_nums"), + std::make_tuple(std::vector>{{1037, -2385, 8543}, {-286, 629, -1094}, {8306, 6290, -375}}, + "matrix3x3big_nums_with_negative")}; + +const auto kTestTasksList = std::tuple_cat( + ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_sannikov_i_column_sum), + ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_sannikov_i_column_sum)); const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList); diff --git a/tasks/sannikov_i_column_sum/tests/performance/main.cpp b/tasks/sannikov_i_column_sum/tests/performance/main.cpp index 30f81ef1df..d368137d11 100644 --- a/tasks/sannikov_i_column_sum/tests/performance/main.cpp +++ b/tasks/sannikov_i_column_sum/tests/performance/main.cpp @@ -13,9 +13,9 @@ class SannikovIColumnSumPerfTests : public ppc::util::BaseRunPerfTests(10000)); for (size_t i = 0; i < 10000; i++) { - for (size_t j = 0; j < 10000; j++) { - input_data_[i][j] = (size_t)(i*14 + j*21); - } + for (size_t j = 0; j < 10000; j++) { + input_data_[i][j] = (size_t)(i * 14 + j * 21); + } } } @@ -38,8 +38,8 @@ TEST_P(SannikovIColumnSumPerfTests, RunPerfModes) { ExecuteTest(GetParam()); } -const auto kAllPerfTasks = - ppc::util::MakeAllPerfTasks(PPC_SETTINGS_sannikov_i_column_sum); +const auto kAllPerfTasks = ppc::util::MakeAllPerfTasks( + PPC_SETTINGS_sannikov_i_column_sum); const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); From 411d6954aa6114ff3982642fa5c334acd2cc20d5 Mon Sep 17 00:00:00 2001 From: ivan-sannikov Date: Thu, 13 Nov 2025 09:38:40 +0000 Subject: [PATCH 04/15] gcc fix bags 1 --- tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp | 14 ++++++++------ tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp | 12 +++++++----- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp index aa5c040cad..eb39564036 100644 --- a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp +++ b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp @@ -17,19 +17,20 @@ SannikovIColumnSumMPI::SannikovIColumnSumMPI(const InType &in) { } bool SannikovIColumnSumMPI::ValidationImpl() { - return (!GetInput().empty()) && (GetInput().front().size() != 0) && (GetOutput().empty()); + const auto &input_matrix = GetInput(); + return (!input_matrix.empty()) && (input_matrix.front().size() != 0) && (GetOutput().empty()); } bool SannikovIColumnSumMPI::PreProcessingImpl() { int rank = 0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); - + const auto &input_matrix = GetInput(); int columns = 0; if (rank == 0) { - if (GetInput().empty()) { + if (input_matrix.empty()) { return false; } - columns = (GetInput().front().size()); + columns = (input_matrix.front().size()); } MPI_Bcast(&columns, 1, MPI_INT, 0, MPI_COMM_WORLD); if (columns <= 0) { @@ -40,7 +41,8 @@ bool SannikovIColumnSumMPI::PreProcessingImpl() { } bool SannikovIColumnSumMPI::RunImpl() { - if (GetInput().empty()) { + const auto &input_matrix = GetInput(); + if (input_matrix.empty()) { return false; } int rank = 0; @@ -51,7 +53,7 @@ bool SannikovIColumnSumMPI::RunImpl() { MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank == 0) { - if (GetInput().empty() || (size_t)GetInput().front().size() != columns) { + if (input_matrix.empty() || (size_t)input_matrix.front().size() != columns) { return false; } rows = (GetInput().size()); diff --git a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp index d7c496b22f..8bf08279d4 100644 --- a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp +++ b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp @@ -15,7 +15,8 @@ SannikovIColumnSumSEQ::SannikovIColumnSumSEQ(const InType &in) { } bool SannikovIColumnSumSEQ::ValidationImpl() { - return (!GetInput().empty()) && (GetInput().front().size() != 0) && (GetOutput().empty()); + const auto &input_matrix = GetInput(); + return (!input_matrix.empty()) && (input_matrix.front().size() != 0) && (GetOutput().empty()); } bool SannikovIColumnSumSEQ::PreProcessingImpl() { @@ -24,13 +25,14 @@ bool SannikovIColumnSumSEQ::PreProcessingImpl() { } bool SannikovIColumnSumSEQ::RunImpl() { - if (GetInput().empty()) { + const auto &input_matrix = GetInput(); + if (input_matrix.empty()) { return false; } - for (size_t i = 0; i < (size_t)GetInput().size(); i++) { - for (size_t j = 0; j < (size_t)GetInput()[i].size(); j++) { - GetOutput()[j] += GetInput()[i][j]; + for (size_t i = 0; i < (size_t)input_matrix.size(); i++) { + for (size_t j = 0; j < (size_t)input_matrix[i].size(); j++) { + GetOutput()[j] += input_matrix[i][j]; } } From e5a13e442884004d9b14dd19981eb94f507965fb Mon Sep 17 00:00:00 2001 From: ivan-sannikov Date: Thu, 13 Nov 2025 09:49:49 +0000 Subject: [PATCH 05/15] gcc fix bags 2 --- tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp | 5 ++++- tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp index eb39564036..97d551b998 100644 --- a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp +++ b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp @@ -12,7 +12,10 @@ namespace sannikov_i_column_sum { SannikovIColumnSumMPI::SannikovIColumnSumMPI(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); - GetInput() = in; + auto &dst = GetInput(); + InType tmp(in); + dst.swap(tmp); + GetOutput().clear(); } diff --git a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp index 8bf08279d4..78b4436511 100644 --- a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp +++ b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp @@ -10,7 +10,10 @@ namespace sannikov_i_column_sum { SannikovIColumnSumSEQ::SannikovIColumnSumSEQ(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); - GetInput() = in; + auto &dst = GetInput(); + InType tmp(in); + dst.swap(tmp); + GetOutput().clear(); } From 6780400d96020d8c829654f73f11e8e2b569c712 Mon Sep 17 00:00:00 2001 From: ivan-sannikov Date: Thu, 13 Nov 2025 13:10:35 +0000 Subject: [PATCH 06/15] fix run-test1 --- .../sannikov_i_column_sum/mpi/src/ops_mpi.cpp | 34 +++++++++---------- .../sannikov_i_column_sum/seq/src/ops_seq.cpp | 4 +-- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp index 97d551b998..4c058f2fe8 100644 --- a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp +++ b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp @@ -45,21 +45,19 @@ bool SannikovIColumnSumMPI::PreProcessingImpl() { bool SannikovIColumnSumMPI::RunImpl() { const auto &input_matrix = GetInput(); - if (input_matrix.empty()) { - return false; - } + int rank = 0; int size = 1; - size_t rows = 0; - size_t columns = (GetOutput().size()); + int rows = 0; + int columns = (GetOutput().size()); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank == 0) { - if (input_matrix.empty() || (size_t)input_matrix.front().size() != columns) { + if (input_matrix.empty() || (int)input_matrix.front().size() != columns) { return false; } - rows = (GetInput().size()); + rows = (input_matrix.size()); } MPI_Bcast(&rows, 1, MPI_INT, 0, MPI_COMM_WORLD); @@ -67,21 +65,21 @@ bool SannikovIColumnSumMPI::RunImpl() { if (rows <= 0 || columns <= 0) { return false; } - size_t rem = rows % size; - size_t pad = (rem == 0) ? 0 : (size - rem); - size_t total_rows = rows + pad; - size_t rows_per_proc = total_rows / size; + int rem = rows % size; + int pad = (rem == 0) ? 0 : (size - rem); + int total_rows = rows + pad; + int rows_per_proc = total_rows / size; std::vector sendbuf; if (rank == 0) { sendbuf.resize((total_rows * columns)); - for (size_t i = 0; i < rows; i++) { - for (size_t j = 0; j < columns; j++) { - sendbuf[(i)*columns + j] = GetInput()[(i)][(j)]; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < columns; j++) { + sendbuf[(i)*columns + j] = input_matrix[(i)][(j)]; } } - for (size_t i = rows; i < total_rows; i++) { - for (size_t j = 0; j < columns; j++) { + for (int i = rows; i < total_rows; i++) { + for (int j = 0; j < columns; j++) { sendbuf[(i)*columns + j] = 0; } } @@ -91,9 +89,9 @@ bool SannikovIColumnSumMPI::RunImpl() { MPI_Scatter(rank == 0 ? sendbuf.data() : nullptr, rows_per_proc * columns, MPI_INT, recvbuf.data(), rows_per_proc * columns, MPI_INT, 0, MPI_COMM_WORLD); std::vector sum((columns), 0); - for (size_t i = 0; i < rows_per_proc; i++) { + for (int i = 0; i < rows_per_proc; i++) { int local_id = i * columns; - for (size_t j = 0; j < columns; j++) { + for (int j = 0; j < columns; j++) { sum[(j)] += recvbuf[local_id + j]; } } diff --git a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp index 78b4436511..9a939d8632 100644 --- a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp +++ b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp @@ -33,8 +33,8 @@ bool SannikovIColumnSumSEQ::RunImpl() { return false; } - for (size_t i = 0; i < (size_t)input_matrix.size(); i++) { - for (size_t j = 0; j < (size_t)input_matrix[i].size(); j++) { + for (int i = 0; i < (int)input_matrix.size(); i++) { + for (int j = 0; j < (int)input_matrix[i].size(); j++) { GetOutput()[j] += input_matrix[i][j]; } } From 2dfc2b1767ecc18a004e44864d6bca7fb54555e1 Mon Sep 17 00:00:00 2001 From: ivan-sannikov Date: Thu, 13 Nov 2025 14:20:42 +0000 Subject: [PATCH 07/15] fix perf tests --- tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp index 9a939d8632..811a926e75 100644 --- a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp +++ b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp @@ -19,11 +19,13 @@ SannikovIColumnSumSEQ::SannikovIColumnSumSEQ(const InType &in) { bool SannikovIColumnSumSEQ::ValidationImpl() { const auto &input_matrix = GetInput(); - return (!input_matrix.empty()) && (input_matrix.front().size() != 0) && (GetOutput().empty()); + return (!input_matrix.empty()) && (input_matrix.front().size() != 0); } bool SannikovIColumnSumSEQ::PreProcessingImpl() { - GetOutput().resize(GetInput().front().size(), 0); + const auto &input_matrix = GetInput(); + GetOutput().clear(); + GetOutput().resize(input_matrix.front().size(), 0); return !GetOutput().empty(); } @@ -38,7 +40,6 @@ bool SannikovIColumnSumSEQ::RunImpl() { GetOutput()[j] += input_matrix[i][j]; } } - return !GetOutput().empty(); } From abd7a59d064a27ea5afaa11b5a5a7bd53fd4267e Mon Sep 17 00:00:00 2001 From: ivan-sannikov Date: Sun, 16 Nov 2025 19:59:55 +0000 Subject: [PATCH 08/15] fix mpi for perf results --- .../sannikov_i_column_sum/mpi/src/ops_mpi.cpp | 45 +++++++++---------- .../sannikov_i_column_sum/seq/src/ops_seq.cpp | 4 +- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp index 4c058f2fe8..ad1f15b652 100644 --- a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp +++ b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp @@ -12,10 +12,9 @@ namespace sannikov_i_column_sum { SannikovIColumnSumMPI::SannikovIColumnSumMPI(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); - auto &dst = GetInput(); + auto &input_buffer = GetInput(); InType tmp(in); - dst.swap(tmp); - + input_buffer.swap(tmp); GetOutput().clear(); } @@ -65,35 +64,31 @@ bool SannikovIColumnSumMPI::RunImpl() { if (rows <= 0 || columns <= 0) { return false; } - int rem = rows % size; - int pad = (rem == 0) ? 0 : (size - rem); - int total_rows = rows + pad; - int rows_per_proc = total_rows / size; std::vector sendbuf; if (rank == 0) { - sendbuf.resize((total_rows * columns)); + sendbuf.resize((rows * columns)); for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { - sendbuf[(i)*columns + j] = input_matrix[(i)][(j)]; - } - } - - for (int i = rows; i < total_rows; i++) { - for (int j = 0; j < columns; j++) { - sendbuf[(i)*columns + j] = 0; + sendbuf[i * columns + j] = input_matrix[i][j]; } } } - - std::vector recvbuf((rows_per_proc * columns), 0); - MPI_Scatter(rank == 0 ? sendbuf.data() : nullptr, rows_per_proc * columns, MPI_INT, recvbuf.data(), - rows_per_proc * columns, MPI_INT, 0, MPI_COMM_WORLD); - std::vector sum((columns), 0); - for (int i = 0; i < rows_per_proc; i++) { - int local_id = i * columns; - for (int j = 0; j < columns; j++) { - sum[(j)] += recvbuf[local_id + j]; - } + std::vector elem_for_proc(size); + std::vector id_elem(size); + int displacement = 0; + for (int i = 0; i < size; i++) { + elem_for_proc[i] = rows * columns / size + (i < rows * columns % size ? 1 : 0); + id_elem[i] = displacement; + displacement += elem_for_proc[i]; + } + int mpi_displacement = id_elem[rank] % columns; + std::vector buf(elem_for_proc[rank], 0); + MPI_Scatterv(rank == 0 ? sendbuf.data() : nullptr, elem_for_proc.data(), id_elem.data(), MPI_INT, buf.data(), + elem_for_proc[rank], MPI_INT, 0, MPI_COMM_WORLD); + std::vector sum(columns, 0); + for (int i = 0; i < elem_for_proc[rank]; i++) { + int new_col = (i + mpi_displacement) % columns; + sum[new_col] += buf[i]; } MPI_Allreduce(sum.data(), GetOutput().data(), columns, MPI_INT, MPI_SUM, MPI_COMM_WORLD); return !GetOutput().empty(); diff --git a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp index 811a926e75..47e708e58d 100644 --- a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp +++ b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp @@ -10,9 +10,9 @@ namespace sannikov_i_column_sum { SannikovIColumnSumSEQ::SannikovIColumnSumSEQ(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); - auto &dst = GetInput(); + auto &input_buffer = GetInput(); InType tmp(in); - dst.swap(tmp); + input_buffer.swap(tmp); GetOutput().clear(); } From 16a1e0045c2e157168d2d51385124bf718e5cbe0 Mon Sep 17 00:00:00 2001 From: ivan-sannikov Date: Mon, 17 Nov 2025 08:27:12 +0000 Subject: [PATCH 09/15] compleate report --- tasks/sannikov_i_column_sum/report.md | 132 ++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/tasks/sannikov_i_column_sum/report.md b/tasks/sannikov_i_column_sum/report.md index e69de29bb2..d8c6530dd1 100644 --- a/tasks/sannikov_i_column_sum/report.md +++ b/tasks/sannikov_i_column_sum/report.md @@ -0,0 +1,132 @@ +# Сумма значений по столбцам матрицы + +- Студент: Санников Иван Михайлович, Группа: 3823Б1ФИ2 +- Технология: SEQ, MPI +- Вариант: 12 +## 1. Введение +Вычисление сумм по столбцам матрицы является одной из основных в математике и часто используется в прикладных задачах, как машинное обучение(ML) и статистика. Часто приходится работать с большим объемом данных, что делает задачу ресурсоемкой при использовании последовательных алгоритмов. Цель данной лабораторной работы - написание алгоритма на основе технологии MPI для распределение нагрузки между несколькоми процессами. + +## 2. Постановка задачи +Входные данные: std::vector> - вектор векторов типа данных int представляющий из себя матрицу. + +Для матрицы размера A*B, строица std::vector размера B, где для элемента i хранится сумма столбца i из входной матрицы. + +## 3. Базовый алгоритм(seq) +Последовательный алгорритм: +- Проходим по всем строкам +- В каждой i строке проходим по всем столбцам +- Складываем элемент i строки j столбца c элементом j вектора суммы. + +```cpp +bool SannikovIColumnSumSEQ::RunImpl() { + const auto &input_matrix = GetInput(); + if (input_matrix.empty()) { + return false; + } + + for (int i = 0; i < (int)input_matrix.size(); i++) { + for (int j = 0; j < (int)input_matrix[i].size(); j++) { + GetOutput()[j] += input_matrix[i][j]; + } + } + return !GetOutput().empty(); +} +``` + +## 4. Описание параллельного алгоритма + +1. Обрабатываем входные данные: Превращаем std::vector> в последовательный std::vector, чтобы была возможность его разделить Scatterv. +2. Вычисляем сколько данных получит процесс: перемножаем количество столбцов на строки, делим на количество процессов и прибавляем 1, если номер вычисления меньше остатка (i sendbuf; + if (rank == 0) { + sendbuf.resize((rows * columns)); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < columns; j++) { + sendbuf[i * columns + j] = input_matrix[i][j]; + } + } + } + std::vector elem_for_proc(size); + std::vector id_elem(size); + int displacement = 0; + for (int i = 0; i < size; i++) { + elem_for_proc[i] = rows * columns / size + (i < rows * columns % size ? 1 : 0); + id_elem[i] = displacement; + displacement += elem_for_proc[i]; + } + int mpi_displacement = id_elem[rank] % columns; + std::vector buf(elem_for_proc[rank], 0); + MPI_Scatterv(rank == 0 ? sendbuf.data() : nullptr, elem_for_proc.data(), id_elem.data(), MPI_INT, buf.data(), + elem_for_proc[rank], MPI_INT, 0, MPI_COMM_WORLD); + std::vector sum(columns, 0); + for (int i = 0; i < elem_for_proc[rank]; i++) { + int new_col = (i + mpi_displacement) % columns; + sum[new_col] += buf[i]; + } + MPI_Allreduce(sum.data(), GetOutput().data(), columns, MPI_INT, MPI_SUM, MPI_COMM_WORLD); + return !GetOutput().empty(); +} + + +``` \ No newline at end of file From f2466bc5e68e7ca83d7b3798629430e8a57b76a7 Mon Sep 17 00:00:00 2001 From: ivan-sannikov Date: Mon, 17 Nov 2025 10:47:51 +0000 Subject: [PATCH 10/15] fix clang-tidy and fix test coverage --- tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp | 6 +++--- tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp | 5 ++--- tasks/sannikov_i_column_sum/tests/functional/main.cpp | 9 +++++++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp index ad1f15b652..c4cf5fc1e2 100644 --- a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp +++ b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp @@ -2,7 +2,6 @@ #include -#include #include #include "sannikov_i_column_sum/common/include/common.hpp" @@ -53,7 +52,7 @@ bool SannikovIColumnSumMPI::RunImpl() { MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank == 0) { - if (input_matrix.empty() || (int)input_matrix.front().size() != columns) { + if (input_matrix.empty() || static_cast(input_matrix.front().size()) != columns) { return false; } rows = (input_matrix.size()); @@ -81,7 +80,8 @@ bool SannikovIColumnSumMPI::RunImpl() { id_elem[i] = displacement; displacement += elem_for_proc[i]; } - int mpi_displacement = id_elem[rank] % columns; + int mpi_displacement = 0; + mpi_displacement = id_elem[rank] % columns; std::vector buf(elem_for_proc[rank], 0); MPI_Scatterv(rank == 0 ? sendbuf.data() : nullptr, elem_for_proc.data(), id_elem.data(), MPI_INT, buf.data(), elem_for_proc[rank], MPI_INT, 0, MPI_COMM_WORLD); diff --git a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp index 47e708e58d..b8771aac04 100644 --- a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp +++ b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp @@ -1,6 +1,5 @@ #include "sannikov_i_column_sum/seq/include/ops_seq.hpp" -#include #include #include "sannikov_i_column_sum/common/include/common.hpp" @@ -35,8 +34,8 @@ bool SannikovIColumnSumSEQ::RunImpl() { return false; } - for (int i = 0; i < (int)input_matrix.size(); i++) { - for (int j = 0; j < (int)input_matrix[i].size(); j++) { + for (int i = 0; i < static_cast(input_matrix.size()); i++) { + for (int j = 0; j < static_cast(input_matrix[i].size()); j++) { GetOutput()[j] += input_matrix[i][j]; } } diff --git a/tasks/sannikov_i_column_sum/tests/functional/main.cpp b/tasks/sannikov_i_column_sum/tests/functional/main.cpp index 809edeea45..fada1e1b29 100644 --- a/tasks/sannikov_i_column_sum/tests/functional/main.cpp +++ b/tasks/sannikov_i_column_sum/tests/functional/main.cpp @@ -56,7 +56,7 @@ TEST_P(SannikovIColumnSumFuncTests, MatmulFromPic) { ExecuteTest(GetParam()); } -const std::array kTestParam = { +const std::array kTestParam = { std::make_tuple(std::vector>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, "matrix3x3"), std::make_tuple(std::vector>{{-1, -2, -3}, {-4, -5, -6}, {-7, -8, -9}}, "matrix3x3negative"), std::make_tuple(std::vector>{{1, 2}, {1, 2}, {1, 2}, {1, 2}}, "matrix4x2"), @@ -66,7 +66,12 @@ const std::array kTestParam = { std::make_tuple(std::vector>{{1037, 2385, 8543}, {286, 629, 1094}, {8306, 6290, 375}}, "matrix3x3big_nums"), std::make_tuple(std::vector>{{1037, -2385, 8543}, {-286, 629, -1094}, {8306, 6290, -375}}, - "matrix3x3big_nums_with_negative")}; + "matrix3x3big_nums_with_negative"), + std::make_tuple(std::vector>{{-5, 0, 7, -3, 10}}, "matrix1x5_mix"), + std::make_tuple(std::vector>{{1}, {2}, {-3}, {4}, {-5}}, "matrix5x1_column"), + std::make_tuple(std::vector>{{0, -1, 2, -3}, {4, 0, -5, 6}}, "matrix2x4_mix"), + std::make_tuple(std::vector>{{1, 2, 3, 4, 5}, {-1, 0, 7, -2, 3}, {10, -5, 8, 0, -4}}, + "matrix3x5_mix")}; const auto kTestTasksList = std::tuple_cat( ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_sannikov_i_column_sum), From a02dc7748d728a2be17c068e027877c95995b644 Mon Sep 17 00:00:00 2001 From: ivan-sannikov Date: Mon, 17 Nov 2025 14:32:59 +0000 Subject: [PATCH 11/15] fix clang-tidy and tests coverage 2 --- .../mpi/include/ops_mpi.hpp | 2 + .../sannikov_i_column_sum/mpi/src/ops_mpi.cpp | 55 ++++++++++--------- .../sannikov_i_column_sum/seq/src/ops_seq.cpp | 13 +++-- .../tests/functional/main.cpp | 11 +--- .../tests/performance/main.cpp | 16 +++--- 5 files changed, 49 insertions(+), 48 deletions(-) diff --git a/tasks/sannikov_i_column_sum/mpi/include/ops_mpi.hpp b/tasks/sannikov_i_column_sum/mpi/include/ops_mpi.hpp index b9d5377933..796791920e 100644 --- a/tasks/sannikov_i_column_sum/mpi/include/ops_mpi.hpp +++ b/tasks/sannikov_i_column_sum/mpi/include/ops_mpi.hpp @@ -17,6 +17,8 @@ class SannikovIColumnSumMPI : public BaseTask { bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; + + static void PrepareSendBuffer(const InType &input_matrix, int rank, int rows, int columns, std::vector &sendbuf); }; } // namespace sannikov_i_column_sum diff --git a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp index c4cf5fc1e2..a8459a0426 100644 --- a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp +++ b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp @@ -5,7 +5,6 @@ #include #include "sannikov_i_column_sum/common/include/common.hpp" -#include "util/include/util.hpp" namespace sannikov_i_column_sum { @@ -19,7 +18,7 @@ SannikovIColumnSumMPI::SannikovIColumnSumMPI(const InType &in) { bool SannikovIColumnSumMPI::ValidationImpl() { const auto &input_matrix = GetInput(); - return (!input_matrix.empty()) && (input_matrix.front().size() != 0) && (GetOutput().empty()); + return (!input_matrix.empty()) && (!input_matrix.front().empty()) && (GetOutput().empty()); } bool SannikovIColumnSumMPI::PreProcessingImpl() { @@ -28,10 +27,7 @@ bool SannikovIColumnSumMPI::PreProcessingImpl() { const auto &input_matrix = GetInput(); int columns = 0; if (rank == 0) { - if (input_matrix.empty()) { - return false; - } - columns = (input_matrix.front().size()); + columns = static_cast(input_matrix.front().size()); } MPI_Bcast(&columns, 1, MPI_INT, 0, MPI_COMM_WORLD); if (columns <= 0) { @@ -41,54 +37,59 @@ bool SannikovIColumnSumMPI::PreProcessingImpl() { return !GetOutput().empty(); } +void SannikovIColumnSumMPI::PrepareSendBuffer(const InType &input_matrix, int rank, int rows, int columns, + std::vector &sendbuf) { + if (rank != 0) { + return; + } + if (rank == 0) { + const int base = rows * columns; + sendbuf.resize(base); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < columns; j++) { + sendbuf[(i * columns) + (j)] = input_matrix[i][j]; + } + } + } +} + bool SannikovIColumnSumMPI::RunImpl() { const auto &input_matrix = GetInput(); int rank = 0; int size = 1; int rows = 0; - int columns = (GetOutput().size()); + int columns = 0; + columns = static_cast(GetOutput().size()); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank == 0) { - if (input_matrix.empty() || static_cast(input_matrix.front().size()) != columns) { - return false; - } - rows = (input_matrix.size()); + rows = static_cast(input_matrix.size()); } MPI_Bcast(&rows, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(&columns, 1, MPI_INT, 0, MPI_COMM_WORLD); - if (rows <= 0 || columns <= 0) { - return false; - } std::vector sendbuf; - if (rank == 0) { - sendbuf.resize((rows * columns)); - for (int i = 0; i < rows; i++) { - for (int j = 0; j < columns; j++) { - sendbuf[i * columns + j] = input_matrix[i][j]; - } - } - } + PrepareSendBuffer(input_matrix, rank, rows, columns, sendbuf); std::vector elem_for_proc(size); std::vector id_elem(size); int displacement = 0; + const int base = rows * columns; for (int i = 0; i < size; i++) { - elem_for_proc[i] = rows * columns / size + (i < rows * columns % size ? 1 : 0); + elem_for_proc[i] = static_cast(base / size) + (i < (base % size) ? 1 : 0); id_elem[i] = displacement; displacement += elem_for_proc[i]; } int mpi_displacement = 0; mpi_displacement = id_elem[rank] % columns; - std::vector buf(elem_for_proc[rank], 0); + std::vector buf((elem_for_proc[rank]), 0); MPI_Scatterv(rank == 0 ? sendbuf.data() : nullptr, elem_for_proc.data(), id_elem.data(), MPI_INT, buf.data(), elem_for_proc[rank], MPI_INT, 0, MPI_COMM_WORLD); - std::vector sum(columns, 0); - for (int i = 0; i < elem_for_proc[rank]; i++) { + std::vector sum((columns), 0); + for (int i = 0; i < (elem_for_proc[rank]); i++) { int new_col = (i + mpi_displacement) % columns; - sum[new_col] += buf[i]; + sum[(new_col)] += buf[(i)]; } MPI_Allreduce(sum.data(), GetOutput().data(), columns, MPI_INT, MPI_SUM, MPI_COMM_WORLD); return !GetOutput().empty(); diff --git a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp index b8771aac04..f7c7a0cf16 100644 --- a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp +++ b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp @@ -1,10 +1,9 @@ #include "sannikov_i_column_sum/seq/include/ops_seq.hpp" +#include #include #include "sannikov_i_column_sum/common/include/common.hpp" -#include "util/include/util.hpp" - namespace sannikov_i_column_sum { SannikovIColumnSumSEQ::SannikovIColumnSumSEQ(const InType &in) { @@ -18,7 +17,7 @@ SannikovIColumnSumSEQ::SannikovIColumnSumSEQ(const InType &in) { bool SannikovIColumnSumSEQ::ValidationImpl() { const auto &input_matrix = GetInput(); - return (!input_matrix.empty()) && (input_matrix.front().size() != 0); + return (!input_matrix.empty()) && (!input_matrix.front().empty()); } bool SannikovIColumnSumSEQ::PreProcessingImpl() { @@ -34,9 +33,11 @@ bool SannikovIColumnSumSEQ::RunImpl() { return false; } - for (int i = 0; i < static_cast(input_matrix.size()); i++) { - for (int j = 0; j < static_cast(input_matrix[i].size()); j++) { - GetOutput()[j] += input_matrix[i][j]; + for (const auto &row : input_matrix) { + std::size_t column = 0; + for (const auto &value : row) { + GetOutput()[column] += value; + column++; } } return !GetOutput().empty(); diff --git a/tasks/sannikov_i_column_sum/tests/functional/main.cpp b/tasks/sannikov_i_column_sum/tests/functional/main.cpp index fada1e1b29..153b0073c3 100644 --- a/tasks/sannikov_i_column_sum/tests/functional/main.cpp +++ b/tasks/sannikov_i_column_sum/tests/functional/main.cpp @@ -1,15 +1,10 @@ #include #include -#include #include #include -#include -#include -#include #include #include -#include #include #include "sannikov_i_column_sum/common/include/common.hpp" @@ -34,8 +29,8 @@ class SannikovIColumnSumFuncTests : public ppc::util::BaseRunFuncTests +#include +#include + #include "sannikov_i_column_sum/common/include/common.hpp" #include "sannikov_i_column_sum/mpi/include/ops_mpi.hpp" #include "sannikov_i_column_sum/seq/include/ops_seq.hpp" #include "util/include/perf_test_util.hpp" - namespace sannikov_i_column_sum { class SannikovIColumnSumPerfTests : public ppc::util::BaseRunPerfTests { - InType input_data_{}; + InType input_data_; void SetUp() override { input_data_ = InType(10000, std::vector(10000)); - for (size_t i = 0; i < 10000; i++) { - for (size_t j = 0; j < 10000; j++) { - input_data_[i][j] = (size_t)(i * 14 + j * 21); + for (int i = 0; i < 10000; i++) { + for (int j = 0; j < 10000; j++) { + input_data_[i][j] = (i * 14) + (j * 21); } } } bool CheckTestOutputData(OutType &output_data) final { OutType sums_vec(input_data_.front().size(), 0); - for (size_t i = 0; i < (size_t)input_data_.size(); i++) { - for (size_t j = 0; j < (size_t)input_data_[i].size(); j++) { + for (std::size_t i = 0; i < input_data_.size(); i++) { + for (std::size_t j = 0; j < input_data_[i].size(); j++) { sums_vec[j] += input_data_[i][j]; } } From c40fa3754bf9167321a60d3f66fe73fedd021319 Mon Sep 17 00:00:00 2001 From: ivan-sannikov Date: Mon, 17 Nov 2025 15:41:56 +0000 Subject: [PATCH 12/15] fix clang-tidy all --- tasks/sannikov_i_column_sum/mpi/include/ops_mpi.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasks/sannikov_i_column_sum/mpi/include/ops_mpi.hpp b/tasks/sannikov_i_column_sum/mpi/include/ops_mpi.hpp index 796791920e..399567652a 100644 --- a/tasks/sannikov_i_column_sum/mpi/include/ops_mpi.hpp +++ b/tasks/sannikov_i_column_sum/mpi/include/ops_mpi.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "sannikov_i_column_sum/common/include/common.hpp" #include "task/include/task.hpp" From deb1710fc967f1517369e28ee3d294cecbd549d9 Mon Sep 17 00:00:00 2001 From: ivan-sannikov Date: Mon, 24 Nov 2025 08:30:54 +0000 Subject: [PATCH 13/15] fix bags --- .../mpi/include/ops_mpi.hpp | 4 +- .../sannikov_i_column_sum/mpi/src/ops_mpi.cpp | 87 +++++++++++-------- .../sannikov_i_column_sum/seq/src/ops_seq.cpp | 13 ++- .../tests/functional/main.cpp | 9 +- 4 files changed, 73 insertions(+), 40 deletions(-) diff --git a/tasks/sannikov_i_column_sum/mpi/include/ops_mpi.hpp b/tasks/sannikov_i_column_sum/mpi/include/ops_mpi.hpp index 399567652a..bdacc87fb6 100644 --- a/tasks/sannikov_i_column_sum/mpi/include/ops_mpi.hpp +++ b/tasks/sannikov_i_column_sum/mpi/include/ops_mpi.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include "sannikov_i_column_sum/common/include/common.hpp" @@ -20,7 +21,8 @@ class SannikovIColumnSumMPI : public BaseTask { bool RunImpl() override; bool PostProcessingImpl() override; - static void PrepareSendBuffer(const InType &input_matrix, int rank, int rows, int columns, std::vector &sendbuf); + static void PrepareSendBuffer(const InType &input_matrix, int rank, std::uint64_t rows, std::uint64_t columns, + std::vector &sendbuf); }; } // namespace sannikov_i_column_sum diff --git a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp index a8459a0426..502f61bd0c 100644 --- a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp +++ b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp @@ -2,6 +2,9 @@ #include +#include +#include +#include #include #include "sannikov_i_column_sum/common/include/common.hpp" @@ -18,36 +21,37 @@ SannikovIColumnSumMPI::SannikovIColumnSumMPI(const InType &in) { bool SannikovIColumnSumMPI::ValidationImpl() { const auto &input_matrix = GetInput(); - return (!input_matrix.empty()) && (!input_matrix.front().empty()) && (GetOutput().empty()); + if (input_matrix.empty() || input_matrix.front().empty()) { + return false; + } + + const std::size_t columns = input_matrix.front().size(); + for (const auto &row : input_matrix) { + if (row.size() != columns) { + return false; + } + } + + return GetOutput().empty(); } bool SannikovIColumnSumMPI::PreProcessingImpl() { - int rank = 0; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - const auto &input_matrix = GetInput(); - int columns = 0; - if (rank == 0) { - columns = static_cast(input_matrix.front().size()); - } - MPI_Bcast(&columns, 1, MPI_INT, 0, MPI_COMM_WORLD); - if (columns <= 0) { - return false; - } - GetOutput().resize((columns), 0); - return !GetOutput().empty(); + GetOutput().clear(); + return true; } -void SannikovIColumnSumMPI::PrepareSendBuffer(const InType &input_matrix, int rank, int rows, int columns, - std::vector &sendbuf) { +void SannikovIColumnSumMPI::PrepareSendBuffer(const InType &input_matrix, int rank, std::uint64_t rows, + std::uint64_t columns, std::vector &sendbuf) { if (rank != 0) { return; } if (rank == 0) { - const int base = rows * columns; - sendbuf.resize(base); - for (int i = 0; i < rows; i++) { - for (int j = 0; j < columns; j++) { - sendbuf[(i * columns) + (j)] = input_matrix[i][j]; + const std::uint64_t base = rows * columns; + sendbuf.resize(static_cast(base)); + for (std::uint64_t i = 0; i < rows; i++) { + for (std::uint64_t j = 0; j < columns; j++) { + sendbuf[static_cast((i * columns) + (j))] = + input_matrix[static_cast(i)][static_cast(j)]; } } } @@ -58,40 +62,51 @@ bool SannikovIColumnSumMPI::RunImpl() { int rank = 0; int size = 1; - int rows = 0; - int columns = 0; - columns = static_cast(GetOutput().size()); + std::uint64_t rows = 0; + std::uint64_t columns = 0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank == 0) { - rows = static_cast(input_matrix.size()); + rows = static_cast(input_matrix.size()); + columns = static_cast(input_matrix.front().size()); } - MPI_Bcast(&rows, 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Bcast(&columns, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast(&rows, 1, MPI_UINT64_T, 0, MPI_COMM_WORLD); + MPI_Bcast(&columns, 1, MPI_UINT64_T, 0, MPI_COMM_WORLD); + + const std::uint64_t base = rows * columns; + if (columns > static_cast(std::numeric_limits::max())) { + return false; + } + if (base > static_cast(std::numeric_limits::max())) { + return false; + } + + const int columns_int = static_cast(columns); + const int base_int = static_cast(base); + GetOutput().assign(static_cast(columns_int), 0); + std::vector sendbuf; PrepareSendBuffer(input_matrix, rank, rows, columns, sendbuf); std::vector elem_for_proc(size); std::vector id_elem(size); int displacement = 0; - const int base = rows * columns; for (int i = 0; i < size; i++) { - elem_for_proc[i] = static_cast(base / size) + (i < (base % size) ? 1 : 0); + elem_for_proc[i] = static_cast(base_int / size) + (i < (base_int % size) ? 1 : 0); id_elem[i] = displacement; displacement += elem_for_proc[i]; } - int mpi_displacement = 0; - mpi_displacement = id_elem[rank] % columns; - std::vector buf((elem_for_proc[rank]), 0); + const int mpi_displacement = id_elem[rank] % static_cast(columns_int); + std::vector buf(static_cast(elem_for_proc[rank]), 0); MPI_Scatterv(rank == 0 ? sendbuf.data() : nullptr, elem_for_proc.data(), id_elem.data(), MPI_INT, buf.data(), elem_for_proc[rank], MPI_INT, 0, MPI_COMM_WORLD); - std::vector sum((columns), 0); + std::vector sum(static_cast(columns_int), 0); for (int i = 0; i < (elem_for_proc[rank]); i++) { - int new_col = (i + mpi_displacement) % columns; - sum[(new_col)] += buf[(i)]; + int new_col = (i + mpi_displacement) % columns_int; + sum[static_cast(new_col)] += buf[static_cast(i)]; } - MPI_Allreduce(sum.data(), GetOutput().data(), columns, MPI_INT, MPI_SUM, MPI_COMM_WORLD); + MPI_Allreduce(sum.data(), GetOutput().data(), columns_int, MPI_INT, MPI_SUM, MPI_COMM_WORLD); return !GetOutput().empty(); } diff --git a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp index f7c7a0cf16..e54678c442 100644 --- a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp +++ b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp @@ -17,7 +17,18 @@ SannikovIColumnSumSEQ::SannikovIColumnSumSEQ(const InType &in) { bool SannikovIColumnSumSEQ::ValidationImpl() { const auto &input_matrix = GetInput(); - return (!input_matrix.empty()) && (!input_matrix.front().empty()); + if (input_matrix.empty() || input_matrix.front().empty()) { + return false; + } + + const std::size_t columns = input_matrix.front().size(); + for (const auto &row : input_matrix) { + if (row.size() != columns) { + return false; + } + } + + return GetOutput().empty(); } bool SannikovIColumnSumSEQ::PreProcessingImpl() { diff --git a/tasks/sannikov_i_column_sum/tests/functional/main.cpp b/tasks/sannikov_i_column_sum/tests/functional/main.cpp index 153b0073c3..6e92cf24a6 100644 --- a/tasks/sannikov_i_column_sum/tests/functional/main.cpp +++ b/tasks/sannikov_i_column_sum/tests/functional/main.cpp @@ -51,7 +51,7 @@ TEST_P(SannikovIColumnSumFuncTests, MatmulFromPic) { ExecuteTest(GetParam()); } -const std::array kTestParam = { +const std::array kTestParam = { std::make_tuple(std::vector>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, "matrix3x3"), std::make_tuple(std::vector>{{-1, -2, -3}, {-4, -5, -6}, {-7, -8, -9}}, "matrix3x3negative"), std::make_tuple(std::vector>{{1, 2}, {1, 2}, {1, 2}, {1, 2}}, "matrix4x2"), @@ -66,7 +66,12 @@ const std::array kTestParam = { std::make_tuple(std::vector>{{1}, {2}, {-3}, {4}, {-5}}, "matrix5x1_column"), std::make_tuple(std::vector>{{0, -1, 2, -3}, {4, 0, -5, 6}}, "matrix2x4_mix"), std::make_tuple(std::vector>{{1, 2, 3, 4, 5}, {-1, 0, 7, -2, 3}, {10, -5, 8, 0, -4}}, - "matrix3x5_mix")}; + "matrix3x5_mix"), + std::make_tuple(std::vector>{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}, "matrix1x10_wide"), + std::make_tuple(std::vector>{{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}}, "matrix10x1_tall"), + std::make_tuple(std::vector>{{5, 5}, {5, 5}}, "matrix2x2_same_values"), + std::make_tuple(std::vector>{{100000, -50000, 30000}, {20000, -10000, 5000}, {1, 2, 3}}, + "matrix3x3_large_positive_mixed")}; const auto kTestTasksList = std::tuple_cat( ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_sannikov_i_column_sum), From ff923ef66c8e794f4b0614ae8bfc800d20343ffc Mon Sep 17 00:00:00 2001 From: ivan-sannikov Date: Mon, 24 Nov 2025 10:31:36 +0000 Subject: [PATCH 14/15] fix report --- .../sannikov_i_column_sum/mpi/src/ops_mpi.cpp | 7 +- tasks/sannikov_i_column_sum/report.md | 83 ++++++++++++------- .../sannikov_i_column_sum/seq/src/ops_seq.cpp | 4 - 3 files changed, 53 insertions(+), 41 deletions(-) diff --git a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp index 502f61bd0c..f9ae5de652 100644 --- a/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp +++ b/tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp @@ -76,13 +76,10 @@ bool SannikovIColumnSumMPI::RunImpl() { MPI_Bcast(&columns, 1, MPI_UINT64_T, 0, MPI_COMM_WORLD); const std::uint64_t base = rows * columns; - if (columns > static_cast(std::numeric_limits::max())) { + if (columns > static_cast(std::numeric_limits::max()) || + (base > static_cast(std::numeric_limits::max()))) { return false; } - if (base > static_cast(std::numeric_limits::max())) { - return false; - } - const int columns_int = static_cast(columns); const int base_int = static_cast(base); GetOutput().assign(static_cast(columns_int), 0); diff --git a/tasks/sannikov_i_column_sum/report.md b/tasks/sannikov_i_column_sum/report.md index d8c6530dd1..3b3b8831be 100644 --- a/tasks/sannikov_i_column_sum/report.md +++ b/tasks/sannikov_i_column_sum/report.md @@ -20,13 +20,11 @@ ```cpp bool SannikovIColumnSumSEQ::RunImpl() { const auto &input_matrix = GetInput(); - if (input_matrix.empty()) { - return false; - } - - for (int i = 0; i < (int)input_matrix.size(); i++) { - for (int j = 0; j < (int)input_matrix[i].size(); j++) { - GetOutput()[j] += input_matrix[i][j]; + for (const auto &row : input_matrix) { + std::size_t column = 0; + for (const auto &value : row) { + GetOutput()[column] += value; + column++; } } return !GetOutput().empty(); @@ -76,55 +74,76 @@ bool SannikovIColumnSumSEQ::RunImpl() { ## 9. Приложение ```cpp + +void SannikovIColumnSumMPI::PrepareSendBuffer(const InType &input_matrix, int rank, std::uint64_t rows, + std::uint64_t columns, std::vector &sendbuf) { + if (rank != 0) { + return; + } + if (rank == 0) { + const std::uint64_t base = rows * columns; + sendbuf.resize(static_cast(base)); + for (std::uint64_t i = 0; i < rows; i++) { + for (std::uint64_t j = 0; j < columns; j++) { + sendbuf[static_cast((i * columns) + (j))] = + input_matrix[static_cast(i)][static_cast(j)]; + } + } + } +} + + + bool SannikovIColumnSumMPI::RunImpl() { const auto &input_matrix = GetInput(); int rank = 0; int size = 1; - int rows = 0; - int columns = (GetOutput().size()); + std::uint64_t rows = 0; + std::uint64_t columns = 0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank == 0) { - if (input_matrix.empty() || (int)input_matrix.front().size() != columns) { - return false; - } - rows = (input_matrix.size()); + rows = static_cast(input_matrix.size()); + columns = static_cast(input_matrix.front().size()); } - MPI_Bcast(&rows, 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Bcast(&columns, 1, MPI_INT, 0, MPI_COMM_WORLD); - if (rows <= 0 || columns <= 0) { + MPI_Bcast(&rows, 1, MPI_UINT64_T, 0, MPI_COMM_WORLD); + MPI_Bcast(&columns, 1, MPI_UINT64_T, 0, MPI_COMM_WORLD); + + const std::uint64_t base = rows * columns; + if (columns > static_cast(std::numeric_limits::max())) { return false; } - std::vector sendbuf; - if (rank == 0) { - sendbuf.resize((rows * columns)); - for (int i = 0; i < rows; i++) { - for (int j = 0; j < columns; j++) { - sendbuf[i * columns + j] = input_matrix[i][j]; - } - } + if (base > static_cast(std::numeric_limits::max())) { + return false; } + + const int columns_int = static_cast(columns); + const int base_int = static_cast(base); + GetOutput().assign(static_cast(columns_int), 0); + + std::vector sendbuf; + PrepareSendBuffer(input_matrix, rank, rows, columns, sendbuf); std::vector elem_for_proc(size); std::vector id_elem(size); int displacement = 0; for (int i = 0; i < size; i++) { - elem_for_proc[i] = rows * columns / size + (i < rows * columns % size ? 1 : 0); + elem_for_proc[i] = static_cast(base_int / size) + (i < (base_int % size) ? 1 : 0); id_elem[i] = displacement; displacement += elem_for_proc[i]; } - int mpi_displacement = id_elem[rank] % columns; - std::vector buf(elem_for_proc[rank], 0); + const int mpi_displacement = id_elem[rank] % static_cast(columns_int); + std::vector buf(static_cast(elem_for_proc[rank]), 0); MPI_Scatterv(rank == 0 ? sendbuf.data() : nullptr, elem_for_proc.data(), id_elem.data(), MPI_INT, buf.data(), elem_for_proc[rank], MPI_INT, 0, MPI_COMM_WORLD); - std::vector sum(columns, 0); - for (int i = 0; i < elem_for_proc[rank]; i++) { - int new_col = (i + mpi_displacement) % columns; - sum[new_col] += buf[i]; + std::vector sum(static_cast(columns_int), 0); + for (int i = 0; i < (elem_for_proc[rank]); i++) { + int new_col = (i + mpi_displacement) % columns_int; + sum[static_cast(new_col)] += buf[static_cast(i)]; } - MPI_Allreduce(sum.data(), GetOutput().data(), columns, MPI_INT, MPI_SUM, MPI_COMM_WORLD); + MPI_Allreduce(sum.data(), GetOutput().data(), columns_int, MPI_INT, MPI_SUM, MPI_COMM_WORLD); return !GetOutput().empty(); } diff --git a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp index e54678c442..e2abfe975c 100644 --- a/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp +++ b/tasks/sannikov_i_column_sum/seq/src/ops_seq.cpp @@ -40,10 +40,6 @@ bool SannikovIColumnSumSEQ::PreProcessingImpl() { bool SannikovIColumnSumSEQ::RunImpl() { const auto &input_matrix = GetInput(); - if (input_matrix.empty()) { - return false; - } - for (const auto &row : input_matrix) { std::size_t column = 0; for (const auto &value : row) { From 080a744005612ba1027069137e18d53a6ad24b18 Mon Sep 17 00:00:00 2001 From: ivan-sannikov Date: Mon, 24 Nov 2025 19:41:20 +0000 Subject: [PATCH 15/15] fix artefact --- scripts/build/perf_stat_dir/perf_log.txt | 0 tasks/sannikov_i_column_sum/data/pic.jpg | Bin 15356 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 scripts/build/perf_stat_dir/perf_log.txt delete mode 100644 tasks/sannikov_i_column_sum/data/pic.jpg diff --git a/scripts/build/perf_stat_dir/perf_log.txt b/scripts/build/perf_stat_dir/perf_log.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tasks/sannikov_i_column_sum/data/pic.jpg b/tasks/sannikov_i_column_sum/data/pic.jpg deleted file mode 100644 index 34458023494a39d66880a98aa5dcad18eb14b249..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15356 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