From d10091e9e973e6fdef11288697e5e67c91dcf822 Mon Sep 17 00:00:00 2001 From: myffii <132840123+myffii@users.noreply.github.com> Date: Thu, 26 Dec 2024 13:07:27 +0300 Subject: [PATCH 1/8] First --- .../func_tests/main.cpp | 262 ++++++++++++ .../include/ops_mpi.hpp | 55 +++ .../perf_tests/main.cpp | 96 +++++ .../src/ops_mpi.cpp | 404 ++++++++++++++++++ 4 files changed, 817 insertions(+) create mode 100644 tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp create mode 100644 tasks/mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp create mode 100644 tasks/mpi/nasedkin_e_strassen_algorithm/perf_tests/main.cpp create mode 100644 tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp diff --git a/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp b/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp new file mode 100644 index 00000000000..797d67f90a3 --- /dev/null +++ b/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp @@ -0,0 +1,262 @@ +#include + +#include +#include +#include +#include +#include + +#include "mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp" + +std::vector generateRandomMatrix(int size) { + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_real_distribution<> dis(-100.0, 100.0); + std::vector matrix(size * size); + + for (int i = 0; i < size * size; i++) { + matrix[i] = dis(gen); + } + return matrix; +} + +TEST(nasedkin_e_strassen_algorithm_mpi, Test_2x2) { + boost::mpi::communicator world; + + int matrixSize = 2; + std::vector matrixA; + std::vector matrixB; + if (world.rank() == 0) { + matrixA = generateRandomMatrix(matrixSize); + matrixB = generateRandomMatrix(matrixSize); + } + std::vector resultParallel(matrixSize * matrixSize, 0.0); + std::vector resultSeq(matrixSize * matrixSize, 0.0); + +std::shared_ptr taskDataSeq = std::make_shared(); + +if (world.rank() == 0) { +taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); +taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); +taskDataSeq->inputs_count.emplace_back(matrixA.size()); +taskDataSeq->inputs_count.emplace_back(matrixB.size()); +taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); +taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + +nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); +ASSERT_TRUE(testMpiTaskSeq.validation()); +ASSERT_TRUE(testMpiTaskSeq.pre_processing()); +ASSERT_TRUE(testMpiTaskSeq.run()); +ASSERT_TRUE(testMpiTaskSeq.post_processing()); +} + + std::shared_ptr taskDataParallel = std::make_shared(); + + if (world.rank() == 0) { + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataParallel->inputs_count.emplace_back(matrixA.size()); + taskDataParallel->inputs_count.emplace_back(matrixB.size()); + taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); + taskDataParallel->outputs_count.emplace_back(resultParallel.size()); +} + nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); + ASSERT_TRUE(testMpiTaskParallel.validation()); + ASSERT_TRUE(testMpiTaskParallel.pre_processing()); + ASSERT_TRUE(testMpiTaskParallel.run()); + ASSERT_TRUE(testMpiTaskParallel.post_processing()); +ASSERT_EQ(resultSeq, resultParallel); +} + +TEST(nasedkin_e_strassen_algorithm_mpi, Test_4x4) { +boost::mpi::communicator world; + +int matrixSize = 4; +std::vector matrixA; +std::vector matrixB; +if (world.rank() == 0) { +matrixA = generateRandomMatrix(matrixSize); +matrixB = generateRandomMatrix(matrixSize); +} +std::vector resultParallel(matrixSize * matrixSize, 0.0); +std::vector resultSeq(matrixSize * matrixSize, 0.0); + +std::shared_ptr taskDataSeq = std::make_shared(); + +if (world.rank() == 0) { +taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); +taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); +taskDataSeq->inputs_count.emplace_back(matrixA.size()); +taskDataSeq->inputs_count.emplace_back(matrixB.size()); +taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); +taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + +nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); +ASSERT_TRUE(testMpiTaskSeq.validation()); +ASSERT_TRUE(testMpiTaskSeq.pre_processing()); +ASSERT_TRUE(testMpiTaskSeq.run()); +ASSERT_TRUE(testMpiTaskSeq.post_processing()); +} + +std::shared_ptr taskDataParallel = std::make_shared(); + +if (world.rank() == 0) { +taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); +taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); +taskDataParallel->inputs_count.emplace_back(matrixA.size()); +taskDataParallel->inputs_count.emplace_back(matrixB.size()); +taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); +taskDataParallel->outputs_count.emplace_back(resultParallel.size()); +} +nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); +ASSERT_TRUE(testMpiTaskParallel.validation()); +ASSERT_TRUE(testMpiTaskParallel.pre_processing()); +ASSERT_TRUE(testMpiTaskParallel.run()); +ASSERT_TRUE(testMpiTaskParallel.post_processing()); + +ASSERT_EQ(resultSeq, resultParallel); +} + +TEST(nasedkin_e_strassen_algorithm_mpi, Test_8x8) { +boost::mpi::communicator world; + +int matrixSize = 8; +std::vector matrixA; +std::vector matrixB; +if (world.rank() == 0) { +matrixA = generateRandomMatrix(matrixSize); +matrixB = generateRandomMatrix(matrixSize); +} +std::vector resultParallel(matrixSize * matrixSize, 0.0); +std::vector resultSeq(matrixSize * matrixSize, 0.0); + +std::shared_ptr taskDataSeq = std::make_shared(); + +if (world.rank() == 0) { +taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); +taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); +taskDataSeq->inputs_count.emplace_back(matrixA.size()); +taskDataSeq->inputs_count.emplace_back(matrixB.size()); +taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); +taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + +nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); +ASSERT_TRUE(testMpiTaskSeq.validation()); +ASSERT_TRUE(testMpiTaskSeq.pre_processing()); +ASSERT_TRUE(testMpiTaskSeq.run()); +ASSERT_TRUE(testMpiTaskSeq.post_processing()); +} + +std::shared_ptr taskDataParallel = std::make_shared(); + +if (world.rank() == 0) { +taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); +taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); +taskDataParallel->inputs_count.emplace_back(matrixA.size()); +taskDataParallel->inputs_count.emplace_back(matrixB.size()); +taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); +taskDataParallel->outputs_count.emplace_back(resultParallel.size()); +} +nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); +ASSERT_TRUE(testMpiTaskParallel.validation()); +ASSERT_TRUE(testMpiTaskParallel.pre_processing()); +ASSERT_TRUE(testMpiTaskParallel.run()); +ASSERT_TRUE(testMpiTaskParallel.post_processing()); +ASSERT_EQ(resultSeq, resultParallel); +} + +TEST(nasedkin_e_strassen_algorithm_mpi, Test_16x16) { +boost::mpi::communicator world; + +int matrixSize = 16; +std::vector matrixA; +std::vector matrixB; +if (world.rank() == 0) { +matrixA = generateRandomMatrix(matrixSize); +matrixB = generateRandomMatrix(matrixSize); +} +std::vector resultParallel(matrixSize * matrixSize, 0.0); +std::vector resultSeq(matrixSize * matrixSize, 0.0); + +std::shared_ptr taskDataSeq = std::make_shared(); + +if (world.rank() == 0) { +taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); +taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); +taskDataSeq->inputs_count.emplace_back(matrixA.size()); +taskDataSeq->inputs_count.emplace_back(matrixB.size()); +taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); +taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + +nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); +ASSERT_TRUE(testMpiTaskSeq.validation()); +ASSERT_TRUE(testMpiTaskSeq.pre_processing()); +ASSERT_TRUE(testMpiTaskSeq.run()); +ASSERT_TRUE(testMpiTaskSeq.post_processing()); +} + +std::shared_ptr taskDataParallel = std::make_shared(); + +if (world.rank() == 0) { +taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); +taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); +taskDataParallel->inputs_count.emplace_back(matrixA.size()); +taskDataParallel->inputs_count.emplace_back(matrixB.size()); +taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); +taskDataParallel->outputs_count.emplace_back(resultParallel.size()); +} +nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); +ASSERT_TRUE(testMpiTaskParallel.validation()); +ASSERT_TRUE(testMpiTaskParallel.pre_processing()); +ASSERT_TRUE(testMpiTaskParallel.run()); +ASSERT_TRUE(testMpiTaskParallel.post_processing()); +ASSERT_EQ(resultSeq, resultParallel); +} + +TEST(nasedkin_e_strassen_algorithm_mpi, Test_32x32) { +boost::mpi::communicator world; + +int matrixSize = 32; +std::vector matrixA; +std::vector matrixB; +if (world.rank() == 0) { +matrixA = generateRandomMatrix(matrixSize); +matrixB = generateRandomMatrix(matrixSize); +} +std::vector resultParallel(matrixSize * matrixSize, 0.0); +std::vector resultSeq(matrixSize * matrixSize, 0.0); + +std::shared_ptr taskDataSeq = std::make_shared(); + +if (world.rank() == 0) { +taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); +taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); +taskDataSeq->inputs_count.emplace_back(matrixA.size()); +taskDataSeq->inputs_count.emplace_back(matrixB.size()); +taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); +taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + +nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); +ASSERT_TRUE(testMpiTaskSeq.validation()); +ASSERT_TRUE(testMpiTaskSeq.pre_processing()); +ASSERT_TRUE(testMpiTaskSeq.run()); +ASSERT_TRUE(testMpiTaskSeq.post_processing()); +} + +std::shared_ptr taskDataParallel = std::make_shared(); + +if (world.rank() == 0) { +taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); +taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); +taskDataParallel->inputs_count.emplace_back(matrixA.size()); +taskDataParallel->inputs_count.emplace_back(matrixB.size()); +taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); +taskDataParallel->outputs_count.emplace_back(resultParallel.size()); +} +nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); +ASSERT_TRUE(testMpiTaskParallel.validation()); +ASSERT_TRUE(testMpiTaskParallel.pre_processing()); +ASSERT_TRUE(testMpiTaskParallel.run()); +ASSERT_TRUE(testMpiTaskParallel.post_processing()); +ASSERT_EQ(resultSeq, resultParallel); +} \ No newline at end of file diff --git a/tasks/mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp b/tasks/mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp new file mode 100644 index 00000000000..8362082f385 --- /dev/null +++ b/tasks/mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include "core/task/include/task.hpp" + +namespace nasedkin_e_strassen_algorithm { + + class StrassenAlgorithmSEQ : public ppc::core::Task { + public: + explicit StrassenAlgorithmSEQ(std::shared_ptr taskData_) : Task(std::move(taskData_)) {} + + bool pre_processing() override; + bool validation() override; + bool run() override; + bool post_processing() override; + + private: + static std::vector strassen_multiply_seq(const std::vector& matrixA, const std::vector& matrixB, size_t size); + + std::vector inputMatrixA; + std::vector inputMatrixB; + std::vector outputMatrix; + size_t matrixSize; + }; + + class StrassenAlgorithmMPI : public ppc::core::Task { + public: + explicit StrassenAlgorithmMPI(std::shared_ptr taskData_) : Task(std::move(taskData_)) {} + + bool pre_processing() override; + bool validation() override; + bool run() override; + bool post_processing() override; + + private: + static std::vector strassen_multiply(const std::vector& matrixA, const std::vector& matrixB, size_t size); + + boost::mpi::communicator world; + + std::vector inputMatrixA; + std::vector inputMatrixB; + std::vector outputMatrix; + size_t matrixSize; + }; + + std::vector strassen_recursive(const std::vector& matrixA, + const std::vector& matrixB, size_t size); + std::vector matrix_add(const std::vector& matrixA, const std::vector& matrixB, size_t size); + std::vector matrix_subtract(const std::vector& matrixA, const std::vector& matrixB, size_t size); +} // namespace nasedkin_e_strassen_algorithm \ No newline at end of file diff --git a/tasks/mpi/nasedkin_e_strassen_algorithm/perf_tests/main.cpp b/tasks/mpi/nasedkin_e_strassen_algorithm/perf_tests/main.cpp new file mode 100644 index 00000000000..1e40abdc35c --- /dev/null +++ b/tasks/mpi/nasedkin_e_strassen_algorithm/perf_tests/main.cpp @@ -0,0 +1,96 @@ +#include + +#include +#include +#include +#include "core/perf/include/perf.hpp" +#include "mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp" + +std::vector generateRandomMatrix(int size) { + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_real_distribution<> dis(-100.0, 100.0); + std::vector matrix(size * size); + for (int i = 0; i < size * size; i++) { + matrix[i] = dis(gen); + } + return matrix; +} + +TEST(nasedkin_e_strassen_algorithm_perf_test, test_pipeline_run) { + int matrixSize = 1024; + boost::mpi::communicator world; + std::vector matrixA = generateRandomMatrix(matrixSize); + std::vector matrixB = generateRandomMatrix(matrixSize); + std::vector resultParallel(matrixSize * matrixSize, 0.0); + + std::shared_ptr taskDataParallel = std::make_shared(); + + if (world.rank() == 0) { + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataParallel->inputs_count.emplace_back(matrixA.size()); + taskDataParallel->inputs_count.emplace_back(matrixB.size()); + taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); + taskDataParallel->outputs_count.emplace_back(resultParallel.size()); + } + + auto testMpiTaskParallel = std::make_shared(taskDataParallel); + ASSERT_EQ(testMpiTaskParallel->validation(), true); + testMpiTaskParallel->pre_processing(); + testMpiTaskParallel->run(); + testMpiTaskParallel->post_processing(); + + auto perfAttr = std::make_shared(); + perfAttr->num_running = 10; + const boost::mpi::timer currentTimer; + perfAttr->current_timer = [&] { return currentTimer.elapsed(); }; + + auto perfResults = std::make_shared(); + + auto perfAnalyzer = std::make_shared(testMpiTaskParallel); + perfAnalyzer->pipeline_run(perfAttr, perfResults); + + if (world.rank() == 0) { + ppc::core::Perf::print_perf_statistic(perfResults); + } +} + +TEST(nasedkin_e_strassen_algorithm_perf_test, test_task_run) { + int matrixSize = 1024; + boost::mpi::communicator world; + std::vector matrixA = generateRandomMatrix(matrixSize); + std::vector matrixB = generateRandomMatrix(matrixSize); + std::vector resultParallel(matrixSize * matrixSize, 0.0); + + std::shared_ptr taskDataParallel = std::make_shared(); + + if (world.rank() == 0) { + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataParallel->inputs_count.emplace_back(matrixA.size()); + taskDataParallel->inputs_count.emplace_back(matrixB.size()); + taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); + taskDataParallel->outputs_count.emplace_back(resultParallel.size()); + } + + auto testMpiTaskParallel = std::make_shared(taskDataParallel); + ASSERT_EQ(testMpiTaskParallel->validation(), true); + testMpiTaskParallel->pre_processing(); + testMpiTaskParallel->run(); + testMpiTaskParallel->post_processing(); + + auto perfAttr = std::make_shared(); + perfAttr->num_running = 10; + const boost::mpi::timer currentTimer; + perfAttr->current_timer = [&] { return currentTimer.elapsed(); }; + + auto perfResults = std::make_shared(); + + auto perfAnalyzer = std::make_shared(testMpiTaskParallel); + perfAnalyzer->task_run(perfAttr, perfResults); + + if (world.rank() == 0) { + ppc::core::Perf::print_perf_statistic(perfResults); + } +} \ No newline at end of file diff --git a/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp b/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp new file mode 100644 index 00000000000..5956e07261a --- /dev/null +++ b/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp @@ -0,0 +1,404 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp" + +namespace nasedkin_e_strassen_algorithm { + + bool StrassenAlgorithmSEQ::pre_processing() { + internal_order_test(); + auto* inputsA = reinterpret_cast(taskData->inputs[0]); + auto* inputsB = reinterpret_cast(taskData->inputs[1]); + matrixSize = static_cast(std::sqrt(taskData->inputs_count[0])); + inputMatrixA.assign(inputsA, inputsA + matrixSize * matrixSize); + inputMatrixB.assign(inputsB, inputsB + matrixSize * matrixSize); + outputMatrix.resize(matrixSize * matrixSize, 0.0); + return true; + } + + bool StrassenAlgorithmSEQ::validation() { + internal_order_test(); + if (taskData->inputs.empty()) { + return false; + } + if (taskData->inputs_count[0] != taskData->inputs_count[1]) { + return false; + } + if (taskData->inputs_count[0] != taskData->outputs_count[0]) { + return false; + } + return true; + } + + bool StrassenAlgorithmSEQ::run() { + internal_order_test(); + outputMatrix = strassen_multiply_seq(inputMatrixA, inputMatrixB, matrixSize); + return true; + } + + bool StrassenAlgorithmSEQ::post_processing() { + internal_order_test(); + auto* outputs = reinterpret_cast(taskData->outputs[0]); + std::copy(outputMatrix.begin(), outputMatrix.end(), outputs); + return true; + } + +bool StrassenAlgorithmMPI::pre_processing() { + internal_order_test(); + int rank = world.rank(); + if (rank == 0) { + auto* inputsA = reinterpret_cast(taskData->inputs[0]); + auto* inputsB = reinterpret_cast(taskData->inputs[1]); + + if (inputsA == nullptr || inputsB == nullptr) { + return false; + } + + matrixSize = static_cast(std::sqrt(taskData->inputs_count[0])); + + if (matrixSize * matrixSize != taskData->inputs_count[0]) { + return false; + } + + inputMatrixA.assign(inputsA, inputsA + matrixSize * matrixSize); + inputMatrixB.assign(inputsB, inputsB + matrixSize * matrixSize); + outputMatrix.resize(matrixSize * matrixSize, 0.0); + } + return true; +} + + bool StrassenAlgorithmMPI::validation() { + internal_order_test(); + int rank = world.rank(); + if (rank == 0) { + if (taskData->inputs.empty()) { + return false; + } + if (taskData->inputs_count[0] != taskData->inputs_count[1]) { + return false; + } + if (taskData->inputs_count[0] != taskData->outputs_count[0]) { + return false; + } + } + return true; + } + + bool StrassenAlgorithmMPI::run() { + internal_order_test(); + boost::mpi::broadcast(world, inputMatrixA, 0); + boost::mpi::broadcast(world, inputMatrixB, 0); + boost::mpi::broadcast(world, matrixSize, 0); + outputMatrix = strassen_multiply(inputMatrixA, inputMatrixB, matrixSize); + return true; + } + + bool StrassenAlgorithmMPI::post_processing() { + internal_order_test(); + int rank = world.rank(); + if (rank == 0) { + auto* outputs = reinterpret_cast(taskData->outputs[0]); + std::copy(outputMatrix.begin(), outputMatrix.end(), outputs); + } + return true; + } + + std::vector matrix_add(const std::vector& matrixA, + const std::vector& matrixB, + size_t size) { + std::vector result(size * size); + for (size_t i = 0; i < size * size; ++i) { + result[i] = matrixA[i] + matrixB[i]; + } + return result; + } + + std::vector matrix_subtract(const std::vector& matrixA, + const std::vector& matrixB, + size_t size) { + std::vector result(size * size); + for (size_t i = 0; i < size * size; ++i) { + result[i] = matrixA[i] - matrixB[i]; + } + return result; + } + + std::vector strassen_recursive(const std::vector& matrixA, + const std::vector& matrixB, size_t size) { + if (size == 1) { + return {matrixA[0] * matrixB[0]}; + } + + size_t half_size = size / 2; + + std::vector A11(half_size * half_size); + std::vector A12(half_size * half_size); + std::vector A21(half_size * half_size); + std::vector A22(half_size * half_size); + + std::vector B11(half_size * half_size); + std::vector B12(half_size * half_size); + std::vector B21(half_size * half_size); + std::vector B22(half_size * half_size); + + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + A11[i * half_size + j] = matrixA[i * size + j]; + A12[i * half_size + j] = matrixA[i * size + j + half_size]; + A21[i * half_size + j] = matrixA[(i + half_size) * size + j]; + A22[i * half_size + j] = matrixA[(i + half_size) * size + j + half_size]; + + B11[i * half_size + j] = matrixB[i * size + j]; + B12[i * half_size + j] = matrixB[i * size + j + half_size]; + B21[i * half_size + j] = matrixB[(i + half_size) * size + j]; + B22[i * half_size + j] = matrixB[(i + half_size) * size + j + half_size]; + } + } + + std::vector M1 = strassen_recursive(matrix_add(A11, A22, half_size), + matrix_add(B11, B22, half_size), half_size); + std::vector M2 = strassen_recursive(matrix_add(A21, A22, half_size), B11, half_size); + std::vector M3 = strassen_recursive(A11, matrix_subtract(B12, B22, half_size), half_size); + std::vector M4 = strassen_recursive(A22, matrix_subtract(B21, B11, half_size), half_size); + std::vector M5 = strassen_recursive(matrix_add(A11, A12, half_size), B22, half_size); + std::vector M6 = strassen_recursive(matrix_subtract(A21, A11, half_size), + matrix_add(B11, B12, half_size), half_size); + std::vector M7 = strassen_recursive(matrix_subtract(A12, A22, half_size), + matrix_add(B21, B22, half_size), half_size); + + std::vector C11 = matrix_add(matrix_subtract(matrix_add(M1, M4, half_size), M5, half_size), M7, half_size); + std::vector C12 = matrix_add(M3, M5, half_size); + std::vector C21 = matrix_add(M2, M4, half_size); + std::vector C22 = matrix_add(matrix_subtract(matrix_add(M1, M3, half_size), M2, half_size), M6, half_size); + + std::vector local_result(size * size); + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + local_result[i * size + j] = C11[i * half_size + j]; + local_result[i * size + j + half_size] = C12[i * half_size + j]; + local_result[(i + half_size) * size + j] = C21[i * half_size + j]; + local_result[(i + half_size) * size + j + half_size] = C22[i * half_size + j]; + } + } + + return local_result; + } + + std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vector& matrixA, + const std::vector& matrixB, size_t size) { + if (size == 1) { + return {matrixA[0] * matrixB[0]}; + } + + size_t new_size = 1; + while (new_size < size) { + new_size *= 2; + } + + size_t half_size = new_size / 2; + + std::vector A11(half_size * half_size); + std::vector A12(half_size * half_size); + std::vector A21(half_size * half_size); + std::vector A22(half_size * half_size); + + std::vector B11(half_size * half_size); + std::vector B12(half_size * half_size); + std::vector B21(half_size * half_size); + std::vector B22(half_size * half_size); + + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + A11[i * half_size + j] = matrixA[i * new_size + j]; + A12[i * half_size + j] = matrixA[i * new_size + j + half_size]; + A21[i * half_size + j] = matrixA[(i + half_size) * new_size + j]; + A22[i * half_size + j] = matrixA[(i + half_size) * new_size + j + half_size]; + + B11[i * half_size + j] = matrixB[i * new_size + j]; + B12[i * half_size + j] = matrixB[i * new_size + j + half_size]; + B21[i * half_size + j] = matrixB[(i + half_size) * new_size + j]; + B22[i * half_size + j] = matrixB[(i + half_size) * new_size + j + half_size]; + } + } + + std::vector> M(7); + std::vector> tasks = { + matrix_add(A11, A22, half_size), + matrix_add(A21, A22, half_size), + A11, + A22, + matrix_add(A11, A12, half_size), + matrix_subtract(A21, A11, half_size), + matrix_subtract(A12, A22, half_size) + }; + + std::vector> tasksB = { + matrix_add(B11, B22, half_size), + B11, + matrix_subtract(B12, B22, half_size), + matrix_subtract(B21, B11, half_size), + B22, + matrix_add(B11, B12, half_size), + matrix_add(B21, B22, half_size) + }; + + for (int i = 0; i < 7; ++i) { + M[i] = strassen_recursive(tasks[i], tasksB[i], half_size); + } + + + for (int i = 0; i < 7; ++i) { + std::vector result; + M[i] = result; + } + + std::vector C11 = + matrix_add(matrix_subtract(matrix_add(M[0], M[3], half_size), M[4], half_size), M[6], half_size); + std::vector C12 = matrix_add(M[2], M[4], half_size); + std::vector C21 = matrix_add(M[1], M[3], half_size); + std::vector C22 = + matrix_add(matrix_subtract(matrix_add(M[0], M[2], half_size), M[1], half_size), M[5], half_size); + + std::vector result(size * size); + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + result[i * size + j] = C11[i * half_size + j]; + result[i * size + j + half_size] = C12[i * half_size + j]; + result[(i + half_size) * size + j] = C21[i * half_size + j]; + result[(i + half_size) * size + j + half_size] = C22[i * half_size + j]; + } + } + return result; + return {}; + } + + std::vector StrassenAlgorithmMPI::strassen_multiply(const std::vector& matrixA, + const std::vector& matrixB, size_t size) { + boost::mpi::environment env; + boost::mpi::communicator world; + + int rank = world.rank(); + int num_procs = world.size(); + + if (size == 1) { + return {matrixA[0] * matrixB[0]}; + } + + size_t new_size = 1; + while (new_size < size) { + new_size *= 2; + } + + size_t half_size = new_size / 2; + + std::vector A11(half_size * half_size); + std::vector A12(half_size * half_size); + std::vector A21(half_size * half_size); + std::vector A22(half_size * half_size); + + std::vector B11(half_size * half_size); + std::vector B12(half_size * half_size); + std::vector B21(half_size * half_size); + std::vector B22(half_size * half_size); + + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + A11[i * half_size + j] = matrixA[i * new_size + j]; + A12[i * half_size + j] = matrixA[i * new_size + j + half_size]; + A21[i * half_size + j] = matrixA[(i + half_size) * new_size + j]; + A22[i * half_size + j] = matrixA[(i + half_size) * new_size + j + half_size]; + + B11[i * half_size + j] = matrixB[i * new_size + j]; + B12[i * half_size + j] = matrixB[i * new_size + j + half_size]; + B21[i * half_size + j] = matrixB[(i + half_size) * new_size + j]; + B22[i * half_size + j] = matrixB[(i + half_size) * new_size + j + half_size]; + } + } + + std::vector> M(7); + if (rank == 0) { + std::vector> tasks = { + matrix_add(A11, A22, half_size), + matrix_add(A21, A22, half_size), + A11, + A22, + matrix_add(A11, A12, half_size), + matrix_subtract(A21, A11, half_size), + matrix_subtract(A12, A22, half_size) + }; + + std::vector> tasksB = { + matrix_add(B11, B22, half_size), + B11, + matrix_subtract(B12, B22, half_size), + matrix_subtract(B21, B11, half_size), + B22, + matrix_add(B11, B12, half_size), + matrix_add(B21, B22, half_size) + }; + + for (int i = 0; i < 7; ++i) { + if (i % num_procs == 0) { + M[i] = strassen_recursive(tasks[i], tasksB[i], half_size); + } else { + world.send(i % num_procs, i, tasks[i]); + world.send(i % num_procs, i, tasksB[i]); + } + } + } + + for (int i = 0; i < 7; ++i) { + if (i % num_procs == rank && i % num_procs != 0) { + std::vector taskA; + std::vector taskB; + + world.recv(0, i, taskA); + world.recv(0, i, taskB); + + M[i] = strassen_recursive(taskA, taskB, half_size); + + world.send(0, i, M[i]); + } + } + + if (rank == 0) { + for (int i = 0; i < 7; ++i) { + if (i % num_procs != 0) { + std::vector result; + world.recv(i % num_procs, i, result); + M[i] = result; + } + } + } + + if (rank == 0) { + + std::vector C11 = + matrix_add(matrix_subtract(matrix_add(M[0], M[3], half_size), M[4], half_size), M[6], half_size); + std::vector C12 = matrix_add(M[2], M[4], half_size); + std::vector C21 = matrix_add(M[1], M[3], half_size); + std::vector C22 = + matrix_add(matrix_subtract(matrix_add(M[0], M[2], half_size), M[1], half_size), M[5], half_size); + + + std::vector result(size * size); + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + result[i * size + j] = C11[i * half_size + j]; + result[i * size + j + half_size] = C12[i * half_size + j]; + result[(i + half_size) * size + j] = C21[i * half_size + j]; + result[(i + half_size) * size + j + half_size] = C22[i * half_size + j]; + } + } + return result; + } + return {}; + } + +} // namespace nasedkin_e_strassen_algorithm \ No newline at end of file From e1795b2deef642e67006961c3125f176b685b5e9 Mon Sep 17 00:00:00 2001 From: myffii <132840123+myffii@users.noreply.github.com> Date: Thu, 26 Dec 2024 16:04:00 +0300 Subject: [PATCH 2/8] Added SEQ, fixed clang-format --- .../func_tests/main.cpp | 433 +++++----- .../include/ops_mpi.hpp | 94 ++- .../perf_tests/main.cpp | 3 +- .../src/ops_mpi.cpp | 791 ++++++++++-------- .../func_tests/main.cpp | 153 ++++ .../include/ops_seq.hpp | 37 + .../perf_tests/main.cpp | 95 +++ .../src/ops_seq.cpp | 263 ++++++ 8 files changed, 1286 insertions(+), 583 deletions(-) create mode 100644 tasks/seq/nasedkin_e_strassen_algorithm/func_tests/main.cpp create mode 100644 tasks/seq/nasedkin_e_strassen_algorithm/include/ops_seq.hpp create mode 100644 tasks/seq/nasedkin_e_strassen_algorithm/perf_tests/main.cpp create mode 100644 tasks/seq/nasedkin_e_strassen_algorithm/src/ops_seq.cpp diff --git a/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp b/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp index 797d67f90a3..1ed9a097b6e 100644 --- a/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp +++ b/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp @@ -14,6 +14,11 @@ std::vector generateRandomMatrix(int size) { std::uniform_real_distribution<> dis(-100.0, 100.0); std::vector matrix(size * size); + if (size <= 0) { + std::cout << "generateRandomMatrix: Invalid size: " << size << std::endl; + return matrix; + } + for (int i = 0; i < size * size; i++) { matrix[i] = dis(gen); } @@ -29,26 +34,31 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_2x2) { if (world.rank() == 0) { matrixA = generateRandomMatrix(matrixSize); matrixB = generateRandomMatrix(matrixSize); + std::cout << "Test: MatrixA size = " << matrixSize << ", MatrixB size = " << matrixSize << std::endl; } std::vector resultParallel(matrixSize * matrixSize, 0.0); std::vector resultSeq(matrixSize * matrixSize, 0.0); -std::shared_ptr taskDataSeq = std::make_shared(); - -if (world.rank() == 0) { -taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); -taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); -taskDataSeq->inputs_count.emplace_back(matrixA.size()); -taskDataSeq->inputs_count.emplace_back(matrixB.size()); -taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); -taskDataSeq->outputs_count.emplace_back(resultSeq.size()); - -nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); -ASSERT_TRUE(testMpiTaskSeq.validation()); -ASSERT_TRUE(testMpiTaskSeq.pre_processing()); -ASSERT_TRUE(testMpiTaskSeq.run()); -ASSERT_TRUE(testMpiTaskSeq.post_processing()); -} + std::shared_ptr taskDataSeq = std::make_shared(); + + if (world.rank() == 0) { + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] + << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); + ASSERT_TRUE(testMpiTaskSeq.validation()); + ASSERT_TRUE(testMpiTaskSeq.pre_processing()); + ASSERT_TRUE(testMpiTaskSeq.run()); + ASSERT_TRUE(testMpiTaskSeq.post_processing()); + std::cout << "SEQ Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; + } std::shared_ptr taskDataParallel = std::make_shared(); @@ -59,204 +69,247 @@ ASSERT_TRUE(testMpiTaskSeq.post_processing()); taskDataParallel->inputs_count.emplace_back(matrixB.size()); taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); taskDataParallel->outputs_count.emplace_back(resultParallel.size()); -} + + std::cout << "Test: TaskData inputs_count[0] = " << taskDataParallel->inputs_count[0] + << ", inputs_count[1] = " << taskDataParallel->inputs_count[1] << std::endl; + } nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); ASSERT_TRUE(testMpiTaskParallel.validation()); ASSERT_TRUE(testMpiTaskParallel.pre_processing()); ASSERT_TRUE(testMpiTaskParallel.run()); ASSERT_TRUE(testMpiTaskParallel.post_processing()); -ASSERT_EQ(resultSeq, resultParallel); + ASSERT_EQ(resultSeq, resultParallel); + std::cout << "Parallel Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; } TEST(nasedkin_e_strassen_algorithm_mpi, Test_4x4) { -boost::mpi::communicator world; - -int matrixSize = 4; -std::vector matrixA; -std::vector matrixB; -if (world.rank() == 0) { -matrixA = generateRandomMatrix(matrixSize); -matrixB = generateRandomMatrix(matrixSize); -} -std::vector resultParallel(matrixSize * matrixSize, 0.0); -std::vector resultSeq(matrixSize * matrixSize, 0.0); - -std::shared_ptr taskDataSeq = std::make_shared(); - -if (world.rank() == 0) { -taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); -taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); -taskDataSeq->inputs_count.emplace_back(matrixA.size()); -taskDataSeq->inputs_count.emplace_back(matrixB.size()); -taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); -taskDataSeq->outputs_count.emplace_back(resultSeq.size()); - -nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); -ASSERT_TRUE(testMpiTaskSeq.validation()); -ASSERT_TRUE(testMpiTaskSeq.pre_processing()); -ASSERT_TRUE(testMpiTaskSeq.run()); -ASSERT_TRUE(testMpiTaskSeq.post_processing()); -} + boost::mpi::communicator world; -std::shared_ptr taskDataParallel = std::make_shared(); + int matrixSize = 4; + std::vector matrixA; + std::vector matrixB; + if (world.rank() == 0) { + matrixA = generateRandomMatrix(matrixSize); + matrixB = generateRandomMatrix(matrixSize); + std::cout << "Test: MatrixA size = " << matrixSize << ", MatrixB size = " << matrixSize << std::endl; + } + std::vector resultParallel(matrixSize * matrixSize, 0.0); + std::vector resultSeq(matrixSize * matrixSize, 0.0); -if (world.rank() == 0) { -taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); -taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); -taskDataParallel->inputs_count.emplace_back(matrixA.size()); -taskDataParallel->inputs_count.emplace_back(matrixB.size()); -taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); -taskDataParallel->outputs_count.emplace_back(resultParallel.size()); -} -nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); -ASSERT_TRUE(testMpiTaskParallel.validation()); -ASSERT_TRUE(testMpiTaskParallel.pre_processing()); -ASSERT_TRUE(testMpiTaskParallel.run()); -ASSERT_TRUE(testMpiTaskParallel.post_processing()); + std::shared_ptr taskDataSeq = std::make_shared(); + + if (world.rank() == 0) { + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] + << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); + ASSERT_TRUE(testMpiTaskSeq.validation()); + ASSERT_TRUE(testMpiTaskSeq.pre_processing()); + ASSERT_TRUE(testMpiTaskSeq.run()); + ASSERT_TRUE(testMpiTaskSeq.post_processing()); + std::cout << "Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; + } + + std::shared_ptr taskDataParallel = std::make_shared(); + + if (world.rank() == 0) { + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataParallel->inputs_count.emplace_back(matrixA.size()); + taskDataParallel->inputs_count.emplace_back(matrixB.size()); + taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); + taskDataParallel->outputs_count.emplace_back(resultParallel.size()); + + std::cout << "Test: TaskData inputs_count[0] = " << taskDataParallel->inputs_count[0] + << ", inputs_count[1] = " << taskDataParallel->inputs_count[1] << std::endl; + } + nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); + ASSERT_TRUE(testMpiTaskParallel.validation()); + ASSERT_TRUE(testMpiTaskParallel.pre_processing()); + ASSERT_TRUE(testMpiTaskParallel.run()); + ASSERT_TRUE(testMpiTaskParallel.post_processing()); + std::cout << "Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; -ASSERT_EQ(resultSeq, resultParallel); + ASSERT_EQ(resultSeq, resultParallel); } TEST(nasedkin_e_strassen_algorithm_mpi, Test_8x8) { -boost::mpi::communicator world; - -int matrixSize = 8; -std::vector matrixA; -std::vector matrixB; -if (world.rank() == 0) { -matrixA = generateRandomMatrix(matrixSize); -matrixB = generateRandomMatrix(matrixSize); -} -std::vector resultParallel(matrixSize * matrixSize, 0.0); -std::vector resultSeq(matrixSize * matrixSize, 0.0); - -std::shared_ptr taskDataSeq = std::make_shared(); - -if (world.rank() == 0) { -taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); -taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); -taskDataSeq->inputs_count.emplace_back(matrixA.size()); -taskDataSeq->inputs_count.emplace_back(matrixB.size()); -taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); -taskDataSeq->outputs_count.emplace_back(resultSeq.size()); - -nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); -ASSERT_TRUE(testMpiTaskSeq.validation()); -ASSERT_TRUE(testMpiTaskSeq.pre_processing()); -ASSERT_TRUE(testMpiTaskSeq.run()); -ASSERT_TRUE(testMpiTaskSeq.post_processing()); -} + boost::mpi::communicator world; -std::shared_ptr taskDataParallel = std::make_shared(); + int matrixSize = 8; + std::vector matrixA; + std::vector matrixB; + if (world.rank() == 0) { + matrixA = generateRandomMatrix(matrixSize); + matrixB = generateRandomMatrix(matrixSize); + std::cout << "Test: MatrixA size = " << matrixSize << ", MatrixB size = " << matrixSize << std::endl; + } + std::vector resultParallel(matrixSize * matrixSize, 0.0); + std::vector resultSeq(matrixSize * matrixSize, 0.0); -if (world.rank() == 0) { -taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); -taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); -taskDataParallel->inputs_count.emplace_back(matrixA.size()); -taskDataParallel->inputs_count.emplace_back(matrixB.size()); -taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); -taskDataParallel->outputs_count.emplace_back(resultParallel.size()); -} -nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); -ASSERT_TRUE(testMpiTaskParallel.validation()); -ASSERT_TRUE(testMpiTaskParallel.pre_processing()); -ASSERT_TRUE(testMpiTaskParallel.run()); -ASSERT_TRUE(testMpiTaskParallel.post_processing()); -ASSERT_EQ(resultSeq, resultParallel); + std::shared_ptr taskDataSeq = std::make_shared(); + + if (world.rank() == 0) { + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] + << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); + ASSERT_TRUE(testMpiTaskSeq.validation()); + ASSERT_TRUE(testMpiTaskSeq.pre_processing()); + ASSERT_TRUE(testMpiTaskSeq.run()); + ASSERT_TRUE(testMpiTaskSeq.post_processing()); + std::cout << "Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; + } + + std::shared_ptr taskDataParallel = std::make_shared(); + + if (world.rank() == 0) { + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataParallel->inputs_count.emplace_back(matrixA.size()); + taskDataParallel->inputs_count.emplace_back(matrixB.size()); + taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); + taskDataParallel->outputs_count.emplace_back(resultParallel.size()); + + std::cout << "Test: TaskData inputs_count[0] = " << taskDataParallel->inputs_count[0] + << ", inputs_count[1] = " << taskDataParallel->inputs_count[1] << std::endl; + } + nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); + ASSERT_TRUE(testMpiTaskParallel.validation()); + ASSERT_TRUE(testMpiTaskParallel.pre_processing()); + ASSERT_TRUE(testMpiTaskParallel.run()); + ASSERT_TRUE(testMpiTaskParallel.post_processing()); + std::cout << "Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; + + ASSERT_EQ(resultSeq, resultParallel); } TEST(nasedkin_e_strassen_algorithm_mpi, Test_16x16) { -boost::mpi::communicator world; - -int matrixSize = 16; -std::vector matrixA; -std::vector matrixB; -if (world.rank() == 0) { -matrixA = generateRandomMatrix(matrixSize); -matrixB = generateRandomMatrix(matrixSize); -} -std::vector resultParallel(matrixSize * matrixSize, 0.0); -std::vector resultSeq(matrixSize * matrixSize, 0.0); - -std::shared_ptr taskDataSeq = std::make_shared(); - -if (world.rank() == 0) { -taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); -taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); -taskDataSeq->inputs_count.emplace_back(matrixA.size()); -taskDataSeq->inputs_count.emplace_back(matrixB.size()); -taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); -taskDataSeq->outputs_count.emplace_back(resultSeq.size()); - -nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); -ASSERT_TRUE(testMpiTaskSeq.validation()); -ASSERT_TRUE(testMpiTaskSeq.pre_processing()); -ASSERT_TRUE(testMpiTaskSeq.run()); -ASSERT_TRUE(testMpiTaskSeq.post_processing()); -} + boost::mpi::communicator world; + + int matrixSize = 16; + std::vector matrixA; + std::vector matrixB; + if (world.rank() == 0) { + matrixA = generateRandomMatrix(matrixSize); + matrixB = generateRandomMatrix(matrixSize); + std::cout << "Test: MatrixA size = " << matrixSize << ", MatrixB size = " << matrixSize << std::endl; + } + std::vector resultParallel(matrixSize * matrixSize, 0.0); + std::vector resultSeq(matrixSize * matrixSize, 0.0); -std::shared_ptr taskDataParallel = std::make_shared(); + std::shared_ptr taskDataSeq = std::make_shared(); -if (world.rank() == 0) { -taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); -taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); -taskDataParallel->inputs_count.emplace_back(matrixA.size()); -taskDataParallel->inputs_count.emplace_back(matrixB.size()); -taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); -taskDataParallel->outputs_count.emplace_back(resultParallel.size()); -} -nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); -ASSERT_TRUE(testMpiTaskParallel.validation()); -ASSERT_TRUE(testMpiTaskParallel.pre_processing()); -ASSERT_TRUE(testMpiTaskParallel.run()); -ASSERT_TRUE(testMpiTaskParallel.post_processing()); -ASSERT_EQ(resultSeq, resultParallel); + if (world.rank() == 0) { + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] + << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); + ASSERT_TRUE(testMpiTaskSeq.validation()); + ASSERT_TRUE(testMpiTaskSeq.pre_processing()); + ASSERT_TRUE(testMpiTaskSeq.run()); + ASSERT_TRUE(testMpiTaskSeq.post_processing()); + std::cout << "Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; + } + + std::shared_ptr taskDataParallel = std::make_shared(); + + if (world.rank() == 0) { + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataParallel->inputs_count.emplace_back(matrixA.size()); + taskDataParallel->inputs_count.emplace_back(matrixB.size()); + taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); + taskDataParallel->outputs_count.emplace_back(resultParallel.size()); + + std::cout << "Test: TaskData inputs_count[0] = " << taskDataParallel->inputs_count[0] + << ", inputs_count[1] = " << taskDataParallel->inputs_count[1] << std::endl; + } + nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); + ASSERT_TRUE(testMpiTaskParallel.validation()); + ASSERT_TRUE(testMpiTaskParallel.pre_processing()); + ASSERT_TRUE(testMpiTaskParallel.run()); + ASSERT_TRUE(testMpiTaskParallel.post_processing()); + std::cout << "Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; + + ASSERT_EQ(resultSeq, resultParallel); } TEST(nasedkin_e_strassen_algorithm_mpi, Test_32x32) { -boost::mpi::communicator world; - -int matrixSize = 32; -std::vector matrixA; -std::vector matrixB; -if (world.rank() == 0) { -matrixA = generateRandomMatrix(matrixSize); -matrixB = generateRandomMatrix(matrixSize); -} -std::vector resultParallel(matrixSize * matrixSize, 0.0); -std::vector resultSeq(matrixSize * matrixSize, 0.0); - -std::shared_ptr taskDataSeq = std::make_shared(); - -if (world.rank() == 0) { -taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); -taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); -taskDataSeq->inputs_count.emplace_back(matrixA.size()); -taskDataSeq->inputs_count.emplace_back(matrixB.size()); -taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); -taskDataSeq->outputs_count.emplace_back(resultSeq.size()); - -nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); -ASSERT_TRUE(testMpiTaskSeq.validation()); -ASSERT_TRUE(testMpiTaskSeq.pre_processing()); -ASSERT_TRUE(testMpiTaskSeq.run()); -ASSERT_TRUE(testMpiTaskSeq.post_processing()); -} + boost::mpi::communicator world; + + int matrixSize = 32; + std::vector matrixA; + std::vector matrixB; + if (world.rank() == 0) { + matrixA = generateRandomMatrix(matrixSize); + matrixB = generateRandomMatrix(matrixSize); + std::cout << "Test: MatrixA size = " << matrixSize << ", MatrixB size = " << matrixSize << std::endl; + } + std::vector resultParallel(matrixSize * matrixSize, 0.0); + std::vector resultSeq(matrixSize * matrixSize, 0.0); -std::shared_ptr taskDataParallel = std::make_shared(); + std::shared_ptr taskDataSeq = std::make_shared(); -if (world.rank() == 0) { -taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); -taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); -taskDataParallel->inputs_count.emplace_back(matrixA.size()); -taskDataParallel->inputs_count.emplace_back(matrixB.size()); -taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); -taskDataParallel->outputs_count.emplace_back(resultParallel.size()); -} -nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); -ASSERT_TRUE(testMpiTaskParallel.validation()); -ASSERT_TRUE(testMpiTaskParallel.pre_processing()); -ASSERT_TRUE(testMpiTaskParallel.run()); -ASSERT_TRUE(testMpiTaskParallel.post_processing()); -ASSERT_EQ(resultSeq, resultParallel); + if (world.rank() == 0) { + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] + << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); + ASSERT_TRUE(testMpiTaskSeq.validation()); + ASSERT_TRUE(testMpiTaskSeq.pre_processing()); + ASSERT_TRUE(testMpiTaskSeq.run()); + ASSERT_TRUE(testMpiTaskSeq.post_processing()); + std::cout << "Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; + } + + std::shared_ptr taskDataParallel = std::make_shared(); + + if (world.rank() == 0) { + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataParallel->inputs_count.emplace_back(matrixA.size()); + taskDataParallel->inputs_count.emplace_back(matrixB.size()); + taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); + taskDataParallel->outputs_count.emplace_back(resultParallel.size()); + + std::cout << "Test: TaskData inputs_count[0] = " << taskDataParallel->inputs_count[0] + << ", inputs_count[1] = " << taskDataParallel->inputs_count[1] << std::endl; + } + nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); + ASSERT_TRUE(testMpiTaskParallel.validation()); + ASSERT_TRUE(testMpiTaskParallel.pre_processing()); + ASSERT_TRUE(testMpiTaskParallel.run()); + ASSERT_TRUE(testMpiTaskParallel.post_processing()); + std::cout << "Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; + + ASSERT_EQ(resultSeq, resultParallel); } \ No newline at end of file diff --git a/tasks/mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp b/tasks/mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp index 8362082f385..0ac0fcb864b 100644 --- a/tasks/mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp +++ b/tasks/mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp @@ -1,55 +1,59 @@ #pragma once -#include +#include +#include #include #include -#include #include -#include +#include + #include "core/task/include/task.hpp" namespace nasedkin_e_strassen_algorithm { - class StrassenAlgorithmSEQ : public ppc::core::Task { - public: - explicit StrassenAlgorithmSEQ(std::shared_ptr taskData_) : Task(std::move(taskData_)) {} - - bool pre_processing() override; - bool validation() override; - bool run() override; - bool post_processing() override; - - private: - static std::vector strassen_multiply_seq(const std::vector& matrixA, const std::vector& matrixB, size_t size); - - std::vector inputMatrixA; - std::vector inputMatrixB; - std::vector outputMatrix; - size_t matrixSize; - }; - - class StrassenAlgorithmMPI : public ppc::core::Task { - public: - explicit StrassenAlgorithmMPI(std::shared_ptr taskData_) : Task(std::move(taskData_)) {} - - bool pre_processing() override; - bool validation() override; - bool run() override; - bool post_processing() override; - - private: - static std::vector strassen_multiply(const std::vector& matrixA, const std::vector& matrixB, size_t size); - - boost::mpi::communicator world; - - std::vector inputMatrixA; - std::vector inputMatrixB; - std::vector outputMatrix; - size_t matrixSize; - }; - - std::vector strassen_recursive(const std::vector& matrixA, - const std::vector& matrixB, size_t size); - std::vector matrix_add(const std::vector& matrixA, const std::vector& matrixB, size_t size); - std::vector matrix_subtract(const std::vector& matrixA, const std::vector& matrixB, size_t size); +class StrassenAlgorithmSEQ : public ppc::core::Task { + public: + explicit StrassenAlgorithmSEQ(std::shared_ptr taskData_) : Task(std::move(taskData_)) {} + + bool pre_processing() override; + bool validation() override; + bool run() override; + bool post_processing() override; + + private: + static std::vector strassen_multiply_seq(const std::vector& matrixA, + const std::vector& matrixB, size_t size); + + std::vector inputMatrixA; + std::vector inputMatrixB; + std::vector outputMatrix; + size_t matrixSize; +}; + +class StrassenAlgorithmMPI : public ppc::core::Task { + public: + explicit StrassenAlgorithmMPI(std::shared_ptr taskData_) : Task(std::move(taskData_)) {} + + bool pre_processing() override; + bool validation() override; + bool run() override; + bool post_processing() override; + + private: + static std::vector strassen_multiply(const std::vector& matrixA, const std::vector& matrixB, + size_t size); + + boost::mpi::communicator world; + + std::vector inputMatrixA; + std::vector inputMatrixB; + std::vector outputMatrix; + size_t matrixSize; +}; + +std::vector strassen_recursive(const std::vector& matrixA, const std::vector& matrixB, + size_t size); +std::vector matrix_add(const std::vector& matrixA, const std::vector& matrixB, size_t size); +std::vector matrix_subtract(const std::vector& matrixA, const std::vector& matrixB, + size_t size); } // namespace nasedkin_e_strassen_algorithm \ No newline at end of file diff --git a/tasks/mpi/nasedkin_e_strassen_algorithm/perf_tests/main.cpp b/tasks/mpi/nasedkin_e_strassen_algorithm/perf_tests/main.cpp index 1e40abdc35c..d6d435caca9 100644 --- a/tasks/mpi/nasedkin_e_strassen_algorithm/perf_tests/main.cpp +++ b/tasks/mpi/nasedkin_e_strassen_algorithm/perf_tests/main.cpp @@ -1,8 +1,9 @@ #include #include -#include #include +#include + #include "core/perf/include/perf.hpp" #include "mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp" diff --git a/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp b/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp index 5956e07261a..a5e03228c63 100644 --- a/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp +++ b/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp @@ -1,404 +1,501 @@ -#include +#include "mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp" + +#include +#include +#include +#include #include #include -#include -#include #include -#include -#include -#include -#include "mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp" +#include +#include namespace nasedkin_e_strassen_algorithm { - bool StrassenAlgorithmSEQ::pre_processing() { - internal_order_test(); - auto* inputsA = reinterpret_cast(taskData->inputs[0]); - auto* inputsB = reinterpret_cast(taskData->inputs[1]); - matrixSize = static_cast(std::sqrt(taskData->inputs_count[0])); - inputMatrixA.assign(inputsA, inputsA + matrixSize * matrixSize); - inputMatrixB.assign(inputsB, inputsB + matrixSize * matrixSize); - outputMatrix.resize(matrixSize * matrixSize, 0.0); - return true; - } +bool StrassenAlgorithmSEQ::pre_processing() { + internal_order_test(); + std::cout << "Pre-processing: Loading inputs..." << std::endl; + auto* inputsA = reinterpret_cast(taskData->inputs[0]); + auto* inputsB = reinterpret_cast(taskData->inputs[1]); - bool StrassenAlgorithmSEQ::validation() { - internal_order_test(); - if (taskData->inputs.empty()) { - return false; - } - if (taskData->inputs_count[0] != taskData->inputs_count[1]) { - return false; - } - if (taskData->inputs_count[0] != taskData->outputs_count[0]) { - return false; - } - return true; - } + if (inputsA == nullptr || inputsB == nullptr) { + std::cout << "Pre-processing failed: Input pointers are null." << std::endl; + return false; + } - bool StrassenAlgorithmSEQ::run() { - internal_order_test(); - outputMatrix = strassen_multiply_seq(inputMatrixA, inputMatrixB, matrixSize); - return true; - } + std::cout << "Pre-processing: inputs_count[0] = " << taskData->inputs_count[0] << std::endl; + std::cout << "Pre-processing: inputs_count[1] = " << taskData->inputs_count[1] << std::endl; - bool StrassenAlgorithmSEQ::post_processing() { - internal_order_test(); - auto* outputs = reinterpret_cast(taskData->outputs[0]); - std::copy(outputMatrix.begin(), outputMatrix.end(), outputs); - return true; - } + matrixSize = static_cast(std::sqrt(taskData->inputs_count[0])); + + std::cout << "Pre-processing: Matrix size = " << matrixSize << std::endl; + + if (matrixSize * matrixSize != taskData->inputs_count[0]) { + std::cout << "Pre-processing failed: Input size mismatch. Expected: " << matrixSize * matrixSize + << ", got: " << taskData->inputs_count[0] << std::endl; + return false; + } + + inputMatrixA.assign(inputsA, inputsA + matrixSize * matrixSize); + inputMatrixB.assign(inputsB, inputsB + matrixSize * matrixSize); + outputMatrix.resize(matrixSize * matrixSize, 0.0); + + std::cout << "Pre-processing: Input matrices loaded successfully." << std::endl; + return true; +} + +bool StrassenAlgorithmSEQ::validation() { + internal_order_test(); + std::cout << "Validation: Checking inputs..." << std::endl; + if (taskData->inputs.empty()) { + std::cout << "Validation failed: Inputs are empty." << std::endl; + return false; + } + if (taskData->inputs_count[0] != taskData->inputs_count[1]) { + std::cout << "Validation failed: Input sizes do not match." << std::endl; + return false; + } + std::cout << "Validation passed." << std::endl; + + return true; +} + +bool StrassenAlgorithmSEQ::run() { + internal_order_test(); + std::cout << "Starting Strassen_multiply with matrixSize = " << matrixSize << std::endl; + outputMatrix = strassen_multiply_seq(inputMatrixA, inputMatrixB, matrixSize); + return true; +} + +bool StrassenAlgorithmSEQ::post_processing() { + internal_order_test(); + std::cout << "Post-processing: Saving output..." << std::endl; + auto* outputs = reinterpret_cast(taskData->outputs[0]); + std::copy(outputMatrix.begin(), outputMatrix.end(), outputs); + std::cout << "Post-processing: Output saved successfully." << std::endl; + return true; +} bool StrassenAlgorithmMPI::pre_processing() { internal_order_test(); int rank = world.rank(); if (rank == 0) { + std::cout << "Pre-processing: Loading inputs..." << std::endl; auto* inputsA = reinterpret_cast(taskData->inputs[0]); auto* inputsB = reinterpret_cast(taskData->inputs[1]); if (inputsA == nullptr || inputsB == nullptr) { + std::cout << "Pre-processing failed: Input pointers are null." << std::endl; return false; } + if (rank == 0) { + std::cout << "Pre-processing: inputs_count[0] = " << taskData->inputs_count[0] << std::endl; + std::cout << "Pre-processing: inputs_count[1] = " << taskData->inputs_count[1] << std::endl; + } + matrixSize = static_cast(std::sqrt(taskData->inputs_count[0])); + std::cout << "Pre-processing: Matrix size = " << matrixSize << std::endl; + if (matrixSize * matrixSize != taskData->inputs_count[0]) { + std::cout << "Pre-processing failed: Input size mismatch. Expected: " << matrixSize * matrixSize + << ", got: " << taskData->inputs_count[0] << std::endl; return false; } inputMatrixA.assign(inputsA, inputsA + matrixSize * matrixSize); inputMatrixB.assign(inputsB, inputsB + matrixSize * matrixSize); outputMatrix.resize(matrixSize * matrixSize, 0.0); + + std::cout << "Pre-processing: Input matrices loaded successfully." << std::endl; } return true; } - bool StrassenAlgorithmMPI::validation() { - internal_order_test(); - int rank = world.rank(); - if (rank == 0) { - if (taskData->inputs.empty()) { - return false; - } - if (taskData->inputs_count[0] != taskData->inputs_count[1]) { - return false; - } - if (taskData->inputs_count[0] != taskData->outputs_count[0]) { - return false; - } - } - return true; +bool StrassenAlgorithmMPI::validation() { + internal_order_test(); + int rank = world.rank(); + if (rank == 0) { + std::cout << "Validation: Checking inputs..." << std::endl; + if (taskData->inputs.empty()) { + std::cout << "Validation failed: Inputs are empty." << std::endl; + return false; } - - bool StrassenAlgorithmMPI::run() { - internal_order_test(); - boost::mpi::broadcast(world, inputMatrixA, 0); - boost::mpi::broadcast(world, inputMatrixB, 0); - boost::mpi::broadcast(world, matrixSize, 0); - outputMatrix = strassen_multiply(inputMatrixA, inputMatrixB, matrixSize); - return true; + if (taskData->inputs_count[0] != taskData->inputs_count[1]) { + std::cout << "Validation failed: Input sizes do not match." << std::endl; + return false; } + std::cout << "Validation passed." << std::endl; + } + return true; +} - bool StrassenAlgorithmMPI::post_processing() { - internal_order_test(); - int rank = world.rank(); - if (rank == 0) { - auto* outputs = reinterpret_cast(taskData->outputs[0]); - std::copy(outputMatrix.begin(), outputMatrix.end(), outputs); - } - return true; +bool StrassenAlgorithmMPI::run() { + internal_order_test(); + + boost::mpi::broadcast(world, inputMatrixA, 0); + boost::mpi::broadcast(world, inputMatrixB, 0); + boost::mpi::broadcast(world, matrixSize, 0); + + std::cout << "Rank " << world.rank() << ": Starting Strassen_multiply with matrixSize = " << matrixSize << std::endl; + outputMatrix = strassen_multiply(inputMatrixA, inputMatrixB, matrixSize); + return true; +} + +bool StrassenAlgorithmMPI::post_processing() { + internal_order_test(); + int rank = world.rank(); + if (rank == 0) { + std::cout << "Post-processing: Saving output..." << std::endl; + auto* outputs = reinterpret_cast(taskData->outputs[0]); + std::copy(outputMatrix.begin(), outputMatrix.end(), outputs); + std::cout << "Post-processing: Output saved successfully." << std::endl; + } + return true; +} + +std::vector matrix_add(const std::vector& matrixA, const std::vector& matrixB, size_t size) { + std::vector result(size * size); + for (size_t i = 0; i < size * size; ++i) { + result[i] = matrixA[i] + matrixB[i]; + } + return result; +} + +std::vector matrix_subtract(const std::vector& matrixA, const std::vector& matrixB, + size_t size) { + std::vector result(size * size); + for (size_t i = 0; i < size * size; ++i) { + result[i] = matrixA[i] - matrixB[i]; + } + return result; +} + +std::vector strassen_recursive(const std::vector& matrixA, const std::vector& matrixB, + size_t size) { + if (size == 1) { + return {matrixA[0] * matrixB[0]}; + } + + size_t half_size = size / 2; + + std::vector A11(half_size * half_size); + std::vector A12(half_size * half_size); + std::vector A21(half_size * half_size); + std::vector A22(half_size * half_size); + + std::vector B11(half_size * half_size); + std::vector B12(half_size * half_size); + std::vector B21(half_size * half_size); + std::vector B22(half_size * half_size); + + if (matrixA.size() != size * size || matrixB.size() != size * size) { + std::cout << "strassen_recursive: Matrix size mismatch. Expected: " << size * size << ", got: " << matrixA.size() + << " and " << matrixB.size() << std::endl; + return {}; + } + + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + A11[i * half_size + j] = matrixA[i * size + j]; + A12[i * half_size + j] = matrixA[i * size + j + half_size]; + A21[i * half_size + j] = matrixA[(i + half_size) * size + j]; + A22[i * half_size + j] = matrixA[(i + half_size) * size + j + half_size]; + + B11[i * half_size + j] = matrixB[i * size + j]; + B12[i * half_size + j] = matrixB[i * size + j + half_size]; + B21[i * half_size + j] = matrixB[(i + half_size) * size + j]; + B22[i * half_size + j] = matrixB[(i + half_size) * size + j + half_size]; } + } - std::vector matrix_add(const std::vector& matrixA, - const std::vector& matrixB, - size_t size) { - std::vector result(size * size); - for (size_t i = 0; i < size * size; ++i) { - result[i] = matrixA[i] + matrixB[i]; - } - return result; + std::vector M1 = + strassen_recursive(matrix_add(A11, A22, half_size), matrix_add(B11, B22, half_size), half_size); + std::vector M2 = strassen_recursive(matrix_add(A21, A22, half_size), B11, half_size); + std::vector M3 = strassen_recursive(A11, matrix_subtract(B12, B22, half_size), half_size); + std::vector M4 = strassen_recursive(A22, matrix_subtract(B21, B11, half_size), half_size); + std::vector M5 = strassen_recursive(matrix_add(A11, A12, half_size), B22, half_size); + std::vector M6 = + strassen_recursive(matrix_subtract(A21, A11, half_size), matrix_add(B11, B12, half_size), half_size); + std::vector M7 = + strassen_recursive(matrix_subtract(A12, A22, half_size), matrix_add(B21, B22, half_size), half_size); + + std::vector C11 = matrix_add(matrix_subtract(matrix_add(M1, M4, half_size), M5, half_size), M7, half_size); + std::vector C12 = matrix_add(M3, M5, half_size); + std::vector C21 = matrix_add(M2, M4, half_size); + std::vector C22 = matrix_add(matrix_subtract(matrix_add(M1, M3, half_size), M2, half_size), M6, half_size); + + std::vector local_result(size * size); + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + local_result[i * size + j] = C11[i * half_size + j]; + local_result[i * size + j + half_size] = C12[i * half_size + j]; + local_result[(i + half_size) * size + j] = C21[i * half_size + j]; + local_result[(i + half_size) * size + j + half_size] = C22[i * half_size + j]; } + } - std::vector matrix_subtract(const std::vector& matrixA, - const std::vector& matrixB, - size_t size) { - std::vector result(size * size); - for (size_t i = 0; i < size * size; ++i) { - result[i] = matrixA[i] - matrixB[i]; - } - return result; + return local_result; +} + +std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vector& matrixA, + const std::vector& matrixB, size_t size) { + if (matrixA.empty() || matrixB.empty() || size == 0) { + std::cout << "Error! matrixA, matrixB are empty, or size is zero before Strassen_multiply" << std::endl; + return {}; + } + + std::cout << "Strassen_multiply: Received matrix size = " << size << std::endl; + + if (size == 1) { + std::cout << "Strassen_multiply: Base case reached." << std::endl; + return {matrixA[0] * matrixB[0]}; + } + + size_t new_size = 1; + while (new_size < size) { + new_size *= 2; + } + + size_t half_size = new_size / 2; + + std::vector A11(half_size * half_size); + std::vector A12(half_size * half_size); + std::vector A21(half_size * half_size); + std::vector A22(half_size * half_size); + + std::vector B11(half_size * half_size); + std::vector B12(half_size * half_size); + std::vector B21(half_size * half_size); + std::vector B22(half_size * half_size); + + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + A11[i * half_size + j] = matrixA[i * new_size + j]; + A12[i * half_size + j] = matrixA[i * new_size + j + half_size]; + A21[i * half_size + j] = matrixA[(i + half_size) * new_size + j]; + A22[i * half_size + j] = matrixA[(i + half_size) * new_size + j + half_size]; + + B11[i * half_size + j] = matrixB[i * new_size + j]; + B12[i * half_size + j] = matrixB[i * new_size + j + half_size]; + B21[i * half_size + j] = matrixB[(i + half_size) * new_size + j]; + B22[i * half_size + j] = matrixB[(i + half_size) * new_size + j + half_size]; } + } + + std::cout << "Strassen_multiply: Divided matrices into submatrices." << std::endl; + + std::cout << "A11 size = " << A11.size() << ", A12 size = " << A12.size() << ", A21 size = " << A21.size() + << ", A22 size = " << A22.size() << std::endl; + std::cout << "B11 size = " << B11.size() << ", B12 size = " << B12.size() << ", B21 size = " << B21.size() + << ", B22 size = " << B22.size() << std::endl; + + std::vector> M(7); + std::vector> tasks = {matrix_add(A11, A22, half_size), + matrix_add(A21, A22, half_size), + A11, + A22, + matrix_add(A11, A12, half_size), + matrix_subtract(A21, A11, half_size), + matrix_subtract(A12, A22, half_size)}; + + std::vector> tasksB = { + matrix_add(B11, B22, half_size), B11, matrix_subtract(B12, B22, half_size), + matrix_subtract(B21, B11, half_size), B22, matrix_add(B11, B12, half_size), + matrix_add(B21, B22, half_size)}; + std::cout << "Tasks created successfully" << std::endl; + + for (int i = 0; i < 7; ++i) { + M[i] = strassen_recursive(tasks[i], tasksB[i], half_size); + } + + for (int i = 0; i < 7; ++i) { + std::vector result; + M[i] = result; + } + + std::cout << "Final results collected. Verifying matrix sizes:" << std::endl; + for (int i = 0; i < 7; ++i) { + std::cout << "M[" << i << "] size = " << M[i].size() << std::endl; + } - std::vector strassen_recursive(const std::vector& matrixA, - const std::vector& matrixB, size_t size) { - if (size == 1) { - return {matrixA[0] * matrixB[0]}; - } - - size_t half_size = size / 2; - - std::vector A11(half_size * half_size); - std::vector A12(half_size * half_size); - std::vector A21(half_size * half_size); - std::vector A22(half_size * half_size); - - std::vector B11(half_size * half_size); - std::vector B12(half_size * half_size); - std::vector B21(half_size * half_size); - std::vector B22(half_size * half_size); - - for (size_t i = 0; i < half_size; ++i) { - for (size_t j = 0; j < half_size; ++j) { - A11[i * half_size + j] = matrixA[i * size + j]; - A12[i * half_size + j] = matrixA[i * size + j + half_size]; - A21[i * half_size + j] = matrixA[(i + half_size) * size + j]; - A22[i * half_size + j] = matrixA[(i + half_size) * size + j + half_size]; - - B11[i * half_size + j] = matrixB[i * size + j]; - B12[i * half_size + j] = matrixB[i * size + j + half_size]; - B21[i * half_size + j] = matrixB[(i + half_size) * size + j]; - B22[i * half_size + j] = matrixB[(i + half_size) * size + j + half_size]; - } - } - - std::vector M1 = strassen_recursive(matrix_add(A11, A22, half_size), - matrix_add(B11, B22, half_size), half_size); - std::vector M2 = strassen_recursive(matrix_add(A21, A22, half_size), B11, half_size); - std::vector M3 = strassen_recursive(A11, matrix_subtract(B12, B22, half_size), half_size); - std::vector M4 = strassen_recursive(A22, matrix_subtract(B21, B11, half_size), half_size); - std::vector M5 = strassen_recursive(matrix_add(A11, A12, half_size), B22, half_size); - std::vector M6 = strassen_recursive(matrix_subtract(A21, A11, half_size), - matrix_add(B11, B12, half_size), half_size); - std::vector M7 = strassen_recursive(matrix_subtract(A12, A22, half_size), - matrix_add(B21, B22, half_size), half_size); - - std::vector C11 = matrix_add(matrix_subtract(matrix_add(M1, M4, half_size), M5, half_size), M7, half_size); - std::vector C12 = matrix_add(M3, M5, half_size); - std::vector C21 = matrix_add(M2, M4, half_size); - std::vector C22 = matrix_add(matrix_subtract(matrix_add(M1, M3, half_size), M2, half_size), M6, half_size); - - std::vector local_result(size * size); - for (size_t i = 0; i < half_size; ++i) { - for (size_t j = 0; j < half_size; ++j) { - local_result[i * size + j] = C11[i * half_size + j]; - local_result[i * size + j + half_size] = C12[i * half_size + j]; - local_result[(i + half_size) * size + j] = C21[i * half_size + j]; - local_result[(i + half_size) * size + j + half_size] = C22[i * half_size + j]; - } - } - - return local_result; + std::vector C11 = + matrix_add(matrix_subtract(matrix_add(M[0], M[3], half_size), M[4], half_size), M[6], half_size); + std::vector C12 = matrix_add(M[2], M[4], half_size); + std::vector C21 = matrix_add(M[1], M[3], half_size); + std::vector C22 = + matrix_add(matrix_subtract(matrix_add(M[0], M[2], half_size), M[1], half_size), M[5], half_size); + + std::cout << "All С calculated" << std::endl; + + std::vector result(size * size); + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + result[i * size + j] = C11[i * half_size + j]; + result[i * size + j + half_size] = C12[i * half_size + j]; + result[(i + half_size) * size + j] = C21[i * half_size + j]; + result[(i + half_size) * size + j + half_size] = C22[i * half_size + j]; } + } + std::cout << "Final result calculated" << std::endl; + return result; + return {}; +} - std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vector& matrixA, - const std::vector& matrixB, size_t size) { - if (size == 1) { - return {matrixA[0] * matrixB[0]}; - } - - size_t new_size = 1; - while (new_size < size) { - new_size *= 2; - } - - size_t half_size = new_size / 2; - - std::vector A11(half_size * half_size); - std::vector A12(half_size * half_size); - std::vector A21(half_size * half_size); - std::vector A22(half_size * half_size); - - std::vector B11(half_size * half_size); - std::vector B12(half_size * half_size); - std::vector B21(half_size * half_size); - std::vector B22(half_size * half_size); - - for (size_t i = 0; i < half_size; ++i) { - for (size_t j = 0; j < half_size; ++j) { - A11[i * half_size + j] = matrixA[i * new_size + j]; - A12[i * half_size + j] = matrixA[i * new_size + j + half_size]; - A21[i * half_size + j] = matrixA[(i + half_size) * new_size + j]; - A22[i * half_size + j] = matrixA[(i + half_size) * new_size + j + half_size]; - - B11[i * half_size + j] = matrixB[i * new_size + j]; - B12[i * half_size + j] = matrixB[i * new_size + j + half_size]; - B21[i * half_size + j] = matrixB[(i + half_size) * new_size + j]; - B22[i * half_size + j] = matrixB[(i + half_size) * new_size + j + half_size]; - } - } - - std::vector> M(7); - std::vector> tasks = { - matrix_add(A11, A22, half_size), - matrix_add(A21, A22, half_size), - A11, - A22, - matrix_add(A11, A12, half_size), - matrix_subtract(A21, A11, half_size), - matrix_subtract(A12, A22, half_size) - }; - - std::vector> tasksB = { - matrix_add(B11, B22, half_size), - B11, - matrix_subtract(B12, B22, half_size), - matrix_subtract(B21, B11, half_size), - B22, - matrix_add(B11, B12, half_size), - matrix_add(B21, B22, half_size) - }; - - for (int i = 0; i < 7; ++i) { - M[i] = strassen_recursive(tasks[i], tasksB[i], half_size); - } - - - for (int i = 0; i < 7; ++i) { - std::vector result; - M[i] = result; - } - - std::vector C11 = - matrix_add(matrix_subtract(matrix_add(M[0], M[3], half_size), M[4], half_size), M[6], half_size); - std::vector C12 = matrix_add(M[2], M[4], half_size); - std::vector C21 = matrix_add(M[1], M[3], half_size); - std::vector C22 = - matrix_add(matrix_subtract(matrix_add(M[0], M[2], half_size), M[1], half_size), M[5], half_size); - - std::vector result(size * size); - for (size_t i = 0; i < half_size; ++i) { - for (size_t j = 0; j < half_size; ++j) { - result[i * size + j] = C11[i * half_size + j]; - result[i * size + j + half_size] = C12[i * half_size + j]; - result[(i + half_size) * size + j] = C21[i * half_size + j]; - result[(i + half_size) * size + j + half_size] = C22[i * half_size + j]; - } - } - return result; - return {}; +std::vector StrassenAlgorithmMPI::strassen_multiply(const std::vector& matrixA, + const std::vector& matrixB, size_t size) { + boost::mpi::environment env; + boost::mpi::communicator world; + + int rank = world.rank(); + int num_procs = world.size(); + + std::cout << "Num procs = " << num_procs << std::endl; + + if (rank == 0 && (matrixA.empty() || matrixB.empty() || size == 0)) { + std::cout << "Rank " << rank << ": Error! matrixA, matrixB are empty, or size is zero before Strassen_multiply" + << std::endl; + return {}; + } + if (rank == 0) { + std::cout << "Strassen_multiply: Received matrix size = " << size << ", rank = " << rank << std::endl; + } + + if (size == 1) { + std::cout << "Strassen_multiply: Base case reached." << std::endl; + return {matrixA[0] * matrixB[0]}; + } + + size_t new_size = 1; + while (new_size < size) { + new_size *= 2; + } + + size_t half_size = new_size / 2; + + std::vector A11(half_size * half_size); + std::vector A12(half_size * half_size); + std::vector A21(half_size * half_size); + std::vector A22(half_size * half_size); + + std::vector B11(half_size * half_size); + std::vector B12(half_size * half_size); + std::vector B21(half_size * half_size); + std::vector B22(half_size * half_size); + + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + A11[i * half_size + j] = matrixA[i * new_size + j]; + A12[i * half_size + j] = matrixA[i * new_size + j + half_size]; + A21[i * half_size + j] = matrixA[(i + half_size) * new_size + j]; + A22[i * half_size + j] = matrixA[(i + half_size) * new_size + j + half_size]; + + B11[i * half_size + j] = matrixB[i * new_size + j]; + B12[i * half_size + j] = matrixB[i * new_size + j + half_size]; + B21[i * half_size + j] = matrixB[(i + half_size) * new_size + j]; + B22[i * half_size + j] = matrixB[(i + half_size) * new_size + j + half_size]; } + } - std::vector StrassenAlgorithmMPI::strassen_multiply(const std::vector& matrixA, - const std::vector& matrixB, size_t size) { - boost::mpi::environment env; - boost::mpi::communicator world; + std::cout << "Strassen_multiply: Rank " << rank << " divided matrices into submatrices." << std::endl; - int rank = world.rank(); - int num_procs = world.size(); + std::cout << "A11 size = " << A11.size() << ", A12 size = " << A12.size() << ", A21 size = " << A21.size() + << ", A22 size = " << A22.size() << std::endl; + std::cout << "B11 size = " << B11.size() << ", B12 size = " << B12.size() << ", B21 size = " << B21.size() + << ", B22 size = " << B22.size() << std::endl; - if (size == 1) { - return {matrixA[0] * matrixB[0]}; + std::vector> M(7); + if (rank == 0) { + std::vector> tasks = {matrix_add(A11, A22, half_size), + matrix_add(A21, A22, half_size), + A11, + A22, + matrix_add(A11, A12, half_size), + matrix_subtract(A21, A11, half_size), + matrix_subtract(A12, A22, half_size)}; + + std::vector> tasksB = { + matrix_add(B11, B22, half_size), B11, matrix_subtract(B12, B22, half_size), + matrix_subtract(B21, B11, half_size), B22, matrix_add(B11, B12, half_size), + matrix_add(B21, B22, half_size)}; + std::cout << "Tasks created successfully" << std::endl; + + for (int i = 0; i < 7; ++i) { + if (i % num_procs == 0) { + std::cout << "Rank 0 processing taskA[" << i << "] and taskB[" << i << "] locally." << std::endl; + M[i] = strassen_recursive(tasks[i], tasksB[i], half_size); + } else { + std::cout << "Rank 0 sending taskA[" << i << "] (size = " << tasks[i].size() << ") and taskB[" << i + << "] (size = " << tasksB[i].size() << ") to rank " << (i % num_procs) << std::endl; + world.send(i % num_procs, i, tasks[i]); + world.send(i % num_procs, i, tasksB[i]); + std::cout << "Rank 0 sent taskA[" << i << "] and taskB[" << i << "] to rank " << (i % num_procs) << std::endl; } + } + } - size_t new_size = 1; - while (new_size < size) { - new_size *= 2; - } + for (int i = 0; i < 7; ++i) { + if (i % num_procs == rank && i % num_procs != 0) { + std::vector taskA; + std::vector taskB; + + std::cout << "Rank " << rank << " waiting for taskA and taskB for M[" << i << "]..." << std::endl; + world.recv(0, i, taskA); + world.recv(0, i, taskB); + std::cout << "Rank " << rank << " received taskA size = " << taskA.size() << ", taskB size = " << taskB.size() + << std::endl; + + M[i] = strassen_recursive(taskA, taskB, half_size); - size_t half_size = new_size / 2; - - std::vector A11(half_size * half_size); - std::vector A12(half_size * half_size); - std::vector A21(half_size * half_size); - std::vector A22(half_size * half_size); - - std::vector B11(half_size * half_size); - std::vector B12(half_size * half_size); - std::vector B21(half_size * half_size); - std::vector B22(half_size * half_size); - - for (size_t i = 0; i < half_size; ++i) { - for (size_t j = 0; j < half_size; ++j) { - A11[i * half_size + j] = matrixA[i * new_size + j]; - A12[i * half_size + j] = matrixA[i * new_size + j + half_size]; - A21[i * half_size + j] = matrixA[(i + half_size) * new_size + j]; - A22[i * half_size + j] = matrixA[(i + half_size) * new_size + j + half_size]; - - B11[i * half_size + j] = matrixB[i * new_size + j]; - B12[i * half_size + j] = matrixB[i * new_size + j + half_size]; - B21[i * half_size + j] = matrixB[(i + half_size) * new_size + j]; - B22[i * half_size + j] = matrixB[(i + half_size) * new_size + j + half_size]; - } + world.send(0, i, M[i]); + std::cout << "Rank " << rank << " sent result for M[" << i << "] to rank 0." << std::endl; + } + } + + if (rank == 0) { + for (int i = 0; i < 7; ++i) { + if (i % num_procs == 0) { + std::cout << "Rank 0 already processed result for M[" << i << "] locally." << std::endl; + } else { + std::cout << "Rank 0 waiting to receive result for M[" << i << "] from rank " << (i % num_procs) << "..." + << std::endl; + std::vector result; + world.recv(i % num_procs, i, result); + M[i] = result; + std::cout << "Rank 0 received result for M[" << i << "] from rank " << (i % num_procs) << std::endl; } + } + } + + if (rank == 0) { + std::cout << "Rank 0: Final results collected. Verifying matrix sizes:" << std::endl; + for (int i = 0; i < 7; ++i) { + std::cout << "M[" << i << "] size = " << M[i].size() << std::endl; + } - std::vector> M(7); - if (rank == 0) { - std::vector> tasks = { - matrix_add(A11, A22, half_size), - matrix_add(A21, A22, half_size), - A11, - A22, - matrix_add(A11, A12, half_size), - matrix_subtract(A21, A11, half_size), - matrix_subtract(A12, A22, half_size) - }; - - std::vector> tasksB = { - matrix_add(B11, B22, half_size), - B11, - matrix_subtract(B12, B22, half_size), - matrix_subtract(B21, B11, half_size), - B22, - matrix_add(B11, B12, half_size), - matrix_add(B21, B22, half_size) - }; - - for (int i = 0; i < 7; ++i) { - if (i % num_procs == 0) { - M[i] = strassen_recursive(tasks[i], tasksB[i], half_size); - } else { - world.send(i % num_procs, i, tasks[i]); - world.send(i % num_procs, i, tasksB[i]); - } - } - } - - for (int i = 0; i < 7; ++i) { - if (i % num_procs == rank && i % num_procs != 0) { - std::vector taskA; - std::vector taskB; - - world.recv(0, i, taskA); - world.recv(0, i, taskB); - - M[i] = strassen_recursive(taskA, taskB, half_size); - - world.send(0, i, M[i]); - } - } - - if (rank == 0) { - for (int i = 0; i < 7; ++i) { - if (i % num_procs != 0) { - std::vector result; - world.recv(i % num_procs, i, result); - M[i] = result; - } - } - } - - if (rank == 0) { - - std::vector C11 = - matrix_add(matrix_subtract(matrix_add(M[0], M[3], half_size), M[4], half_size), M[6], half_size); - std::vector C12 = matrix_add(M[2], M[4], half_size); - std::vector C21 = matrix_add(M[1], M[3], half_size); - std::vector C22 = - matrix_add(matrix_subtract(matrix_add(M[0], M[2], half_size), M[1], half_size), M[5], half_size); - - - std::vector result(size * size); - for (size_t i = 0; i < half_size; ++i) { - for (size_t j = 0; j < half_size; ++j) { - result[i * size + j] = C11[i * half_size + j]; - result[i * size + j + half_size] = C12[i * half_size + j]; - result[(i + half_size) * size + j] = C21[i * half_size + j]; - result[(i + half_size) * size + j + half_size] = C22[i * half_size + j]; - } - } - return result; - } - return {}; + std::vector C11 = + matrix_add(matrix_subtract(matrix_add(M[0], M[3], half_size), M[4], half_size), M[6], half_size); + std::vector C12 = matrix_add(M[2], M[4], half_size); + std::vector C21 = matrix_add(M[1], M[3], half_size); + std::vector C22 = + matrix_add(matrix_subtract(matrix_add(M[0], M[2], half_size), M[1], half_size), M[5], half_size); + + std::cout << "Rank 0: all С calculated" << std::endl; + + std::vector result(size * size); + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + result[i * size + j] = C11[i * half_size + j]; + result[i * size + j + half_size] = C12[i * half_size + j]; + result[(i + half_size) * size + j] = C21[i * half_size + j]; + result[(i + half_size) * size + j + half_size] = C22[i * half_size + j]; + } } + std::cout << "Rank 0: final result calculated" << std::endl; + return result; + } + return {}; +} } // namespace nasedkin_e_strassen_algorithm \ No newline at end of file diff --git a/tasks/seq/nasedkin_e_strassen_algorithm/func_tests/main.cpp b/tasks/seq/nasedkin_e_strassen_algorithm/func_tests/main.cpp new file mode 100644 index 00000000000..c03269b0d18 --- /dev/null +++ b/tasks/seq/nasedkin_e_strassen_algorithm/func_tests/main.cpp @@ -0,0 +1,153 @@ +#include + +#include +#include + +#include "seq/nasedkin_e_strassen_algorithm/include/ops_seq.hpp" + +std::vector generateRandomMatrix(int size) { + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_real_distribution<> dis(-100.0, 100.0); + std::vector matrix(size * size); + + if (size <= 0) { + std::cout << "generateRandomMatrix: Invalid size: " << size << std::endl; + return matrix; + } + + for (int i = 0; i < size * size; i++) { + matrix[i] = dis(gen); + } + return matrix; +} + +TEST(nasedkin_e_strassen_algorithm_seq, Test_2x2) { + int matrixSize = 2; + std::vector matrixA = generateRandomMatrix(matrixSize); + std::vector matrixB = generateRandomMatrix(matrixSize); + std::vector resultSeq(matrixSize * matrixSize, 0.0); + + std::shared_ptr taskDataSeq = std::make_shared(); + + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] + << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testSeqTask(taskDataSeq); + ASSERT_TRUE(testSeqTask.validation()); + ASSERT_TRUE(testSeqTask.pre_processing()); + ASSERT_TRUE(testSeqTask.run()); + ASSERT_TRUE(testSeqTask.post_processing()); + std::cout << "SEQ Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; +} + +TEST(nasedkin_e_strassen_algorithm_seq, Test_4x4) { + int matrixSize = 4; + std::vector matrixA = generateRandomMatrix(matrixSize); + std::vector matrixB = generateRandomMatrix(matrixSize); + std::vector resultSeq(matrixSize * matrixSize, 0.0); + + std::shared_ptr taskDataSeq = std::make_shared(); + + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] + << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testSeqTask(taskDataSeq); + ASSERT_TRUE(testSeqTask.validation()); + ASSERT_TRUE(testSeqTask.pre_processing()); + ASSERT_TRUE(testSeqTask.run()); + ASSERT_TRUE(testSeqTask.post_processing()); + std::cout << "SEQ Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; +} + +TEST(nasedkin_e_strassen_algorithm_seq, Test_8x8) { + int matrixSize = 8; + std::vector matrixA = generateRandomMatrix(matrixSize); + std::vector matrixB = generateRandomMatrix(matrixSize); + std::vector resultSeq(matrixSize * matrixSize, 0.0); + + std::shared_ptr taskDataSeq = std::make_shared(); + + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] + << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testSeqTask(taskDataSeq); + ASSERT_TRUE(testSeqTask.validation()); + ASSERT_TRUE(testSeqTask.pre_processing()); + ASSERT_TRUE(testSeqTask.run()); + ASSERT_TRUE(testSeqTask.post_processing()); + std::cout << "SEQ Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; +} + +TEST(nasedkin_e_strassen_algorithm_seq, Test_16x16) { + int matrixSize = 16; + std::vector matrixA = generateRandomMatrix(matrixSize); + std::vector matrixB = generateRandomMatrix(matrixSize); + std::vector resultSeq(matrixSize * matrixSize, 0.0); + + std::shared_ptr taskDataSeq = std::make_shared(); + + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] + << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testSeqTask(taskDataSeq); + ASSERT_TRUE(testSeqTask.validation()); + ASSERT_TRUE(testSeqTask.pre_processing()); + ASSERT_TRUE(testSeqTask.run()); + ASSERT_TRUE(testSeqTask.post_processing()); + std::cout << "SEQ Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; +} + +TEST(nasedkin_e_strassen_algorithm_seq, Test_32x32) { + int matrixSize = 32; + std::vector matrixA = generateRandomMatrix(matrixSize); + std::vector matrixB = generateRandomMatrix(matrixSize); + std::vector resultSeq(matrixSize * matrixSize, 0.0); + + std::shared_ptr taskDataSeq = std::make_shared(); + + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] + << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testSeqTask(taskDataSeq); + ASSERT_TRUE(testSeqTask.validation()); + ASSERT_TRUE(testSeqTask.pre_processing()); + ASSERT_TRUE(testSeqTask.run()); + ASSERT_TRUE(testSeqTask.post_processing()); + std::cout << "SEQ Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; +} \ No newline at end of file diff --git a/tasks/seq/nasedkin_e_strassen_algorithm/include/ops_seq.hpp b/tasks/seq/nasedkin_e_strassen_algorithm/include/ops_seq.hpp new file mode 100644 index 00000000000..128ecfbdb6a --- /dev/null +++ b/tasks/seq/nasedkin_e_strassen_algorithm/include/ops_seq.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "core/task/include/task.hpp" + +namespace nasedkin_e_strassen_algorithm { + +class StrassenAlgorithmSEQ : public ppc::core::Task { + public: + explicit StrassenAlgorithmSEQ(std::shared_ptr taskData_) : Task(std::move(taskData_)) {} + + bool pre_processing() override; + bool validation() override; + bool run() override; + bool post_processing() override; + + private: + static std::vector strassen_multiply_seq(const std::vector& matrixA, + const std::vector& matrixB, size_t size); + + std::vector inputMatrixA; + std::vector inputMatrixB; + std::vector outputMatrix; + size_t matrixSize; +}; + +std::vector strassen_recursive(const std::vector& matrixA, const std::vector& matrixB, + size_t size); +std::vector matrix_add(const std::vector& matrixA, const std::vector& matrixB, size_t size); +std::vector matrix_subtract(const std::vector& matrixA, const std::vector& matrixB, + size_t size); +} // namespace nasedkin_e_strassen_algorithm \ No newline at end of file diff --git a/tasks/seq/nasedkin_e_strassen_algorithm/perf_tests/main.cpp b/tasks/seq/nasedkin_e_strassen_algorithm/perf_tests/main.cpp new file mode 100644 index 00000000000..e12b235c53a --- /dev/null +++ b/tasks/seq/nasedkin_e_strassen_algorithm/perf_tests/main.cpp @@ -0,0 +1,95 @@ +#include + +#include +#include +#include + +#include "core/perf/include/perf.hpp" +#include "seq/nasedkin_e_strassen_algorithm/include/ops_seq.hpp" + +std::vector generateRandomMatrix(int size) { + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_real_distribution<> dis(-100.0, 100.0); + std::vector matrix(size * size); + for (int i = 0; i < size * size; i++) { + matrix[i] = dis(gen); + } + return matrix; +} + +TEST(nasedkin_e_strassen_algorithm_perf_test, test_pipeline_run) { + int matrixSize = 1024; + std::vector matrixA = generateRandomMatrix(matrixSize); + std::vector matrixB = generateRandomMatrix(matrixSize); + std::vector resultSeq(matrixSize * matrixSize, 0.0); + + std::shared_ptr taskDataSeq = std::make_shared(); + + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + auto testSeqTask = std::make_shared(taskDataSeq); + ASSERT_EQ(testSeqTask->validation(), true); + testSeqTask->pre_processing(); + testSeqTask->run(); + testSeqTask->post_processing(); + + auto perfAttr = std::make_shared(); + perfAttr->num_running = 10; + const auto t0 = std::chrono::high_resolution_clock::now(); + perfAttr->current_timer = [&] { + auto current_time_point = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(current_time_point - t0).count(); + return static_cast(duration) * 1e-9; + }; + + auto perfResults = std::make_shared(); + + auto perfAnalyzer = std::make_shared(testSeqTask); + perfAnalyzer->pipeline_run(perfAttr, perfResults); + + ppc::core::Perf::print_perf_statistic(perfResults); +} + +TEST(nasedkin_e_strassen_algorithm_perf_test, test_task_run) { + int matrixSize = 1024; + std::vector matrixA = generateRandomMatrix(matrixSize); + std::vector matrixB = generateRandomMatrix(matrixSize); + std::vector resultSeq(matrixSize * matrixSize, 0.0); + + std::shared_ptr taskDataSeq = std::make_shared(); + + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + auto testSeqTask = std::make_shared(taskDataSeq); + ASSERT_EQ(testSeqTask->validation(), true); + testSeqTask->pre_processing(); + testSeqTask->run(); + testSeqTask->post_processing(); + + auto perfAttr = std::make_shared(); + perfAttr->num_running = 10; + const auto t0 = std::chrono::high_resolution_clock::now(); + perfAttr->current_timer = [&] { + auto current_time_point = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(current_time_point - t0).count(); + return static_cast(duration) * 1e-9; + }; + + auto perfResults = std::make_shared(); + + auto perfAnalyzer = std::make_shared(testSeqTask); + perfAnalyzer->task_run(perfAttr, perfResults); + + ppc::core::Perf::print_perf_statistic(perfResults); +} \ No newline at end of file diff --git a/tasks/seq/nasedkin_e_strassen_algorithm/src/ops_seq.cpp b/tasks/seq/nasedkin_e_strassen_algorithm/src/ops_seq.cpp new file mode 100644 index 00000000000..879cac885f8 --- /dev/null +++ b/tasks/seq/nasedkin_e_strassen_algorithm/src/ops_seq.cpp @@ -0,0 +1,263 @@ +#include "seq/nasedkin_e_strassen_algorithm/include/ops_seq.hpp" + +#include +#include +#include +#include +#include +#include + +namespace nasedkin_e_strassen_algorithm { + +bool StrassenAlgorithmSEQ::pre_processing() { + internal_order_test(); + std::cout << "Pre-processing: Loading inputs..." << std::endl; + auto* inputsA = reinterpret_cast(taskData->inputs[0]); + auto* inputsB = reinterpret_cast(taskData->inputs[1]); + + if (inputsA == nullptr || inputsB == nullptr) { + std::cout << "Pre-processing failed: Input pointers are null." << std::endl; + return false; + } + + std::cout << "Pre-processing: inputs_count[0] = " << taskData->inputs_count[0] << std::endl; + std::cout << "Pre-processing: inputs_count[1] = " << taskData->inputs_count[1] << std::endl; + + matrixSize = static_cast(std::sqrt(taskData->inputs_count[0])); + + std::cout << "Pre-processing: Matrix size = " << matrixSize << std::endl; + + if (matrixSize * matrixSize != taskData->inputs_count[0]) { + std::cout << "Pre-processing failed: Input size mismatch. Expected: " << matrixSize * matrixSize + << ", got: " << taskData->inputs_count[0] << std::endl; + return false; + } + + inputMatrixA.assign(inputsA, inputsA + matrixSize * matrixSize); + inputMatrixB.assign(inputsB, inputsB + matrixSize * matrixSize); + outputMatrix.resize(matrixSize * matrixSize, 0.0); + + std::cout << "Pre-processing: Input matrices loaded successfully." << std::endl; + return true; +} + +bool StrassenAlgorithmSEQ::validation() { + internal_order_test(); + std::cout << "Validation: Checking inputs..." << std::endl; + if (taskData->inputs.empty()) { + std::cout << "Validation failed: Inputs are empty." << std::endl; + return false; + } + if (taskData->inputs_count[0] != taskData->inputs_count[1]) { + std::cout << "Validation failed: Input sizes do not match." << std::endl; + return false; + } + std::cout << "Validation passed." << std::endl; + + return true; +} + +bool StrassenAlgorithmSEQ::run() { + internal_order_test(); + std::cout << "Starting Strassen_multiply with matrixSize = " << matrixSize << std::endl; + outputMatrix = strassen_multiply_seq(inputMatrixA, inputMatrixB, matrixSize); + return true; +} + +bool StrassenAlgorithmSEQ::post_processing() { + internal_order_test(); + std::cout << "Post-processing: Saving output..." << std::endl; + auto* outputs = reinterpret_cast(taskData->outputs[0]); + std::copy(outputMatrix.begin(), outputMatrix.end(), outputs); + std::cout << "Post-processing: Output saved successfully." << std::endl; + return true; +} + +std::vector matrix_add(const std::vector& matrixA, const std::vector& matrixB, size_t size) { + std::vector result(size * size); + for (size_t i = 0; i < size * size; ++i) { + result[i] = matrixA[i] + matrixB[i]; + } + return result; +} + +std::vector matrix_subtract(const std::vector& matrixA, const std::vector& matrixB, + size_t size) { + std::vector result(size * size); + for (size_t i = 0; i < size * size; ++i) { + result[i] = matrixA[i] - matrixB[i]; + } + return result; +} + +std::vector strassen_recursive(const std::vector& matrixA, const std::vector& matrixB, + size_t size) { + if (size == 1) { + return {matrixA[0] * matrixB[0]}; + } + + size_t half_size = size / 2; + + std::vector A11(half_size * half_size); + std::vector A12(half_size * half_size); + std::vector A21(half_size * half_size); + std::vector A22(half_size * half_size); + + std::vector B11(half_size * half_size); + std::vector B12(half_size * half_size); + std::vector B21(half_size * half_size); + std::vector B22(half_size * half_size); + + if (matrixA.size() != size * size || matrixB.size() != size * size) { + std::cout << "strassen_recursive: Matrix size mismatch. Expected: " << size * size << ", got: " << matrixA.size() + << " and " << matrixB.size() << std::endl; + return {}; + } + + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + A11[i * half_size + j] = matrixA[i * size + j]; + A12[i * half_size + j] = matrixA[i * size + j + half_size]; + A21[i * half_size + j] = matrixA[(i + half_size) * size + j]; + A22[i * half_size + j] = matrixA[(i + half_size) * size + j + half_size]; + + B11[i * half_size + j] = matrixB[i * size + j]; + B12[i * half_size + j] = matrixB[i * size + j + half_size]; + B21[i * half_size + j] = matrixB[(i + half_size) * size + j]; + B22[i * half_size + j] = matrixB[(i + half_size) * size + j + half_size]; + } + } + + std::vector M1 = + strassen_recursive(matrix_add(A11, A22, half_size), matrix_add(B11, B22, half_size), half_size); + std::vector M2 = strassen_recursive(matrix_add(A21, A22, half_size), B11, half_size); + std::vector M3 = strassen_recursive(A11, matrix_subtract(B12, B22, half_size), half_size); + std::vector M4 = strassen_recursive(A22, matrix_subtract(B21, B11, half_size), half_size); + std::vector M5 = strassen_recursive(matrix_add(A11, A12, half_size), B22, half_size); + std::vector M6 = + strassen_recursive(matrix_subtract(A21, A11, half_size), matrix_add(B11, B12, half_size), half_size); + std::vector M7 = + strassen_recursive(matrix_subtract(A12, A22, half_size), matrix_add(B21, B22, half_size), half_size); + + std::vector C11 = matrix_add(matrix_subtract(matrix_add(M1, M4, half_size), M5, half_size), M7, half_size); + std::vector C12 = matrix_add(M3, M5, half_size); + std::vector C21 = matrix_add(M2, M4, half_size); + std::vector C22 = matrix_add(matrix_subtract(matrix_add(M1, M3, half_size), M2, half_size), M6, half_size); + + std::vector local_result(size * size); + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + local_result[i * size + j] = C11[i * half_size + j]; + local_result[i * size + j + half_size] = C12[i * half_size + j]; + local_result[(i + half_size) * size + j] = C21[i * half_size + j]; + local_result[(i + half_size) * size + j + half_size] = C22[i * half_size + j]; + } + } + + return local_result; +} + +std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vector& matrixA, + const std::vector& matrixB, size_t size) { + if (matrixA.empty() || matrixB.empty() || size == 0) { + std::cout << "Error! matrixA, matrixB are empty, or size is zero before Strassen_multiply" << std::endl; + return {}; + } + + std::cout << "Strassen_multiply: Received matrix size = " << size << std::endl; + + if (size == 1) { + std::cout << "Strassen_multiply: Base case reached." << std::endl; + return {matrixA[0] * matrixB[0]}; + } + + size_t new_size = 1; + while (new_size < size) { + new_size *= 2; + } + + size_t half_size = new_size / 2; + + std::vector A11(half_size * half_size); + std::vector A12(half_size * half_size); + std::vector A21(half_size * half_size); + std::vector A22(half_size * half_size); + + std::vector B11(half_size * half_size); + std::vector B12(half_size * half_size); + std::vector B21(half_size * half_size); + std::vector B22(half_size * half_size); + + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + A11[i * half_size + j] = matrixA[i * new_size + j]; + A12[i * half_size + j] = matrixA[i * new_size + j + half_size]; + A21[i * half_size + j] = matrixA[(i + half_size) * new_size + j]; + A22[i * half_size + j] = matrixA[(i + half_size) * new_size + j + half_size]; + + B11[i * half_size + j] = matrixB[i * new_size + j]; + B12[i * half_size + j] = matrixB[i * new_size + j + half_size]; + B21[i * half_size + j] = matrixB[(i + half_size) * new_size + j]; + B22[i * half_size + j] = matrixB[(i + half_size) * new_size + j + half_size]; + } + } + + std::cout << "Strassen_multiply: Divided matrices into submatrices." << std::endl; + + std::cout << "A11 size = " << A11.size() << ", A12 size = " << A12.size() << ", A21 size = " << A21.size() + << ", A22 size = " << A22.size() << std::endl; + std::cout << "B11 size = " << B11.size() << ", B12 size = " << B12.size() << ", B21 size = " << B21.size() + << ", B22 size = " << B22.size() << std::endl; + + std::vector> M(7); + std::vector> tasks = {matrix_add(A11, A22, half_size), + matrix_add(A21, A22, half_size), + A11, + A22, + matrix_add(A11, A12, half_size), + matrix_subtract(A21, A11, half_size), + matrix_subtract(A12, A22, half_size)}; + + std::vector> tasksB = { + matrix_add(B11, B22, half_size), B11, matrix_subtract(B12, B22, half_size), + matrix_subtract(B21, B11, half_size), B22, matrix_add(B11, B12, half_size), + matrix_add(B21, B22, half_size)}; + std::cout << "Tasks created successfully" << std::endl; + + for (int i = 0; i < 7; ++i) { + M[i] = strassen_recursive(tasks[i], tasksB[i], half_size); + } + + for (int i = 0; i < 7; ++i) { + std::vector result; + M[i] = result; + } + + std::cout << "Final results collected. Verifying matrix sizes:" << std::endl; + for (int i = 0; i < 7; ++i) { + std::cout << "M[" << i << "] size = " << M[i].size() << std::endl; + } + + std::vector C11 = + matrix_add(matrix_subtract(matrix_add(M[0], M[3], half_size), M[4], half_size), M[6], half_size); + std::vector C12 = matrix_add(M[2], M[4], half_size); + std::vector C21 = matrix_add(M[1], M[3], half_size); + std::vector C22 = + matrix_add(matrix_subtract(matrix_add(M[0], M[2], half_size), M[1], half_size), M[5], half_size); + + std::cout << "All С calculated" << std::endl; + + std::vector result(size * size); + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + result[i * size + j] = C11[i * half_size + j]; + result[i * size + j + half_size] = C12[i * half_size + j]; + result[(i + half_size) * size + j] = C21[i * half_size + j]; + result[(i + half_size) * size + j + half_size] = C22[i * half_size + j]; + } + } + std::cout << "Final result calculated" << std::endl; + return result; + return {}; +} +} // namespace nasedkin_e_strassen_algorithm \ No newline at end of file From 5c2bca1fe92b3b2340170723b09d492da3d03554 Mon Sep 17 00:00:00 2001 From: myffii <132840123+myffii@users.noreply.github.com> Date: Thu, 26 Dec 2024 16:14:00 +0300 Subject: [PATCH 3/8] Removed debug output --- .../func_tests/main.cpp | 50 --------- .../src/ops_mpi.cpp | 100 +----------------- .../func_tests/main.cpp | 25 ----- .../src/ops_seq.cpp | 41 ------- 4 files changed, 1 insertion(+), 215 deletions(-) diff --git a/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp b/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp index 1ed9a097b6e..9f3df5de86a 100644 --- a/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp +++ b/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp @@ -14,11 +14,6 @@ std::vector generateRandomMatrix(int size) { std::uniform_real_distribution<> dis(-100.0, 100.0); std::vector matrix(size * size); - if (size <= 0) { - std::cout << "generateRandomMatrix: Invalid size: " << size << std::endl; - return matrix; - } - for (int i = 0; i < size * size; i++) { matrix[i] = dis(gen); } @@ -34,7 +29,6 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_2x2) { if (world.rank() == 0) { matrixA = generateRandomMatrix(matrixSize); matrixB = generateRandomMatrix(matrixSize); - std::cout << "Test: MatrixA size = " << matrixSize << ", MatrixB size = " << matrixSize << std::endl; } std::vector resultParallel(matrixSize * matrixSize, 0.0); std::vector resultSeq(matrixSize * matrixSize, 0.0); @@ -49,15 +43,11 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_2x2) { taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); taskDataSeq->outputs_count.emplace_back(resultSeq.size()); - std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] - << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; - nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); ASSERT_TRUE(testMpiTaskSeq.validation()); ASSERT_TRUE(testMpiTaskSeq.pre_processing()); ASSERT_TRUE(testMpiTaskSeq.run()); ASSERT_TRUE(testMpiTaskSeq.post_processing()); - std::cout << "SEQ Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; } std::shared_ptr taskDataParallel = std::make_shared(); @@ -69,9 +59,6 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_2x2) { taskDataParallel->inputs_count.emplace_back(matrixB.size()); taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); taskDataParallel->outputs_count.emplace_back(resultParallel.size()); - - std::cout << "Test: TaskData inputs_count[0] = " << taskDataParallel->inputs_count[0] - << ", inputs_count[1] = " << taskDataParallel->inputs_count[1] << std::endl; } nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); ASSERT_TRUE(testMpiTaskParallel.validation()); @@ -79,7 +66,6 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_2x2) { ASSERT_TRUE(testMpiTaskParallel.run()); ASSERT_TRUE(testMpiTaskParallel.post_processing()); ASSERT_EQ(resultSeq, resultParallel); - std::cout << "Parallel Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; } TEST(nasedkin_e_strassen_algorithm_mpi, Test_4x4) { @@ -91,7 +77,6 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_4x4) { if (world.rank() == 0) { matrixA = generateRandomMatrix(matrixSize); matrixB = generateRandomMatrix(matrixSize); - std::cout << "Test: MatrixA size = " << matrixSize << ", MatrixB size = " << matrixSize << std::endl; } std::vector resultParallel(matrixSize * matrixSize, 0.0); std::vector resultSeq(matrixSize * matrixSize, 0.0); @@ -106,15 +91,11 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_4x4) { taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); taskDataSeq->outputs_count.emplace_back(resultSeq.size()); - std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] - << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; - nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); ASSERT_TRUE(testMpiTaskSeq.validation()); ASSERT_TRUE(testMpiTaskSeq.pre_processing()); ASSERT_TRUE(testMpiTaskSeq.run()); ASSERT_TRUE(testMpiTaskSeq.post_processing()); - std::cout << "Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; } std::shared_ptr taskDataParallel = std::make_shared(); @@ -126,16 +107,12 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_4x4) { taskDataParallel->inputs_count.emplace_back(matrixB.size()); taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); taskDataParallel->outputs_count.emplace_back(resultParallel.size()); - - std::cout << "Test: TaskData inputs_count[0] = " << taskDataParallel->inputs_count[0] - << ", inputs_count[1] = " << taskDataParallel->inputs_count[1] << std::endl; } nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); ASSERT_TRUE(testMpiTaskParallel.validation()); ASSERT_TRUE(testMpiTaskParallel.pre_processing()); ASSERT_TRUE(testMpiTaskParallel.run()); ASSERT_TRUE(testMpiTaskParallel.post_processing()); - std::cout << "Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; ASSERT_EQ(resultSeq, resultParallel); } @@ -149,7 +126,6 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_8x8) { if (world.rank() == 0) { matrixA = generateRandomMatrix(matrixSize); matrixB = generateRandomMatrix(matrixSize); - std::cout << "Test: MatrixA size = " << matrixSize << ", MatrixB size = " << matrixSize << std::endl; } std::vector resultParallel(matrixSize * matrixSize, 0.0); std::vector resultSeq(matrixSize * matrixSize, 0.0); @@ -164,15 +140,11 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_8x8) { taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); taskDataSeq->outputs_count.emplace_back(resultSeq.size()); - std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] - << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; - nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); ASSERT_TRUE(testMpiTaskSeq.validation()); ASSERT_TRUE(testMpiTaskSeq.pre_processing()); ASSERT_TRUE(testMpiTaskSeq.run()); ASSERT_TRUE(testMpiTaskSeq.post_processing()); - std::cout << "Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; } std::shared_ptr taskDataParallel = std::make_shared(); @@ -184,16 +156,12 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_8x8) { taskDataParallel->inputs_count.emplace_back(matrixB.size()); taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); taskDataParallel->outputs_count.emplace_back(resultParallel.size()); - - std::cout << "Test: TaskData inputs_count[0] = " << taskDataParallel->inputs_count[0] - << ", inputs_count[1] = " << taskDataParallel->inputs_count[1] << std::endl; } nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); ASSERT_TRUE(testMpiTaskParallel.validation()); ASSERT_TRUE(testMpiTaskParallel.pre_processing()); ASSERT_TRUE(testMpiTaskParallel.run()); ASSERT_TRUE(testMpiTaskParallel.post_processing()); - std::cout << "Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; ASSERT_EQ(resultSeq, resultParallel); } @@ -207,7 +175,6 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_16x16) { if (world.rank() == 0) { matrixA = generateRandomMatrix(matrixSize); matrixB = generateRandomMatrix(matrixSize); - std::cout << "Test: MatrixA size = " << matrixSize << ", MatrixB size = " << matrixSize << std::endl; } std::vector resultParallel(matrixSize * matrixSize, 0.0); std::vector resultSeq(matrixSize * matrixSize, 0.0); @@ -222,15 +189,11 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_16x16) { taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); taskDataSeq->outputs_count.emplace_back(resultSeq.size()); - std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] - << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; - nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); ASSERT_TRUE(testMpiTaskSeq.validation()); ASSERT_TRUE(testMpiTaskSeq.pre_processing()); ASSERT_TRUE(testMpiTaskSeq.run()); ASSERT_TRUE(testMpiTaskSeq.post_processing()); - std::cout << "Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; } std::shared_ptr taskDataParallel = std::make_shared(); @@ -242,16 +205,12 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_16x16) { taskDataParallel->inputs_count.emplace_back(matrixB.size()); taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); taskDataParallel->outputs_count.emplace_back(resultParallel.size()); - - std::cout << "Test: TaskData inputs_count[0] = " << taskDataParallel->inputs_count[0] - << ", inputs_count[1] = " << taskDataParallel->inputs_count[1] << std::endl; } nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); ASSERT_TRUE(testMpiTaskParallel.validation()); ASSERT_TRUE(testMpiTaskParallel.pre_processing()); ASSERT_TRUE(testMpiTaskParallel.run()); ASSERT_TRUE(testMpiTaskParallel.post_processing()); - std::cout << "Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; ASSERT_EQ(resultSeq, resultParallel); } @@ -265,7 +224,6 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_32x32) { if (world.rank() == 0) { matrixA = generateRandomMatrix(matrixSize); matrixB = generateRandomMatrix(matrixSize); - std::cout << "Test: MatrixA size = " << matrixSize << ", MatrixB size = " << matrixSize << std::endl; } std::vector resultParallel(matrixSize * matrixSize, 0.0); std::vector resultSeq(matrixSize * matrixSize, 0.0); @@ -280,15 +238,11 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_32x32) { taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); taskDataSeq->outputs_count.emplace_back(resultSeq.size()); - std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] - << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; - nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); ASSERT_TRUE(testMpiTaskSeq.validation()); ASSERT_TRUE(testMpiTaskSeq.pre_processing()); ASSERT_TRUE(testMpiTaskSeq.run()); ASSERT_TRUE(testMpiTaskSeq.post_processing()); - std::cout << "Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; } std::shared_ptr taskDataParallel = std::make_shared(); @@ -300,16 +254,12 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_32x32) { taskDataParallel->inputs_count.emplace_back(matrixB.size()); taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); taskDataParallel->outputs_count.emplace_back(resultParallel.size()); - - std::cout << "Test: TaskData inputs_count[0] = " << taskDataParallel->inputs_count[0] - << ", inputs_count[1] = " << taskDataParallel->inputs_count[1] << std::endl; } nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); ASSERT_TRUE(testMpiTaskParallel.validation()); ASSERT_TRUE(testMpiTaskParallel.pre_processing()); ASSERT_TRUE(testMpiTaskParallel.run()); ASSERT_TRUE(testMpiTaskParallel.post_processing()); - std::cout << "Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; ASSERT_EQ(resultSeq, resultParallel); } \ No newline at end of file diff --git a/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp b/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp index a5e03228c63..ba09c3b3654 100644 --- a/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp +++ b/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp @@ -14,25 +14,16 @@ namespace nasedkin_e_strassen_algorithm { bool StrassenAlgorithmSEQ::pre_processing() { internal_order_test(); - std::cout << "Pre-processing: Loading inputs..." << std::endl; auto* inputsA = reinterpret_cast(taskData->inputs[0]); auto* inputsB = reinterpret_cast(taskData->inputs[1]); if (inputsA == nullptr || inputsB == nullptr) { - std::cout << "Pre-processing failed: Input pointers are null." << std::endl; return false; } - std::cout << "Pre-processing: inputs_count[0] = " << taskData->inputs_count[0] << std::endl; - std::cout << "Pre-processing: inputs_count[1] = " << taskData->inputs_count[1] << std::endl; - matrixSize = static_cast(std::sqrt(taskData->inputs_count[0])); - std::cout << "Pre-processing: Matrix size = " << matrixSize << std::endl; - if (matrixSize * matrixSize != taskData->inputs_count[0]) { - std::cout << "Pre-processing failed: Input size mismatch. Expected: " << matrixSize * matrixSize - << ", got: " << taskData->inputs_count[0] << std::endl; return false; } @@ -40,39 +31,30 @@ bool StrassenAlgorithmSEQ::pre_processing() { inputMatrixB.assign(inputsB, inputsB + matrixSize * matrixSize); outputMatrix.resize(matrixSize * matrixSize, 0.0); - std::cout << "Pre-processing: Input matrices loaded successfully." << std::endl; return true; } bool StrassenAlgorithmSEQ::validation() { internal_order_test(); - std::cout << "Validation: Checking inputs..." << std::endl; if (taskData->inputs.empty()) { - std::cout << "Validation failed: Inputs are empty." << std::endl; return false; } if (taskData->inputs_count[0] != taskData->inputs_count[1]) { - std::cout << "Validation failed: Input sizes do not match." << std::endl; return false; } - std::cout << "Validation passed." << std::endl; - return true; } bool StrassenAlgorithmSEQ::run() { internal_order_test(); - std::cout << "Starting Strassen_multiply with matrixSize = " << matrixSize << std::endl; outputMatrix = strassen_multiply_seq(inputMatrixA, inputMatrixB, matrixSize); return true; } bool StrassenAlgorithmSEQ::post_processing() { internal_order_test(); - std::cout << "Post-processing: Saving output..." << std::endl; auto* outputs = reinterpret_cast(taskData->outputs[0]); std::copy(outputMatrix.begin(), outputMatrix.end(), outputs); - std::cout << "Post-processing: Output saved successfully." << std::endl; return true; } @@ -80,35 +62,22 @@ bool StrassenAlgorithmMPI::pre_processing() { internal_order_test(); int rank = world.rank(); if (rank == 0) { - std::cout << "Pre-processing: Loading inputs..." << std::endl; auto* inputsA = reinterpret_cast(taskData->inputs[0]); auto* inputsB = reinterpret_cast(taskData->inputs[1]); if (inputsA == nullptr || inputsB == nullptr) { - std::cout << "Pre-processing failed: Input pointers are null." << std::endl; return false; } - if (rank == 0) { - std::cout << "Pre-processing: inputs_count[0] = " << taskData->inputs_count[0] << std::endl; - std::cout << "Pre-processing: inputs_count[1] = " << taskData->inputs_count[1] << std::endl; - } - matrixSize = static_cast(std::sqrt(taskData->inputs_count[0])); - std::cout << "Pre-processing: Matrix size = " << matrixSize << std::endl; - if (matrixSize * matrixSize != taskData->inputs_count[0]) { - std::cout << "Pre-processing failed: Input size mismatch. Expected: " << matrixSize * matrixSize - << ", got: " << taskData->inputs_count[0] << std::endl; return false; } inputMatrixA.assign(inputsA, inputsA + matrixSize * matrixSize); inputMatrixB.assign(inputsB, inputsB + matrixSize * matrixSize); outputMatrix.resize(matrixSize * matrixSize, 0.0); - - std::cout << "Pre-processing: Input matrices loaded successfully." << std::endl; } return true; } @@ -117,16 +86,12 @@ bool StrassenAlgorithmMPI::validation() { internal_order_test(); int rank = world.rank(); if (rank == 0) { - std::cout << "Validation: Checking inputs..." << std::endl; if (taskData->inputs.empty()) { - std::cout << "Validation failed: Inputs are empty." << std::endl; return false; } if (taskData->inputs_count[0] != taskData->inputs_count[1]) { - std::cout << "Validation failed: Input sizes do not match." << std::endl; return false; } - std::cout << "Validation passed." << std::endl; } return true; } @@ -138,7 +103,6 @@ bool StrassenAlgorithmMPI::run() { boost::mpi::broadcast(world, inputMatrixB, 0); boost::mpi::broadcast(world, matrixSize, 0); - std::cout << "Rank " << world.rank() << ": Starting Strassen_multiply with matrixSize = " << matrixSize << std::endl; outputMatrix = strassen_multiply(inputMatrixA, inputMatrixB, matrixSize); return true; } @@ -147,10 +111,8 @@ bool StrassenAlgorithmMPI::post_processing() { internal_order_test(); int rank = world.rank(); if (rank == 0) { - std::cout << "Post-processing: Saving output..." << std::endl; auto* outputs = reinterpret_cast(taskData->outputs[0]); std::copy(outputMatrix.begin(), outputMatrix.end(), outputs); - std::cout << "Post-processing: Output saved successfully." << std::endl; } return true; } @@ -191,8 +153,6 @@ std::vector strassen_recursive(const std::vector& matrixA, const std::vector B22(half_size * half_size); if (matrixA.size() != size * size || matrixB.size() != size * size) { - std::cout << "strassen_recursive: Matrix size mismatch. Expected: " << size * size << ", got: " << matrixA.size() - << " and " << matrixB.size() << std::endl; return {}; } @@ -242,14 +202,10 @@ std::vector strassen_recursive(const std::vector& matrixA, const std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vector& matrixA, const std::vector& matrixB, size_t size) { if (matrixA.empty() || matrixB.empty() || size == 0) { - std::cout << "Error! matrixA, matrixB are empty, or size is zero before Strassen_multiply" << std::endl; return {}; } - std::cout << "Strassen_multiply: Received matrix size = " << size << std::endl; - if (size == 1) { - std::cout << "Strassen_multiply: Base case reached." << std::endl; return {matrixA[0] * matrixB[0]}; } @@ -284,13 +240,6 @@ std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vecto } } - std::cout << "Strassen_multiply: Divided matrices into submatrices." << std::endl; - - std::cout << "A11 size = " << A11.size() << ", A12 size = " << A12.size() << ", A21 size = " << A21.size() - << ", A22 size = " << A22.size() << std::endl; - std::cout << "B11 size = " << B11.size() << ", B12 size = " << B12.size() << ", B21 size = " << B21.size() - << ", B22 size = " << B22.size() << std::endl; - std::vector> M(7); std::vector> tasks = {matrix_add(A11, A22, half_size), matrix_add(A21, A22, half_size), @@ -304,7 +253,6 @@ std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vecto matrix_add(B11, B22, half_size), B11, matrix_subtract(B12, B22, half_size), matrix_subtract(B21, B11, half_size), B22, matrix_add(B11, B12, half_size), matrix_add(B21, B22, half_size)}; - std::cout << "Tasks created successfully" << std::endl; for (int i = 0; i < 7; ++i) { M[i] = strassen_recursive(tasks[i], tasksB[i], half_size); @@ -315,11 +263,6 @@ std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vecto M[i] = result; } - std::cout << "Final results collected. Verifying matrix sizes:" << std::endl; - for (int i = 0; i < 7; ++i) { - std::cout << "M[" << i << "] size = " << M[i].size() << std::endl; - } - std::vector C11 = matrix_add(matrix_subtract(matrix_add(M[0], M[3], half_size), M[4], half_size), M[6], half_size); std::vector C12 = matrix_add(M[2], M[4], half_size); @@ -327,8 +270,6 @@ std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vecto std::vector C22 = matrix_add(matrix_subtract(matrix_add(M[0], M[2], half_size), M[1], half_size), M[5], half_size); - std::cout << "All С calculated" << std::endl; - std::vector result(size * size); for (size_t i = 0; i < half_size; ++i) { for (size_t j = 0; j < half_size; ++j) { @@ -338,7 +279,6 @@ std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vecto result[(i + half_size) * size + j + half_size] = C22[i * half_size + j]; } } - std::cout << "Final result calculated" << std::endl; return result; return {}; } @@ -351,19 +291,11 @@ std::vector StrassenAlgorithmMPI::strassen_multiply(const std::vector StrassenAlgorithmMPI::strassen_multiply(const std::vector StrassenAlgorithmMPI::strassen_multiply(const std::vector taskA; std::vector taskB; - std::cout << "Rank " << rank << " waiting for taskA and taskB for M[" << i << "]..." << std::endl; world.recv(0, i, taskA); world.recv(0, i, taskB); - std::cout << "Rank " << rank << " received taskA size = " << taskA.size() << ", taskB size = " << taskB.size() - << std::endl; M[i] = strassen_recursive(taskA, taskB, half_size); world.send(0, i, M[i]); - std::cout << "Rank " << rank << " sent result for M[" << i << "] to rank 0." << std::endl; } } if (rank == 0) { for (int i = 0; i < 7; ++i) { - if (i % num_procs == 0) { - std::cout << "Rank 0 already processed result for M[" << i << "] locally." << std::endl; - } else { - std::cout << "Rank 0 waiting to receive result for M[" << i << "] from rank " << (i % num_procs) << "..." - << std::endl; + if (i % num_procs != 0) { std::vector result; world.recv(i % num_procs, i, result); M[i] = result; - std::cout << "Rank 0 received result for M[" << i << "] from rank " << (i % num_procs) << std::endl; } } } - if (rank == 0) { - std::cout << "Rank 0: Final results collected. Verifying matrix sizes:" << std::endl; - for (int i = 0; i < 7; ++i) { - std::cout << "M[" << i << "] size = " << M[i].size() << std::endl; - } - std::vector C11 = matrix_add(matrix_subtract(matrix_add(M[0], M[3], half_size), M[4], half_size), M[6], half_size); std::vector C12 = matrix_add(M[2], M[4], half_size); @@ -481,8 +386,6 @@ std::vector StrassenAlgorithmMPI::strassen_multiply(const std::vector C22 = matrix_add(matrix_subtract(matrix_add(M[0], M[2], half_size), M[1], half_size), M[5], half_size); - std::cout << "Rank 0: all С calculated" << std::endl; - std::vector result(size * size); for (size_t i = 0; i < half_size; ++i) { for (size_t j = 0; j < half_size; ++j) { @@ -492,7 +395,6 @@ std::vector StrassenAlgorithmMPI::strassen_multiply(const std::vector generateRandomMatrix(int size) { std::uniform_real_distribution<> dis(-100.0, 100.0); std::vector matrix(size * size); - if (size <= 0) { - std::cout << "generateRandomMatrix: Invalid size: " << size << std::endl; - return matrix; - } - for (int i = 0; i < size * size; i++) { matrix[i] = dis(gen); } @@ -37,15 +32,11 @@ TEST(nasedkin_e_strassen_algorithm_seq, Test_2x2) { taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); taskDataSeq->outputs_count.emplace_back(resultSeq.size()); - std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] - << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; - nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testSeqTask(taskDataSeq); ASSERT_TRUE(testSeqTask.validation()); ASSERT_TRUE(testSeqTask.pre_processing()); ASSERT_TRUE(testSeqTask.run()); ASSERT_TRUE(testSeqTask.post_processing()); - std::cout << "SEQ Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; } TEST(nasedkin_e_strassen_algorithm_seq, Test_4x4) { @@ -63,15 +54,11 @@ TEST(nasedkin_e_strassen_algorithm_seq, Test_4x4) { taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); taskDataSeq->outputs_count.emplace_back(resultSeq.size()); - std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] - << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; - nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testSeqTask(taskDataSeq); ASSERT_TRUE(testSeqTask.validation()); ASSERT_TRUE(testSeqTask.pre_processing()); ASSERT_TRUE(testSeqTask.run()); ASSERT_TRUE(testSeqTask.post_processing()); - std::cout << "SEQ Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; } TEST(nasedkin_e_strassen_algorithm_seq, Test_8x8) { @@ -89,15 +76,11 @@ TEST(nasedkin_e_strassen_algorithm_seq, Test_8x8) { taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); taskDataSeq->outputs_count.emplace_back(resultSeq.size()); - std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] - << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; - nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testSeqTask(taskDataSeq); ASSERT_TRUE(testSeqTask.validation()); ASSERT_TRUE(testSeqTask.pre_processing()); ASSERT_TRUE(testSeqTask.run()); ASSERT_TRUE(testSeqTask.post_processing()); - std::cout << "SEQ Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; } TEST(nasedkin_e_strassen_algorithm_seq, Test_16x16) { @@ -115,15 +98,11 @@ TEST(nasedkin_e_strassen_algorithm_seq, Test_16x16) { taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); taskDataSeq->outputs_count.emplace_back(resultSeq.size()); - std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] - << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; - nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testSeqTask(taskDataSeq); ASSERT_TRUE(testSeqTask.validation()); ASSERT_TRUE(testSeqTask.pre_processing()); ASSERT_TRUE(testSeqTask.run()); ASSERT_TRUE(testSeqTask.post_processing()); - std::cout << "SEQ Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; } TEST(nasedkin_e_strassen_algorithm_seq, Test_32x32) { @@ -141,13 +120,9 @@ TEST(nasedkin_e_strassen_algorithm_seq, Test_32x32) { taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); taskDataSeq->outputs_count.emplace_back(resultSeq.size()); - std::cout << "Test: TaskData inputs_count[0] = " << taskDataSeq->inputs_count[0] - << ", inputs_count[1] = " << taskDataSeq->inputs_count[1] << std::endl; - nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testSeqTask(taskDataSeq); ASSERT_TRUE(testSeqTask.validation()); ASSERT_TRUE(testSeqTask.pre_processing()); ASSERT_TRUE(testSeqTask.run()); ASSERT_TRUE(testSeqTask.post_processing()); - std::cout << "SEQ Test for " << matrixSize << "x" << matrixSize << " matrix finished" << std::endl; } \ No newline at end of file diff --git a/tasks/seq/nasedkin_e_strassen_algorithm/src/ops_seq.cpp b/tasks/seq/nasedkin_e_strassen_algorithm/src/ops_seq.cpp index 879cac885f8..78c01610123 100644 --- a/tasks/seq/nasedkin_e_strassen_algorithm/src/ops_seq.cpp +++ b/tasks/seq/nasedkin_e_strassen_algorithm/src/ops_seq.cpp @@ -11,65 +11,46 @@ namespace nasedkin_e_strassen_algorithm { bool StrassenAlgorithmSEQ::pre_processing() { internal_order_test(); - std::cout << "Pre-processing: Loading inputs..." << std::endl; auto* inputsA = reinterpret_cast(taskData->inputs[0]); auto* inputsB = reinterpret_cast(taskData->inputs[1]); if (inputsA == nullptr || inputsB == nullptr) { - std::cout << "Pre-processing failed: Input pointers are null." << std::endl; return false; } - std::cout << "Pre-processing: inputs_count[0] = " << taskData->inputs_count[0] << std::endl; - std::cout << "Pre-processing: inputs_count[1] = " << taskData->inputs_count[1] << std::endl; - matrixSize = static_cast(std::sqrt(taskData->inputs_count[0])); - std::cout << "Pre-processing: Matrix size = " << matrixSize << std::endl; - if (matrixSize * matrixSize != taskData->inputs_count[0]) { - std::cout << "Pre-processing failed: Input size mismatch. Expected: " << matrixSize * matrixSize - << ", got: " << taskData->inputs_count[0] << std::endl; return false; } inputMatrixA.assign(inputsA, inputsA + matrixSize * matrixSize); inputMatrixB.assign(inputsB, inputsB + matrixSize * matrixSize); outputMatrix.resize(matrixSize * matrixSize, 0.0); - - std::cout << "Pre-processing: Input matrices loaded successfully." << std::endl; return true; } bool StrassenAlgorithmSEQ::validation() { internal_order_test(); - std::cout << "Validation: Checking inputs..." << std::endl; if (taskData->inputs.empty()) { - std::cout << "Validation failed: Inputs are empty." << std::endl; return false; } if (taskData->inputs_count[0] != taskData->inputs_count[1]) { - std::cout << "Validation failed: Input sizes do not match." << std::endl; return false; } - std::cout << "Validation passed." << std::endl; - return true; } bool StrassenAlgorithmSEQ::run() { internal_order_test(); - std::cout << "Starting Strassen_multiply with matrixSize = " << matrixSize << std::endl; outputMatrix = strassen_multiply_seq(inputMatrixA, inputMatrixB, matrixSize); return true; } bool StrassenAlgorithmSEQ::post_processing() { internal_order_test(); - std::cout << "Post-processing: Saving output..." << std::endl; auto* outputs = reinterpret_cast(taskData->outputs[0]); std::copy(outputMatrix.begin(), outputMatrix.end(), outputs); - std::cout << "Post-processing: Output saved successfully." << std::endl; return true; } @@ -109,8 +90,6 @@ std::vector strassen_recursive(const std::vector& matrixA, const std::vector B22(half_size * half_size); if (matrixA.size() != size * size || matrixB.size() != size * size) { - std::cout << "strassen_recursive: Matrix size mismatch. Expected: " << size * size << ", got: " << matrixA.size() - << " and " << matrixB.size() << std::endl; return {}; } @@ -160,14 +139,10 @@ std::vector strassen_recursive(const std::vector& matrixA, const std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vector& matrixA, const std::vector& matrixB, size_t size) { if (matrixA.empty() || matrixB.empty() || size == 0) { - std::cout << "Error! matrixA, matrixB are empty, or size is zero before Strassen_multiply" << std::endl; return {}; } - std::cout << "Strassen_multiply: Received matrix size = " << size << std::endl; - if (size == 1) { - std::cout << "Strassen_multiply: Base case reached." << std::endl; return {matrixA[0] * matrixB[0]}; } @@ -202,13 +177,6 @@ std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vecto } } - std::cout << "Strassen_multiply: Divided matrices into submatrices." << std::endl; - - std::cout << "A11 size = " << A11.size() << ", A12 size = " << A12.size() << ", A21 size = " << A21.size() - << ", A22 size = " << A22.size() << std::endl; - std::cout << "B11 size = " << B11.size() << ", B12 size = " << B12.size() << ", B21 size = " << B21.size() - << ", B22 size = " << B22.size() << std::endl; - std::vector> M(7); std::vector> tasks = {matrix_add(A11, A22, half_size), matrix_add(A21, A22, half_size), @@ -222,7 +190,6 @@ std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vecto matrix_add(B11, B22, half_size), B11, matrix_subtract(B12, B22, half_size), matrix_subtract(B21, B11, half_size), B22, matrix_add(B11, B12, half_size), matrix_add(B21, B22, half_size)}; - std::cout << "Tasks created successfully" << std::endl; for (int i = 0; i < 7; ++i) { M[i] = strassen_recursive(tasks[i], tasksB[i], half_size); @@ -233,11 +200,6 @@ std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vecto M[i] = result; } - std::cout << "Final results collected. Verifying matrix sizes:" << std::endl; - for (int i = 0; i < 7; ++i) { - std::cout << "M[" << i << "] size = " << M[i].size() << std::endl; - } - std::vector C11 = matrix_add(matrix_subtract(matrix_add(M[0], M[3], half_size), M[4], half_size), M[6], half_size); std::vector C12 = matrix_add(M[2], M[4], half_size); @@ -245,8 +207,6 @@ std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vecto std::vector C22 = matrix_add(matrix_subtract(matrix_add(M[0], M[2], half_size), M[1], half_size), M[5], half_size); - std::cout << "All С calculated" << std::endl; - std::vector result(size * size); for (size_t i = 0; i < half_size; ++i) { for (size_t j = 0; j < half_size; ++j) { @@ -256,7 +216,6 @@ std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vecto result[(i + half_size) * size + j + half_size] = C22[i * half_size + j]; } } - std::cout << "Final result calculated" << std::endl; return result; return {}; } From ca8c8b40dc61a5dae4e833c7d2c889846cf457dd Mon Sep 17 00:00:00 2001 From: myffii <132840123+myffii@users.noreply.github.com> Date: Thu, 26 Dec 2024 16:51:48 +0300 Subject: [PATCH 4/8] fix --- .../src/ops_mpi.cpp | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp b/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp index ba09c3b3654..cb1b0d5cd9c 100644 --- a/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp +++ b/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp @@ -379,25 +379,25 @@ std::vector StrassenAlgorithmMPI::strassen_multiply(const std::vector C11 = - matrix_add(matrix_subtract(matrix_add(M[0], M[3], half_size), M[4], half_size), M[6], half_size); - std::vector C12 = matrix_add(M[2], M[4], half_size); - std::vector C21 = matrix_add(M[1], M[3], half_size); - std::vector C22 = - matrix_add(matrix_subtract(matrix_add(M[0], M[2], half_size), M[1], half_size), M[5], half_size); - - std::vector result(size * size); - for (size_t i = 0; i < half_size; ++i) { - for (size_t j = 0; j < half_size; ++j) { - result[i * size + j] = C11[i * half_size + j]; - result[i * size + j + half_size] = C12[i * half_size + j]; - result[(i + half_size) * size + j] = C21[i * half_size + j]; - result[(i + half_size) * size + j + half_size] = C22[i * half_size + j]; - } + std::vector C11 = + matrix_add(matrix_subtract(matrix_add(M[0], M[3], half_size), M[4], half_size), M[6], half_size); + std::vector C12 = matrix_add(M[2], M[4], half_size); + std::vector C21 = matrix_add(M[1], M[3], half_size); + std::vector C22 = + matrix_add(matrix_subtract(matrix_add(M[0], M[2], half_size), M[1], half_size), M[5], half_size); + + std::vector result(size * size); + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + result[i * size + j] = C11[i * half_size + j]; + result[i * size + j + half_size] = C12[i * half_size + j]; + result[(i + half_size) * size + j] = C21[i * half_size + j]; + result[(i + half_size) * size + j + half_size] = C22[i * half_size + j]; } - return result; } - return {}; + return result; +} +return {}; } } // namespace nasedkin_e_strassen_algorithm \ No newline at end of file From 9b312b9ee752cbea372baf50779aebc6d74fcf50 Mon Sep 17 00:00:00 2001 From: myffii <132840123+myffii@users.noreply.github.com> Date: Thu, 26 Dec 2024 17:31:40 +0300 Subject: [PATCH 5/8] Fix --- .../src/ops_mpi.cpp | 70 +++++++------------ 1 file changed, 26 insertions(+), 44 deletions(-) diff --git a/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp b/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp index cb1b0d5cd9c..dbde72cd6e5 100644 --- a/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp +++ b/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp @@ -1,5 +1,3 @@ -#include "mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp" - #include #include #include @@ -10,27 +8,18 @@ #include #include +#include "mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp" + namespace nasedkin_e_strassen_algorithm { bool StrassenAlgorithmSEQ::pre_processing() { internal_order_test(); auto* inputsA = reinterpret_cast(taskData->inputs[0]); auto* inputsB = reinterpret_cast(taskData->inputs[1]); - - if (inputsA == nullptr || inputsB == nullptr) { - return false; - } - matrixSize = static_cast(std::sqrt(taskData->inputs_count[0])); - - if (matrixSize * matrixSize != taskData->inputs_count[0]) { - return false; - } - inputMatrixA.assign(inputsA, inputsA + matrixSize * matrixSize); inputMatrixB.assign(inputsB, inputsB + matrixSize * matrixSize); outputMatrix.resize(matrixSize * matrixSize, 0.0); - return true; } @@ -42,6 +31,9 @@ bool StrassenAlgorithmSEQ::validation() { if (taskData->inputs_count[0] != taskData->inputs_count[1]) { return false; } + if (taskData->inputs_count[0] != taskData->outputs_count[0]) { + return false; + } return true; } @@ -92,17 +84,18 @@ bool StrassenAlgorithmMPI::validation() { if (taskData->inputs_count[0] != taskData->inputs_count[1]) { return false; } + if (taskData->inputs_count[0] != taskData->outputs_count[0]) { + return false; + } } return true; } bool StrassenAlgorithmMPI::run() { internal_order_test(); - boost::mpi::broadcast(world, inputMatrixA, 0); boost::mpi::broadcast(world, inputMatrixB, 0); boost::mpi::broadcast(world, matrixSize, 0); - outputMatrix = strassen_multiply(inputMatrixA, inputMatrixB, matrixSize); return true; } @@ -152,10 +145,6 @@ std::vector strassen_recursive(const std::vector& matrixA, const std::vector B21(half_size * half_size); std::vector B22(half_size * half_size); - if (matrixA.size() != size * size || matrixB.size() != size * size) { - return {}; - } - for (size_t i = 0; i < half_size; ++i) { for (size_t j = 0; j < half_size; ++j) { A11[i * half_size + j] = matrixA[i * size + j]; @@ -201,10 +190,6 @@ std::vector strassen_recursive(const std::vector& matrixA, const std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vector& matrixA, const std::vector& matrixB, size_t size) { - if (matrixA.empty() || matrixB.empty() || size == 0) { - return {}; - } - if (size == 1) { return {matrixA[0] * matrixB[0]}; } @@ -291,10 +276,6 @@ std::vector StrassenAlgorithmMPI::strassen_multiply(const std::vector StrassenAlgorithmMPI::strassen_multiply(const std::vector C11 = - matrix_add(matrix_subtract(matrix_add(M[0], M[3], half_size), M[4], half_size), M[6], half_size); - std::vector C12 = matrix_add(M[2], M[4], half_size); - std::vector C21 = matrix_add(M[1], M[3], half_size); - std::vector C22 = - matrix_add(matrix_subtract(matrix_add(M[0], M[2], half_size), M[1], half_size), M[5], half_size); - - std::vector result(size * size); - for (size_t i = 0; i < half_size; ++i) { - for (size_t j = 0; j < half_size; ++j) { - result[i * size + j] = C11[i * half_size + j]; - result[i * size + j + half_size] = C12[i * half_size + j]; - result[(i + half_size) * size + j] = C21[i * half_size + j]; - result[(i + half_size) * size + j + half_size] = C22[i * half_size + j]; + if (rank == 0) { + std::vector C11 = + matrix_add(matrix_subtract(matrix_add(M[0], M[3], half_size), M[4], half_size), M[6], half_size); + std::vector C12 = matrix_add(M[2], M[4], half_size); + std::vector C21 = matrix_add(M[1], M[3], half_size); + std::vector C22 = + matrix_add(matrix_subtract(matrix_add(M[0], M[2], half_size), M[1], half_size), M[5], half_size); + + std::vector result(size * size); + for (size_t i = 0; i < half_size; ++i) { + for (size_t j = 0; j < half_size; ++j) { + result[i * size + j] = C11[i * half_size + j]; + result[i * size + j + half_size] = C12[i * half_size + j]; + result[(i + half_size) * size + j] = C21[i * half_size + j]; + result[(i + half_size) * size + j + half_size] = C22[i * half_size + j]; + } } + return result; } - return result; -} -return {}; + return {}; } } // namespace nasedkin_e_strassen_algorithm \ No newline at end of file From feb3cc9af001d3d7f8ceb7a20303f1228723d15b Mon Sep 17 00:00:00 2001 From: myffii <132840123+myffii@users.noreply.github.com> Date: Thu, 26 Dec 2024 17:39:46 +0300 Subject: [PATCH 6/8] LAST CLANG-FORMAT FIX --- tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp b/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp index dbde72cd6e5..dc2bd61dd1d 100644 --- a/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp +++ b/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp @@ -1,3 +1,5 @@ +#include "mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp" + #include #include #include @@ -8,8 +10,6 @@ #include #include -#include "mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp" - namespace nasedkin_e_strassen_algorithm { bool StrassenAlgorithmSEQ::pre_processing() { From 50e2621cbabc46925355204c833aa7ad68712f73 Mon Sep 17 00:00:00 2001 From: myffii <132840123+myffii@users.noreply.github.com> Date: Thu, 26 Dec 2024 19:45:23 +0300 Subject: [PATCH 7/8] Add tests --- .../func_tests/main.cpp | 55 ++++++++++++++++++ .../func_tests/main.cpp | 58 +++++++++++++++++++ 2 files changed, 113 insertions(+) diff --git a/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp b/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp index 9f3df5de86a..2444dfd9f9c 100644 --- a/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp +++ b/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp @@ -20,6 +20,61 @@ std::vector generateRandomMatrix(int size) { return matrix; } +TEST(nasedkin_e_strassen_algorithm_mpi, EmptyInputs) { + boost::mpi::communicator world; + + if (world.rank() == 0) { + auto taskData = std::make_shared(); + taskData->inputs = {}; + + nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI task(taskData); + ASSERT_FALSE(task.validation()); + } +} + +TEST(nasedkin_e_strassen_algorithm_mpi, MismatchedMatrixSizes) { + boost::mpi::communicator world; + + if (world.rank() == 0) { + auto taskData = std::make_shared(); + + std::vector matrixA = {1, 2, 3, 4}; + std::vector matrixB = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + + taskData->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskData->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskData->inputs_count.emplace_back(matrixA.size()); + taskData->inputs_count.emplace_back(matrixB.size()); + taskData->outputs.emplace_back(nullptr); + taskData->outputs_count.emplace_back(0); + + nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI task(taskData); + ASSERT_FALSE(task.validation()); + } +} + +TEST(nasedkin_e_strassen_algorithm_mpi, InvalidOutputSize) { + boost::mpi::communicator world; + + if (world.rank() == 0) { + auto taskData = std::make_shared(); + + std::vector matrixA = {1, 2, 3, 4}; + std::vector matrixB = {5, 6, 7, 8}; + std::vector result(6); + + taskData->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskData->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskData->inputs_count.emplace_back(matrixA.size()); + taskData->inputs_count.emplace_back(matrixB.size()); + taskData->outputs.emplace_back(reinterpret_cast(result.data())); + taskData->outputs_count.emplace_back(result.size()); + + nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI task(taskData); + ASSERT_FALSE(task.validation()); + } +} + TEST(nasedkin_e_strassen_algorithm_mpi, Test_2x2) { boost::mpi::communicator world; diff --git a/tasks/seq/nasedkin_e_strassen_algorithm/func_tests/main.cpp b/tasks/seq/nasedkin_e_strassen_algorithm/func_tests/main.cpp index 8d16f9acdad..5271911e197 100644 --- a/tasks/seq/nasedkin_e_strassen_algorithm/func_tests/main.cpp +++ b/tasks/seq/nasedkin_e_strassen_algorithm/func_tests/main.cpp @@ -17,6 +17,64 @@ std::vector generateRandomMatrix(int size) { return matrix; } +TEST(nasedkin_e_strassen_algorithm_seq, Test_InvalidInputSize) { + int matrixSizeA = 32; + int matrixSizeB = 64; + + std::vector matrixA = generateRandomMatrix(matrixSizeA); + std::vector matrixB = generateRandomMatrix(matrixSizeB); + std::vector resultSeq(matrixSizeA * matrixSizeA, 0.0); + + std::shared_ptr taskDataSeq = std::make_shared(); + + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testSeqTask(taskDataSeq); + ASSERT_FALSE(testSeqTask.validation()); +} + +TEST(nasedkin_e_strassen_algorithm_seq, Test_IdentityMatrix) { + int matrixSize = 16; + std::vector matrixA(matrixSize * matrixSize, 0.0); + std::vector matrixB(matrixSize * matrixSize, 0.0); + std::vector resultSeq(matrixSize * matrixSize, 0.0); + + for (int i = 0; i < matrixSize; ++i) { + matrixA[i * matrixSize + i] = 1.0; + matrixB[i * matrixSize + i] = 1.0; + } + + std::shared_ptr taskDataSeq = std::make_shared(); + + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testSeqTask(taskDataSeq); + ASSERT_TRUE(testSeqTask.validation()); + ASSERT_TRUE(testSeqTask.pre_processing()); + ASSERT_TRUE(testSeqTask.run()); + ASSERT_TRUE(testSeqTask.post_processing()); + + for (int i = 0; i < matrixSize; ++i) { + for (int j = 0; j < matrixSize; ++j) { + if (i == j) { + ASSERT_NEAR(resultSeq[i * matrixSize + j], 1.0, 1e-9); + } else { + ASSERT_NEAR(resultSeq[i * matrixSize + j], 0.0, 1e-9); + } + } + } +} + TEST(nasedkin_e_strassen_algorithm_seq, Test_2x2) { int matrixSize = 2; std::vector matrixA = generateRandomMatrix(matrixSize); From 3e4066f2686c5248ee4ac53eb9d863ebbd4bc356 Mon Sep 17 00:00:00 2001 From: myffii <132840123+myffii@users.noreply.github.com> Date: Sun, 29 Dec 2024 06:30:07 +0300 Subject: [PATCH 8/8] Padding --- .../func_tests/main.cpp | 195 +++++++++++++++++- .../include/ops_mpi.hpp | 2 + .../src/ops_mpi.cpp | 60 +++++- .../func_tests/main.cpp | 88 ++++++++ .../include/ops_seq.hpp | 3 + .../src/ops_seq.cpp | 33 ++- 6 files changed, 365 insertions(+), 16 deletions(-) diff --git a/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp b/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp index 2444dfd9f9c..1eadabbc1fa 100644 --- a/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp +++ b/tasks/mpi/nasedkin_e_strassen_algorithm/func_tests/main.cpp @@ -123,6 +123,54 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_2x2) { ASSERT_EQ(resultSeq, resultParallel); } +TEST(nasedkin_e_strassen_algorithm_mpi, Test_3x3) { + boost::mpi::communicator world; + + int matrixSize = 3; + std::vector matrixA; + std::vector matrixB; + if (world.rank() == 0) { + matrixA = generateRandomMatrix(matrixSize); + matrixB = generateRandomMatrix(matrixSize); + } + std::vector resultParallel(matrixSize * matrixSize, 0.0); + std::vector resultSeq(matrixSize * matrixSize, 0.0); + + std::shared_ptr taskDataSeq = std::make_shared(); + + if (world.rank() == 0) { + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); + ASSERT_TRUE(testMpiTaskSeq.validation()); + ASSERT_TRUE(testMpiTaskSeq.pre_processing()); + ASSERT_TRUE(testMpiTaskSeq.run()); + ASSERT_TRUE(testMpiTaskSeq.post_processing()); + } + + std::shared_ptr taskDataParallel = std::make_shared(); + + if (world.rank() == 0) { + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataParallel->inputs_count.emplace_back(matrixA.size()); + taskDataParallel->inputs_count.emplace_back(matrixB.size()); + taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); + taskDataParallel->outputs_count.emplace_back(resultParallel.size()); + } + nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); + ASSERT_TRUE(testMpiTaskParallel.validation()); + ASSERT_TRUE(testMpiTaskParallel.pre_processing()); + ASSERT_TRUE(testMpiTaskParallel.run()); + ASSERT_TRUE(testMpiTaskParallel.post_processing()); + ASSERT_EQ(resultSeq, resultParallel); +} + TEST(nasedkin_e_strassen_algorithm_mpi, Test_4x4) { boost::mpi::communicator world; @@ -172,6 +220,54 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_4x4) { ASSERT_EQ(resultSeq, resultParallel); } +TEST(nasedkin_e_strassen_algorithm_mpi, Test_7x7) { + boost::mpi::communicator world; + + int matrixSize = 7; + std::vector matrixA; + std::vector matrixB; + if (world.rank() == 0) { + matrixA = generateRandomMatrix(matrixSize); + matrixB = generateRandomMatrix(matrixSize); + } + std::vector resultParallel(matrixSize * matrixSize, 0.0); + std::vector resultSeq(matrixSize * matrixSize, 0.0); + + std::shared_ptr taskDataSeq = std::make_shared(); + + if (world.rank() == 0) { + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); + ASSERT_TRUE(testMpiTaskSeq.validation()); + ASSERT_TRUE(testMpiTaskSeq.pre_processing()); + ASSERT_TRUE(testMpiTaskSeq.run()); + ASSERT_TRUE(testMpiTaskSeq.post_processing()); + } + + std::shared_ptr taskDataParallel = std::make_shared(); + + if (world.rank() == 0) { + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataParallel->inputs_count.emplace_back(matrixA.size()); + taskDataParallel->inputs_count.emplace_back(matrixB.size()); + taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); + taskDataParallel->outputs_count.emplace_back(resultParallel.size()); + } + nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); + ASSERT_TRUE(testMpiTaskParallel.validation()); + ASSERT_TRUE(testMpiTaskParallel.pre_processing()); + ASSERT_TRUE(testMpiTaskParallel.run()); + ASSERT_TRUE(testMpiTaskParallel.post_processing()); + ASSERT_EQ(resultSeq, resultParallel); +} + TEST(nasedkin_e_strassen_algorithm_mpi, Test_8x8) { boost::mpi::communicator world; @@ -221,6 +317,54 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_8x8) { ASSERT_EQ(resultSeq, resultParallel); } +TEST(nasedkin_e_strassen_algorithm_mpi, Test_10x10) { + boost::mpi::communicator world; + + int matrixSize = 10; + std::vector matrixA; + std::vector matrixB; + if (world.rank() == 0) { + matrixA = generateRandomMatrix(matrixSize); + matrixB = generateRandomMatrix(matrixSize); + } + std::vector resultParallel(matrixSize * matrixSize, 0.0); + std::vector resultSeq(matrixSize * matrixSize, 0.0); + + std::shared_ptr taskDataSeq = std::make_shared(); + + if (world.rank() == 0) { + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); + ASSERT_TRUE(testMpiTaskSeq.validation()); + ASSERT_TRUE(testMpiTaskSeq.pre_processing()); + ASSERT_TRUE(testMpiTaskSeq.run()); + ASSERT_TRUE(testMpiTaskSeq.post_processing()); + } + + std::shared_ptr taskDataParallel = std::make_shared(); + + if (world.rank() == 0) { + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataParallel->inputs_count.emplace_back(matrixA.size()); + taskDataParallel->inputs_count.emplace_back(matrixB.size()); + taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); + taskDataParallel->outputs_count.emplace_back(resultParallel.size()); + } + nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); + ASSERT_TRUE(testMpiTaskParallel.validation()); + ASSERT_TRUE(testMpiTaskParallel.pre_processing()); + ASSERT_TRUE(testMpiTaskParallel.run()); + ASSERT_TRUE(testMpiTaskParallel.post_processing()); + ASSERT_EQ(resultSeq, resultParallel); +} + TEST(nasedkin_e_strassen_algorithm_mpi, Test_16x16) { boost::mpi::communicator world; @@ -270,6 +414,55 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_16x16) { ASSERT_EQ(resultSeq, resultParallel); } +TEST(nasedkin_e_strassen_algorithm_mpi, Test_17x17) { + boost::mpi::communicator world; + + int matrixSize = 17; + std::vector matrixA; + std::vector matrixB; + if (world.rank() == 0) { + matrixA = generateRandomMatrix(matrixSize); + matrixB = generateRandomMatrix(matrixSize); + } + std::vector resultParallel(matrixSize * matrixSize, 0.0); + std::vector resultSeq(matrixSize * matrixSize, 0.0); + + std::shared_ptr taskDataSeq = std::make_shared(); + + if (world.rank() == 0) { + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testMpiTaskSeq(taskDataSeq); + ASSERT_TRUE(testMpiTaskSeq.validation()); + ASSERT_TRUE(testMpiTaskSeq.pre_processing()); + ASSERT_TRUE(testMpiTaskSeq.run()); + ASSERT_TRUE(testMpiTaskSeq.post_processing()); + } + + std::shared_ptr taskDataParallel = std::make_shared(); + + if (world.rank() == 0) { + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataParallel->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataParallel->inputs_count.emplace_back(matrixA.size()); + taskDataParallel->inputs_count.emplace_back(matrixB.size()); + taskDataParallel->outputs.emplace_back(reinterpret_cast(resultParallel.data())); + taskDataParallel->outputs_count.emplace_back(resultParallel.size()); + } + nasedkin_e_strassen_algorithm::StrassenAlgorithmMPI testMpiTaskParallel(taskDataParallel); + ASSERT_TRUE(testMpiTaskParallel.validation()); + ASSERT_TRUE(testMpiTaskParallel.pre_processing()); + ASSERT_TRUE(testMpiTaskParallel.run()); + ASSERT_TRUE(testMpiTaskParallel.post_processing()); + + ASSERT_EQ(resultSeq, resultParallel); +} + TEST(nasedkin_e_strassen_algorithm_mpi, Test_32x32) { boost::mpi::communicator world; @@ -317,4 +510,4 @@ TEST(nasedkin_e_strassen_algorithm_mpi, Test_32x32) { ASSERT_TRUE(testMpiTaskParallel.post_processing()); ASSERT_EQ(resultSeq, resultParallel); -} \ No newline at end of file +} diff --git a/tasks/mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp b/tasks/mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp index 0ac0fcb864b..907194a3104 100644 --- a/tasks/mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp +++ b/tasks/mpi/nasedkin_e_strassen_algorithm/include/ops_mpi.hpp @@ -56,4 +56,6 @@ std::vector strassen_recursive(const std::vector& matrixA, const std::vector matrix_add(const std::vector& matrixA, const std::vector& matrixB, size_t size); std::vector matrix_subtract(const std::vector& matrixA, const std::vector& matrixB, size_t size); +size_t nextPowerOfTwo(size_t n); +std::vector padMatrix(const std::vector& matrix, size_t originalSize, size_t newSize); } // namespace nasedkin_e_strassen_algorithm \ No newline at end of file diff --git a/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp b/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp index dc2bd61dd1d..163a961a261 100644 --- a/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp +++ b/tasks/mpi/nasedkin_e_strassen_algorithm/src/ops_mpi.cpp @@ -17,9 +17,11 @@ bool StrassenAlgorithmSEQ::pre_processing() { auto* inputsA = reinterpret_cast(taskData->inputs[0]); auto* inputsB = reinterpret_cast(taskData->inputs[1]); matrixSize = static_cast(std::sqrt(taskData->inputs_count[0])); - inputMatrixA.assign(inputsA, inputsA + matrixSize * matrixSize); - inputMatrixB.assign(inputsB, inputsB + matrixSize * matrixSize); - outputMatrix.resize(matrixSize * matrixSize, 0.0); + size_t newSize = nextPowerOfTwo(matrixSize); + inputMatrixA = padMatrix(std::vector(inputsA, inputsA + matrixSize * matrixSize), matrixSize, newSize); + inputMatrixB = padMatrix(std::vector(inputsB, inputsB + matrixSize * matrixSize), matrixSize, newSize); + outputMatrix.resize(newSize * newSize, 0.0); + matrixSize = newSize; return true; } @@ -46,7 +48,12 @@ bool StrassenAlgorithmSEQ::run() { bool StrassenAlgorithmSEQ::post_processing() { internal_order_test(); auto* outputs = reinterpret_cast(taskData->outputs[0]); - std::copy(outputMatrix.begin(), outputMatrix.end(), outputs); + auto originalSize = static_cast(std::sqrt(taskData->outputs_count[0])); + for (size_t i = 0; i < originalSize; ++i) { + for (size_t j = 0; j < originalSize; ++j) { + outputs[i * originalSize + j] = outputMatrix[i * matrixSize + j]; + } + } return true; } @@ -67,10 +74,22 @@ bool StrassenAlgorithmMPI::pre_processing() { return false; } - inputMatrixA.assign(inputsA, inputsA + matrixSize * matrixSize); - inputMatrixB.assign(inputsB, inputsB + matrixSize * matrixSize); + size_t newSize = nextPowerOfTwo(matrixSize); + inputMatrixA = padMatrix(std::vector(inputsA, inputsA + matrixSize * matrixSize), matrixSize, newSize); + inputMatrixB = padMatrix(std::vector(inputsB, inputsB + matrixSize * matrixSize), matrixSize, newSize); + outputMatrix.resize(newSize * newSize, 0.0); + matrixSize = newSize; + } + + boost::mpi::broadcast(world, matrixSize, 0); + if (rank != 0) { + inputMatrixA.resize(matrixSize * matrixSize); + inputMatrixB.resize(matrixSize * matrixSize); outputMatrix.resize(matrixSize * matrixSize, 0.0); } + boost::mpi::broadcast(world, inputMatrixA, 0); + boost::mpi::broadcast(world, inputMatrixB, 0); + return true; } @@ -93,9 +112,6 @@ bool StrassenAlgorithmMPI::validation() { bool StrassenAlgorithmMPI::run() { internal_order_test(); - boost::mpi::broadcast(world, inputMatrixA, 0); - boost::mpi::broadcast(world, inputMatrixB, 0); - boost::mpi::broadcast(world, matrixSize, 0); outputMatrix = strassen_multiply(inputMatrixA, inputMatrixB, matrixSize); return true; } @@ -105,7 +121,12 @@ bool StrassenAlgorithmMPI::post_processing() { int rank = world.rank(); if (rank == 0) { auto* outputs = reinterpret_cast(taskData->outputs[0]); - std::copy(outputMatrix.begin(), outputMatrix.end(), outputs); + auto originalSize = static_cast(std::sqrt(taskData->outputs_count[0])); + for (size_t i = 0; i < originalSize; ++i) { + for (size_t j = 0; j < originalSize; ++j) { + outputs[i * originalSize + j] = outputMatrix[i * matrixSize + j]; + } + } } return true; } @@ -127,6 +148,24 @@ std::vector matrix_subtract(const std::vector& matrixA, const st return result; } +size_t nextPowerOfTwo(size_t n) { + size_t power = 1; + while (power < n) { + power *= 2; + } + return power; +} + +std::vector padMatrix(const std::vector& matrix, size_t originalSize, size_t newSize) { + std::vector padded(newSize * newSize, 0.0); + for (size_t i = 0; i < originalSize; ++i) { + for (size_t j = 0; j < originalSize; ++j) { + padded[i * newSize + j] = matrix[i * originalSize + j]; + } + } + return padded; +} + std::vector strassen_recursive(const std::vector& matrixA, const std::vector& matrixB, size_t size) { if (size == 1) { @@ -265,7 +304,6 @@ std::vector StrassenAlgorithmSEQ::strassen_multiply_seq(const std::vecto } } return result; - return {}; } std::vector StrassenAlgorithmMPI::strassen_multiply(const std::vector& matrixA, diff --git a/tasks/seq/nasedkin_e_strassen_algorithm/func_tests/main.cpp b/tasks/seq/nasedkin_e_strassen_algorithm/func_tests/main.cpp index 5271911e197..06460ee8102 100644 --- a/tasks/seq/nasedkin_e_strassen_algorithm/func_tests/main.cpp +++ b/tasks/seq/nasedkin_e_strassen_algorithm/func_tests/main.cpp @@ -97,6 +97,28 @@ TEST(nasedkin_e_strassen_algorithm_seq, Test_2x2) { ASSERT_TRUE(testSeqTask.post_processing()); } +TEST(nasedkin_e_strassen_algorithm_seq, Test_3x3) { + int matrixSize = 3; + std::vector matrixA = generateRandomMatrix(matrixSize); + std::vector matrixB = generateRandomMatrix(matrixSize); + std::vector resultSeq(matrixSize * matrixSize, 0.0); + + std::shared_ptr taskDataSeq = std::make_shared(); + + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testSeqTask(taskDataSeq); + ASSERT_TRUE(testSeqTask.validation()); + ASSERT_TRUE(testSeqTask.pre_processing()); + ASSERT_TRUE(testSeqTask.run()); + ASSERT_TRUE(testSeqTask.post_processing()); +} + TEST(nasedkin_e_strassen_algorithm_seq, Test_4x4) { int matrixSize = 4; std::vector matrixA = generateRandomMatrix(matrixSize); @@ -119,6 +141,28 @@ TEST(nasedkin_e_strassen_algorithm_seq, Test_4x4) { ASSERT_TRUE(testSeqTask.post_processing()); } +TEST(nasedkin_e_strassen_algorithm_seq, Test_7x7) { + int matrixSize = 7; + std::vector matrixA = generateRandomMatrix(matrixSize); + std::vector matrixB = generateRandomMatrix(matrixSize); + std::vector resultSeq(matrixSize * matrixSize, 0.0); + + std::shared_ptr taskDataSeq = std::make_shared(); + + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testSeqTask(taskDataSeq); + ASSERT_TRUE(testSeqTask.validation()); + ASSERT_TRUE(testSeqTask.pre_processing()); + ASSERT_TRUE(testSeqTask.run()); + ASSERT_TRUE(testSeqTask.post_processing()); +} + TEST(nasedkin_e_strassen_algorithm_seq, Test_8x8) { int matrixSize = 8; std::vector matrixA = generateRandomMatrix(matrixSize); @@ -141,6 +185,28 @@ TEST(nasedkin_e_strassen_algorithm_seq, Test_8x8) { ASSERT_TRUE(testSeqTask.post_processing()); } +TEST(nasedkin_e_strassen_algorithm_seq, Test_10x10) { + int matrixSize = 10; + std::vector matrixA = generateRandomMatrix(matrixSize); + std::vector matrixB = generateRandomMatrix(matrixSize); + std::vector resultSeq(matrixSize * matrixSize, 0.0); + + std::shared_ptr taskDataSeq = std::make_shared(); + + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testSeqTask(taskDataSeq); + ASSERT_TRUE(testSeqTask.validation()); + ASSERT_TRUE(testSeqTask.pre_processing()); + ASSERT_TRUE(testSeqTask.run()); + ASSERT_TRUE(testSeqTask.post_processing()); +} + TEST(nasedkin_e_strassen_algorithm_seq, Test_16x16) { int matrixSize = 16; std::vector matrixA = generateRandomMatrix(matrixSize); @@ -163,6 +229,28 @@ TEST(nasedkin_e_strassen_algorithm_seq, Test_16x16) { ASSERT_TRUE(testSeqTask.post_processing()); } +TEST(nasedkin_e_strassen_algorithm_seq, Test_17x17) { + int matrixSize = 17; + std::vector matrixA = generateRandomMatrix(matrixSize); + std::vector matrixB = generateRandomMatrix(matrixSize); + std::vector resultSeq(matrixSize * matrixSize, 0.0); + + std::shared_ptr taskDataSeq = std::make_shared(); + + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixA.data())); + taskDataSeq->inputs.emplace_back(reinterpret_cast(matrixB.data())); + taskDataSeq->inputs_count.emplace_back(matrixA.size()); + taskDataSeq->inputs_count.emplace_back(matrixB.size()); + taskDataSeq->outputs.emplace_back(reinterpret_cast(resultSeq.data())); + taskDataSeq->outputs_count.emplace_back(resultSeq.size()); + + nasedkin_e_strassen_algorithm::StrassenAlgorithmSEQ testSeqTask(taskDataSeq); + ASSERT_TRUE(testSeqTask.validation()); + ASSERT_TRUE(testSeqTask.pre_processing()); + ASSERT_TRUE(testSeqTask.run()); + ASSERT_TRUE(testSeqTask.post_processing()); +} + TEST(nasedkin_e_strassen_algorithm_seq, Test_32x32) { int matrixSize = 32; std::vector matrixA = generateRandomMatrix(matrixSize); diff --git a/tasks/seq/nasedkin_e_strassen_algorithm/include/ops_seq.hpp b/tasks/seq/nasedkin_e_strassen_algorithm/include/ops_seq.hpp index 128ecfbdb6a..5cd43c468c9 100644 --- a/tasks/seq/nasedkin_e_strassen_algorithm/include/ops_seq.hpp +++ b/tasks/seq/nasedkin_e_strassen_algorithm/include/ops_seq.hpp @@ -34,4 +34,7 @@ std::vector strassen_recursive(const std::vector& matrixA, const std::vector matrix_add(const std::vector& matrixA, const std::vector& matrixB, size_t size); std::vector matrix_subtract(const std::vector& matrixA, const std::vector& matrixB, size_t size); + +size_t nextPowerOfTwo(size_t n); +std::vector padMatrix(const std::vector& matrix, size_t originalSize, size_t newSize); } // namespace nasedkin_e_strassen_algorithm \ No newline at end of file diff --git a/tasks/seq/nasedkin_e_strassen_algorithm/src/ops_seq.cpp b/tasks/seq/nasedkin_e_strassen_algorithm/src/ops_seq.cpp index 78c01610123..a914e0fe982 100644 --- a/tasks/seq/nasedkin_e_strassen_algorithm/src/ops_seq.cpp +++ b/tasks/seq/nasedkin_e_strassen_algorithm/src/ops_seq.cpp @@ -24,9 +24,11 @@ bool StrassenAlgorithmSEQ::pre_processing() { return false; } - inputMatrixA.assign(inputsA, inputsA + matrixSize * matrixSize); - inputMatrixB.assign(inputsB, inputsB + matrixSize * matrixSize); - outputMatrix.resize(matrixSize * matrixSize, 0.0); + size_t newSize = nextPowerOfTwo(matrixSize); + inputMatrixA = padMatrix(std::vector(inputsA, inputsA + matrixSize * matrixSize), matrixSize, newSize); + inputMatrixB = padMatrix(std::vector(inputsB, inputsB + matrixSize * matrixSize), matrixSize, newSize); + outputMatrix.resize(newSize * newSize, 0.0); + matrixSize = newSize; return true; } @@ -50,7 +52,12 @@ bool StrassenAlgorithmSEQ::run() { bool StrassenAlgorithmSEQ::post_processing() { internal_order_test(); auto* outputs = reinterpret_cast(taskData->outputs[0]); - std::copy(outputMatrix.begin(), outputMatrix.end(), outputs); + auto originalSize = static_cast(std::sqrt(taskData->outputs_count[0])); + for (size_t i = 0; i < originalSize; ++i) { + for (size_t j = 0; j < originalSize; ++j) { + outputs[i * originalSize + j] = outputMatrix[i * matrixSize + j]; + } + } return true; } @@ -71,6 +78,24 @@ std::vector matrix_subtract(const std::vector& matrixA, const st return result; } +size_t nextPowerOfTwo(size_t n) { + size_t power = 1; + while (power < n) { + power *= 2; + } + return power; +} + +std::vector padMatrix(const std::vector& matrix, size_t originalSize, size_t newSize) { + std::vector padded(newSize * newSize, 0.0); + for (size_t i = 0; i < originalSize; ++i) { + for (size_t j = 0; j < originalSize; ++j) { + padded[i * newSize + j] = matrix[i * originalSize + j]; + } + } + return padded; +} + std::vector strassen_recursive(const std::vector& matrixA, const std::vector& matrixB, size_t size) { if (size == 1) {