generated from learning-process/parallel_programming_course
-
Notifications
You must be signed in to change notification settings - Fork 169
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Сдобнов Владимир Задача 3. Вариант 15. Четно-нечетная сортировка слия…
…нием Бетчера (#783) Входные данные: Для последовательного алгоритма: вектор и его размер равный степени двойки Для параллельного: вектор и его размер Описание параллельного алгоритма: Делим вектор между потоками. Каждый поток сортирует свои данные, после чего данные из потоков сливаются. Процесс слияния: Процесс получает данные от следующего за ним процесса, объединяет их со своими и сортирует, затем возвращает вторую половину полученного вектора обратно. Пары выбираются поочередно, сначала (0,1), (2,3), (4,5) и тд, затем (1,2), (3,4), (5,6). Число слияний равно числу потоков. После прохождения слияний все данные собираются в 0 потоке.
- Loading branch information
1 parent
1c4a7af
commit 27135fa
Showing
8 changed files
with
860 additions
and
0 deletions.
There are no files selected for viewing
217 changes: 217 additions & 0 deletions
217
tasks/mpi/Sdobnov_V_mergesort_Betcher/func_tests/main.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
#include <gtest/gtest.h> | ||
|
||
#include <boost/mpi/communicator.hpp> | ||
#include <boost/mpi/environment.hpp> | ||
#include <vector> | ||
|
||
#include "mpi/Sdobnov_V_mergesort_Betcher/include/ops_mpi.hpp" | ||
|
||
TEST(Sdobnov_V_mergesort_Betcher_par, InvalidInputCount) { | ||
boost::mpi::communicator world; | ||
|
||
int size = 10; | ||
std::vector<int> res(size, 0); | ||
std::vector<int> input = {2, 1, 0, 3, 9, 7, 2, 6, 4, 8}; | ||
std::vector<int> expected_res = {0, 1, 2, 2, 3, 4, 6, 7, 8, 9}; | ||
|
||
std::shared_ptr<ppc::core::TaskData> taskDataPar = std::make_shared<ppc::core::TaskData>(); | ||
if (world.rank() == 0) { | ||
taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t *>(input.data())); | ||
taskDataPar->outputs_count.emplace_back(size); | ||
taskDataPar->outputs.emplace_back(reinterpret_cast<uint8_t *>(res.data())); | ||
} | ||
|
||
Sdobnov_V_mergesort_Betcher_par::MergesortBetcherPar test(taskDataPar); | ||
if (world.rank() == 0) { | ||
ASSERT_FALSE(test.validation()); | ||
} | ||
} | ||
|
||
TEST(Sdobnov_V_mergesort_Betcher_par, InvalidInput) { | ||
boost::mpi::communicator world; | ||
|
||
int size = 10; | ||
std::vector<int> res(size, 0); | ||
std::vector<int> input = {2, 1, 0, 3, 9, 7, 2, 6, 4, 8}; | ||
std::vector<int> expected_res = {0, 1, 2, 2, 3, 4, 6, 7, 8, 9}; | ||
|
||
std::shared_ptr<ppc::core::TaskData> taskDataPar = std::make_shared<ppc::core::TaskData>(); | ||
if (world.rank() == 0) { | ||
taskDataPar->inputs_count.emplace_back(size); | ||
taskDataPar->outputs_count.emplace_back(size); | ||
taskDataPar->outputs.emplace_back(reinterpret_cast<uint8_t *>(res.data())); | ||
} | ||
|
||
Sdobnov_V_mergesort_Betcher_par::MergesortBetcherPar test(taskDataPar); | ||
|
||
if (world.rank() == 0) { | ||
ASSERT_FALSE(test.validation()); | ||
} | ||
} | ||
|
||
TEST(Sdobnov_V_mergesort_Betcher_par, InvalidOutputCount) { | ||
boost::mpi::communicator world; | ||
|
||
int size = 10; | ||
std::vector<int> res(size, 0); | ||
std::vector<int> input = {2, 1, 0, 3, 9, 7, 2, 6, 4, 8}; | ||
std::vector<int> expected_res = {0, 1, 2, 2, 3, 4, 6, 7, 8, 9}; | ||
|
||
std::shared_ptr<ppc::core::TaskData> taskDataPar = std::make_shared<ppc::core::TaskData>(); | ||
|
||
if (world.rank() == 0) { | ||
taskDataPar->inputs_count.emplace_back(size); | ||
taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t *>(input.data())); | ||
taskDataPar->outputs.emplace_back(reinterpret_cast<uint8_t *>(res.data())); | ||
} | ||
|
||
Sdobnov_V_mergesort_Betcher_par::MergesortBetcherPar test(taskDataPar); | ||
|
||
if (world.rank() == 0) { | ||
ASSERT_FALSE(test.validation()); | ||
} | ||
} | ||
|
||
TEST(Sdobnov_V_mergesort_Betcher_par, InvalidOutput) { | ||
boost::mpi::communicator world; | ||
|
||
int size = 10; | ||
std::vector<int> res(size, 0); | ||
std::vector<int> input = {2, 1, 0, 3, 9, 7, 2, 6, 4, 8}; | ||
std::vector<int> expected_res = {0, 1, 2, 2, 3, 4, 6, 7, 8, 9}; | ||
|
||
std::shared_ptr<ppc::core::TaskData> taskDataPar = std::make_shared<ppc::core::TaskData>(); | ||
if (world.rank() == 0) { | ||
taskDataPar->inputs_count.emplace_back(size); | ||
taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t *>(input.data())); | ||
taskDataPar->outputs_count.emplace_back(size); | ||
} | ||
|
||
Sdobnov_V_mergesort_Betcher_par::MergesortBetcherPar test(taskDataPar); | ||
|
||
if (world.rank() == 0) { | ||
ASSERT_FALSE(test.validation()); | ||
} | ||
} | ||
|
||
TEST(Sdobnov_V_mergesort_Betcher_par, SortTest8) { | ||
boost::mpi::communicator world; | ||
|
||
int size = 8; | ||
std::vector<int> res(size, 0); | ||
std::vector<int> input = {2, 8, 3, 9, 5, 6, 4, 0}; | ||
std::vector<int> expected_res = {0, 2, 3, 4, 5, 6, 8, 9}; | ||
std::shared_ptr<ppc::core::TaskData> taskDataPar = std::make_shared<ppc::core::TaskData>(); | ||
|
||
if (world.rank() == 0) { | ||
taskDataPar->inputs_count.emplace_back(size); | ||
taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t *>(input.data())); | ||
taskDataPar->outputs_count.emplace_back(size); | ||
taskDataPar->outputs.emplace_back(reinterpret_cast<uint8_t *>(res.data())); | ||
} | ||
|
||
Sdobnov_V_mergesort_Betcher_par::MergesortBetcherPar test(taskDataPar); | ||
test.validation(); | ||
test.pre_processing(); | ||
test.run(); | ||
test.post_processing(); | ||
|
||
if (world.rank() == 0) { | ||
for (int i = 0; i < size; i++) { | ||
ASSERT_EQ(res[i], expected_res[i]); | ||
} | ||
} | ||
} | ||
|
||
TEST(Sdobnov_V_mergesort_Betcher_par, SortTestRand16) { | ||
boost::mpi::communicator world; | ||
|
||
int size = 16; | ||
std::vector<int> res(size, 0); | ||
std::vector<int> input = Sdobnov_V_mergesort_Betcher_par::generate_random_vector(size, 0, 1000); | ||
|
||
std::shared_ptr<ppc::core::TaskData> taskDataPar = std::make_shared<ppc::core::TaskData>(); | ||
|
||
if (world.rank() == 0) { | ||
taskDataPar->inputs_count.emplace_back(size); | ||
taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t *>(input.data())); | ||
taskDataPar->outputs_count.emplace_back(size); | ||
taskDataPar->outputs.emplace_back(reinterpret_cast<uint8_t *>(res.data())); | ||
} | ||
|
||
Sdobnov_V_mergesort_Betcher_par::MergesortBetcherPar test(taskDataPar); | ||
test.validation(); | ||
test.pre_processing(); | ||
test.run(); | ||
test.post_processing(); | ||
|
||
if (world.rank() == 0) { | ||
std::vector<int> expected_res = input; | ||
std::sort(expected_res.begin(), expected_res.end()); | ||
for (int i = 0; i < size; i++) { | ||
ASSERT_EQ(res[i], expected_res[i]); | ||
} | ||
} | ||
} | ||
|
||
TEST(Sdobnov_V_mergesort_Betcher_par, SortTestRand32) { | ||
boost::mpi::communicator world; | ||
|
||
int size = 32; | ||
std::vector<int> res(size, 0); | ||
std::vector<int> input = Sdobnov_V_mergesort_Betcher_par::generate_random_vector(size, 0, 1000); | ||
|
||
std::shared_ptr<ppc::core::TaskData> taskDataPar = std::make_shared<ppc::core::TaskData>(); | ||
|
||
if (world.rank() == 0) { | ||
taskDataPar->inputs_count.emplace_back(size); | ||
taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t *>(input.data())); | ||
taskDataPar->outputs_count.emplace_back(size); | ||
taskDataPar->outputs.emplace_back(reinterpret_cast<uint8_t *>(res.data())); | ||
} | ||
|
||
Sdobnov_V_mergesort_Betcher_par::MergesortBetcherPar test(taskDataPar); | ||
test.validation(); | ||
test.pre_processing(); | ||
test.run(); | ||
test.post_processing(); | ||
|
||
if (world.rank() == 0) { | ||
std::vector<int> expected_res = input; | ||
std::sort(expected_res.begin(), expected_res.end()); | ||
for (int i = 0; i < size; i++) { | ||
ASSERT_EQ(res[i], expected_res[i]); | ||
} | ||
} | ||
} | ||
|
||
TEST(Sdobnov_V_mergesort_Betcher_par, SortTestRand64) { | ||
boost::mpi::communicator world; | ||
|
||
int size = 64; | ||
std::vector<int> res(size, 0); | ||
std::vector<int> input = Sdobnov_V_mergesort_Betcher_par::generate_random_vector(size, 0, 1000); | ||
|
||
std::shared_ptr<ppc::core::TaskData> taskDataPar = std::make_shared<ppc::core::TaskData>(); | ||
|
||
if (world.rank() == 0) { | ||
taskDataPar->inputs_count.emplace_back(size); | ||
taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t *>(input.data())); | ||
taskDataPar->outputs_count.emplace_back(size); | ||
taskDataPar->outputs.emplace_back(reinterpret_cast<uint8_t *>(res.data())); | ||
} | ||
|
||
Sdobnov_V_mergesort_Betcher_par::MergesortBetcherPar test(taskDataPar); | ||
test.validation(); | ||
test.pre_processing(); | ||
test.run(); | ||
test.post_processing(); | ||
|
||
if (world.rank() == 0) { | ||
std::vector<int> expected_res = input; | ||
std::sort(expected_res.begin(), expected_res.end()); | ||
for (int i = 0; i < size; i++) { | ||
ASSERT_EQ(res[i], expected_res[i]); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Copyright 2024 Sdobnov Vladimir | ||
#pragma once | ||
#include <gtest/gtest.h> | ||
|
||
#include <boost/mpi/collectives.hpp> | ||
#include <boost/mpi/communicator.hpp> | ||
#include <vector> | ||
|
||
#include "core/task/include/task.hpp" | ||
|
||
namespace Sdobnov_V_mergesort_Betcher_par { | ||
|
||
std::vector<int> generate_random_vector(int size, int lower_bound = 0, int upper_bound = 50); | ||
int partition(std::vector<int>& vec, int low, int high); | ||
void quickSortIterative(std::vector<int>& vec, int low, int high); | ||
|
||
class MergesortBetcherPar : public ppc::core::Task { | ||
public: | ||
explicit MergesortBetcherPar(std::shared_ptr<ppc::core::TaskData> taskData_) : Task(std::move(taskData_)) {} | ||
bool pre_processing() override; | ||
bool validation() override; | ||
bool run() override; | ||
bool post_processing() override; | ||
|
||
private: | ||
std::vector<int> input_; | ||
int size_; | ||
std::vector<int> local_vec_; | ||
|
||
boost::mpi::communicator world; | ||
}; | ||
} // namespace Sdobnov_V_mergesort_Betcher_par |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
#include <gtest/gtest.h> | ||
|
||
#include <boost/mpi/timer.hpp> | ||
#include <random> | ||
#include <vector> | ||
|
||
#include "core/perf/include/perf.hpp" | ||
#include "mpi/Sdobnov_V_mergesort_Betcher/include/ops_mpi.hpp" | ||
|
||
TEST(Sdobnov_V_mergesort_Betcher_par, test_pipeline_run) { | ||
boost::mpi::communicator world; | ||
|
||
long unsigned int size = 4096; | ||
std::vector<int> res(size, 0); | ||
std::vector<int> input = Sdobnov_V_mergesort_Betcher_par::generate_random_vector(size, 0, 1000); | ||
|
||
std::shared_ptr<ppc::core::TaskData> taskDataPar = std::make_shared<ppc::core::TaskData>(); | ||
if (world.rank() == 0) { | ||
taskDataPar->inputs_count.emplace_back(size); | ||
taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t *>(input.data())); | ||
taskDataPar->outputs_count.emplace_back(size); | ||
taskDataPar->outputs.emplace_back(reinterpret_cast<uint8_t *>(res.data())); | ||
} | ||
|
||
auto test = std::make_shared<Sdobnov_V_mergesort_Betcher_par::MergesortBetcherPar>(taskDataPar); | ||
test->validation(); | ||
test->pre_processing(); | ||
test->run(); | ||
test->post_processing(); | ||
|
||
auto perfAttr = std::make_shared<ppc::core::PerfAttr>(); | ||
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<std::chrono::nanoseconds>(current_time_point - t0).count(); | ||
return static_cast<double>(duration) * 1e-9; | ||
}; | ||
auto perfResults = std::make_shared<ppc::core::PerfResults>(); | ||
auto perfAnalyzer = std::make_shared<ppc::core::Perf>(test); | ||
perfAnalyzer->pipeline_run(perfAttr, perfResults); | ||
ppc::core::Perf::print_perf_statistic(perfResults); | ||
|
||
if (world.rank() == 0) { | ||
ASSERT_EQ(res.size(), size); | ||
} | ||
} | ||
|
||
TEST(Sdobnov_V_mergesort_Betcher_par, test_task_run) { | ||
boost::mpi::communicator world; | ||
|
||
long unsigned int size = 4096; | ||
std::vector<int> res(size, 0); | ||
std::vector<int> input = Sdobnov_V_mergesort_Betcher_par::generate_random_vector(size, 0, 1000); | ||
|
||
std::shared_ptr<ppc::core::TaskData> taskDataPar = std::make_shared<ppc::core::TaskData>(); | ||
|
||
if (world.rank() == 0) { | ||
taskDataPar->inputs_count.emplace_back(size); | ||
taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t *>(input.data())); | ||
taskDataPar->outputs_count.emplace_back(size); | ||
taskDataPar->outputs.emplace_back(reinterpret_cast<uint8_t *>(res.data())); | ||
} | ||
|
||
auto test = std::make_shared<Sdobnov_V_mergesort_Betcher_par::MergesortBetcherPar>(taskDataPar); | ||
test->validation(); | ||
test->pre_processing(); | ||
test->run(); | ||
test->post_processing(); | ||
|
||
auto perfAttr = std::make_shared<ppc::core::PerfAttr>(); | ||
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<std::chrono::nanoseconds>(current_time_point - t0).count(); | ||
return static_cast<double>(duration) * 1e-9; | ||
}; | ||
auto perfResults = std::make_shared<ppc::core::PerfResults>(); | ||
auto perfAnalyzer = std::make_shared<ppc::core::Perf>(test); | ||
perfAnalyzer->task_run(perfAttr, perfResults); | ||
ppc::core::Perf::print_perf_statistic(perfResults); | ||
|
||
if (world.rank() == 0) { | ||
ASSERT_EQ(res.size(), size); | ||
} | ||
} |
Oops, something went wrong.