Skip to content

Commit

Permalink
Revert "Казунин Никита. Задача 2. Вариант 3. Обедающие философы." (#514
Browse files Browse the repository at this point in the history
…) (#547)

В локальной сборке самый большой запуск занимал **120ms** в среднем, и я
не заметил что в GitActions это занимало в среднем **950ms**, и вот
периодически это длилось чуть дольше и тест падал по
`initial_order_test`. Поэтому я исправил задержки и размеры симуляции,
теперь самый долгий тест занимает примерно **500ms** и проблем быть не
должно
  • Loading branch information
NikKazzzzzz authored Dec 15, 2024
1 parent 1f52a55 commit 25d1b92
Show file tree
Hide file tree
Showing 4 changed files with 441 additions and 0 deletions.
103 changes: 103 additions & 0 deletions tasks/mpi/kazunin_n_dining_philosophers/func_tests/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#include <gtest/gtest.h>

#include <boost/mpi/communicator.hpp>
#include <boost/mpi/environment.hpp>

#include "core/task/include/task.hpp"
#include "mpi/kazunin_n_dining_philosophers/include/ops_mpi.hpp"

namespace kazunin_n_dining_philosophers_mpi {

bool is_valid(int eat_limit, int min_think_time, int max_think_time, int min_eat_time, int max_eat_time) {
return eat_limit > 0 && min_think_time < max_think_time && min_eat_time < max_eat_time && max_think_time < 100 &&
min_think_time > 0 && max_eat_time < 100 && min_eat_time > 0;
}

void start_test(int eat_limit = 3, int min_think_time = 2, int max_think_time = 5, int min_eat_time = 2,
int max_eat_time = 5) {
boost::mpi::communicator world;
if (world.size() < 4) {
GTEST_SKIP();
}
std::shared_ptr<ppc::core::TaskData> taskDataPar = std::make_shared<ppc::core::TaskData>();

taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t*>(&eat_limit));
taskDataPar->inputs_count.emplace_back(1);

taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t*>(&min_think_time));
taskDataPar->inputs_count.emplace_back(1);

taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t*>(&max_think_time));
taskDataPar->inputs_count.emplace_back(1);

taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t*>(&min_eat_time));
taskDataPar->inputs_count.emplace_back(1);

taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t*>(&max_eat_time));
taskDataPar->inputs_count.emplace_back(1);

auto taskParallel = std::make_shared<kazunin_n_dining_philosophers_mpi::DiningPhilosophersParallelMPI>(taskDataPar);
if (is_valid(eat_limit, min_think_time, max_think_time, min_eat_time, max_eat_time)) {
EXPECT_TRUE(taskParallel->validation());
taskParallel->pre_processing();
taskParallel->run();
taskParallel->post_processing();
} else {
EXPECT_FALSE(taskParallel->validation());
}
world.barrier();
}

} // namespace kazunin_n_dining_philosophers_mpi

TEST(kazunin_n_dining_philosophers_mpi, defailt) { kazunin_n_dining_philosophers_mpi::start_test(); }

TEST(kazunin_n_dining_philosophers_mpi, default_eat_limit) { kazunin_n_dining_philosophers_mpi::start_test(4); }

TEST(kazunin_n_dining_philosophers_mpi, default_min_think_time) { kazunin_n_dining_philosophers_mpi::start_test(4, 3); }

TEST(kazunin_n_dining_philosophers_mpi, default_max_think_time) {
kazunin_n_dining_philosophers_mpi::start_test(4, 3, 4);
}

TEST(kazunin_n_dining_philosophers_mpi, default_min_eat_time) {
kazunin_n_dining_philosophers_mpi::start_test(4, 3, 4, 3);
}

TEST(kazunin_n_dining_philosophers_mpi, default_max_eat_time) {
kazunin_n_dining_philosophers_mpi::start_test(4, 3, 4, 3, 4);
}

TEST(kazunin_n_dining_philosophers_mpi, validation_test_min_eat_limit) {
kazunin_n_dining_philosophers_mpi::start_test(0);
}

TEST(kazunin_n_dining_philosophers_mpi, validation_test_min_min_think_time) {
kazunin_n_dining_philosophers_mpi::start_test(3, -20);
}

TEST(kazunin_n_dining_philosophers_mpi, validation_test_min_gt_max_think_time) {
kazunin_n_dining_philosophers_mpi::start_test(3, 30, 20);
}

TEST(kazunin_n_dining_philosophers_mpi, validation_test_max_max_think_time) {
kazunin_n_dining_philosophers_mpi::start_test(3, 20, 1000);
}

TEST(kazunin_n_dining_philosophers_mpi, validation_test_min_min_eat_time) {
kazunin_n_dining_philosophers_mpi::start_test(3, 20, 40, -20);
}

TEST(kazunin_n_dining_philosophers_mpi, validation_test_min_gt_max_eat_time) {
kazunin_n_dining_philosophers_mpi::start_test(3, 20, 40, 30, 20);
}

TEST(kazunin_n_dining_philosophers_mpi, validation_test_max_max_eat_time) {
kazunin_n_dining_philosophers_mpi::start_test(3, 20, 40, 20, 1000);
}

TEST(kazunin_n_dining_philosophers_mpi, simulation_5_eat_limit) { kazunin_n_dining_philosophers_mpi::start_test(5); }

TEST(kazunin_n_dining_philosophers_mpi, simulation_15_eat_limit) {
kazunin_n_dining_philosophers_mpi::start_test(15, 1, 2, 1, 2);
}
45 changes: 45 additions & 0 deletions tasks/mpi/kazunin_n_dining_philosophers/include/ops_mpi.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include <gtest/gtest.h>

#include <boost/mpi/collectives.hpp>
#include <boost/mpi/communicator.hpp>
#include <queue>

#include "core/task/include/task.hpp"

namespace kazunin_n_dining_philosophers_mpi {

enum MessageTag : std::uint8_t { REQUEST_FORK = 1, RELEASE_FORK = 2, FORK_GRANTED = 3, TERMINATE_FORK = 4 };

inline void request_forks(int id, int left_fork, int right_fork, int N, boost::mpi::communicator& world);
inline void release_forks(int id, int left_fork, int right_fork, int N, boost::mpi::communicator& world);
inline void handle_fork_request(int& philosopher_id, bool& fork_available, std::queue<int>& waiting_queue,
boost::mpi::communicator& world, int id);
inline void handle_fork_release(int& philosopher_id, bool& fork_available, std::queue<int>& waiting_queue,
boost::mpi::communicator& world, int id);
inline bool fork_manager(int id, boost::mpi::communicator& world);
inline bool philosopher(int id, int N, boost::mpi::communicator& world, boost::mpi::communicator& philosophers_comm,
int eat_limit, int min_think_time, int max_think_time, int min_eat_time, int max_eat_time);

class DiningPhilosophersParallelMPI : public ppc::core::Task {
public:
explicit DiningPhilosophersParallelMPI(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:
int eat_limit;
int min_think_time;
int max_think_time;
int min_eat_time;
int max_eat_time;
int N;
int color;
boost::mpi::communicator local_comm;
boost::mpi::communicator world;
};

} // namespace kazunin_n_dining_philosophers_mpi
128 changes: 128 additions & 0 deletions tasks/mpi/kazunin_n_dining_philosophers/perf_tests/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#include <gtest/gtest.h>

#include <boost/mpi/communicator.hpp>
#include <boost/mpi/environment.hpp>
#include <boost/mpi/timer.hpp>
#include <vector>

#include "core/perf/include/perf.hpp"
#include "mpi/kazunin_n_dining_philosophers/include/ops_mpi.hpp"

namespace kazunin_n_dining_philosophers_mpi {

bool is_valid(int eat_limit, int min_think_time, int max_think_time, int min_eat_time, int max_eat_time) {
return eat_limit > 0 && min_think_time < max_think_time && min_eat_time < max_eat_time && max_think_time < 100 &&
min_think_time > 0 && max_eat_time < 100 && min_eat_time > 0;
}

} // namespace kazunin_n_dining_philosophers_mpi

TEST(kazunin_n_dining_philosophers_mpi, pipeline_run) {
boost::mpi::environment env;
boost::mpi::communicator world;
if (world.size() < 4) {
GTEST_SKIP();
}

int eat_limit = 3;
int min_think_time = 20;
int max_think_time = 40;
int min_eat_time = 10;
int max_eat_time = 20;

std::shared_ptr<ppc::core::TaskData> taskDataPar = std::make_shared<ppc::core::TaskData>();

taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t*>(&eat_limit));
taskDataPar->inputs_count.emplace_back(1);

taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t*>(&min_think_time));
taskDataPar->inputs_count.emplace_back(1);

taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t*>(&max_think_time));
taskDataPar->inputs_count.emplace_back(1);

taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t*>(&min_eat_time));
taskDataPar->inputs_count.emplace_back(1);

taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t*>(&max_eat_time));
taskDataPar->inputs_count.emplace_back(1);

auto taskParallel = std::make_shared<kazunin_n_dining_philosophers_mpi::DiningPhilosophersParallelMPI>(taskDataPar);
if (kazunin_n_dining_philosophers_mpi::is_valid(eat_limit, min_think_time, max_think_time, min_eat_time,
max_eat_time)) {
EXPECT_TRUE(taskParallel->validation());
taskParallel->pre_processing();
taskParallel->run();
taskParallel->post_processing();

auto perfAttr = std::make_shared<ppc::core::PerfAttr>();
perfAttr->num_running = 10;
const boost::mpi::timer current_timer;
perfAttr->current_timer = [&] { return current_timer.elapsed(); };
auto perfResults = std::make_shared<ppc::core::PerfResults>();
auto perfAnalyzer = std::make_shared<ppc::core::Perf>(taskParallel);
perfAnalyzer->pipeline_run(perfAttr, perfResults);

if (world.rank() == 0) {
ppc::core::Perf::print_perf_statistic(perfResults);
}
} else {
EXPECT_FALSE(taskParallel->validation());
}
}

TEST(kazunin_n_dining_philosophers_mpi, task_run) {
boost::mpi::environment env;
boost::mpi::communicator world;
if (world.size() < 4) {
GTEST_SKIP();
}

int eat_limit = 3;
int min_think_time = 20;
int max_think_time = 40;
int min_eat_time = 10;
int max_eat_time = 20;

std::shared_ptr<ppc::core::TaskData> taskDataPar = std::make_shared<ppc::core::TaskData>();

taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t*>(&eat_limit));
taskDataPar->inputs_count.emplace_back(1);

taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t*>(&min_think_time));
taskDataPar->inputs_count.emplace_back(1);

taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t*>(&max_think_time));
taskDataPar->inputs_count.emplace_back(1);

taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t*>(&min_eat_time));
taskDataPar->inputs_count.emplace_back(1);

taskDataPar->inputs.emplace_back(reinterpret_cast<uint8_t*>(&max_eat_time));
taskDataPar->inputs_count.emplace_back(1);

auto taskParallel = std::make_shared<kazunin_n_dining_philosophers_mpi::DiningPhilosophersParallelMPI>(taskDataPar);
if (kazunin_n_dining_philosophers_mpi::is_valid(eat_limit, min_think_time, max_think_time, min_eat_time,
max_eat_time)) {
EXPECT_TRUE(taskParallel->validation());
taskParallel->pre_processing();
taskParallel->run();
taskParallel->post_processing();

auto perfAttr = std::make_shared<ppc::core::PerfAttr>();
perfAttr->num_running = 10;
const boost::mpi::timer current_timer;
perfAttr->current_timer = [&] { return current_timer.elapsed(); };

auto perfResults = std::make_shared<ppc::core::PerfResults>();

auto perfAnalyzer = std::make_shared<ppc::core::Perf>(taskParallel);
perfAnalyzer->task_run(perfAttr, perfResults);

if (world.rank() == 0) {
ppc::core::Perf::print_perf_statistic(perfResults);
}
} else {
EXPECT_FALSE(taskParallel->validation());
}
}
Loading

0 comments on commit 25d1b92

Please sign in to comment.