Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions tasks/likhanov_m_multi_step_scheme/common/include/common.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

#include <string>
#include <tuple>

#include "task/include/task.hpp"

namespace likhanov_m_multi_step_scheme {

using InType = int;
using OutType = int;
using TestType = std::tuple<int, std::string>;
using BaseTask = ppc::task::Task<InType, OutType>;

struct Rect {
double x_left;
double x_right;
double y_left;
double y_right;

double value{0.0};
double characteristic{0.0};

Rect(double x_left_value,
double x_right_value,
double y_left_value,
double y_right_value)
: x_left(x_left_value),
x_right(x_right_value),
y_left(y_left_value),
y_right(y_right_value) {}
};

inline double TestFunction(double x, double y) {
return std::sin(x) + std::cos(y);
}

} // namespace likhanov_m_multi_step_scheme
Binary file added tasks/likhanov_m_multi_step_scheme/data/pic.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions tasks/likhanov_m_multi_step_scheme/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"student": {
"first_name": "Матвей",
"last_name": "Лиханов",
"middle_name": "Дмитриевич",
"group_number": "3823Б1ПР1",
"task_number": "3"
}
}
22 changes: 22 additions & 0 deletions tasks/likhanov_m_multi_step_scheme/mpi/include/ops_mpi.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include "likhanov_m_multi_step_scheme/common/include/common.hpp"
#include "task/include/task.hpp"

namespace likhanov_m_multi_step_scheme {

class LikhanovMMultiStepSchemeMPI : public BaseTask {
public:
static constexpr ppc::task::TypeOfTask GetStaticTypeOfTask() {
return ppc::task::TypeOfTask::kMPI;
}
explicit LikhanovMMultiStepSchemeMPI(const InType &in);

private:
bool ValidationImpl() override;
bool PreProcessingImpl() override;
bool RunImpl() override;
bool PostProcessingImpl() override;
};

} // namespace likhanov_m_multi_step_scheme
107 changes: 107 additions & 0 deletions tasks/likhanov_m_multi_step_scheme/mpi/src/ops_mpi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#include "likhanov_m_multi_step_scheme/mpi/include/ops_mpi.hpp"

#include <mpi.h>

#include <numeric>
#include <vector>

#include "likhanov_m_multi_step_scheme/common/include/common.hpp"
#include "util/include/util.hpp"

namespace likhanov_m_multi_step_scheme {

LikhanovMMultiStepSchemeMPI::LikhanovMMultiStepSchemeMPI(const InType &in) {
SetTypeOfTask(GetStaticTypeOfTask());
GetInput() = in;
GetOutput() = 0;
}

bool LikhanovMMultiStepSchemeMPI::ValidationImpl() {
return (GetInput() > 0) && (GetOutput() == 0);
}

bool LikhanovMMultiStepSchemeMPI::PreProcessingImpl() {
GetOutput() = 2 * GetInput();
return GetOutput() > 0;
}

bool LikhanovMMultiStepSchemeMPI::RunImpl() {
int rank = 0;
int size = 0;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);

const int steps = GetInput();
if (steps <= 0) {
return false;
}

std::vector<Rect> rects;
rects.emplace_back(0.0, 1.0, 0.0, 1.0);

const double L = 2.0;

for (int step = 0; step < steps; step++) {
double local_best = -1e9;
int local_index = -1;

for (int i = rank; i < static_cast<int>(rects.size()); i += size) {
Rect& r = rects[i];

const double cx = 0.5 * (r.x_left + r.x_right);
const double cy = 0.5 * (r.y_left + r.y_right);
r.value = TestFunction(cx, cy);

const double dx = r.x_right - r.x_left;
const double dy = r.y_right - r.y_left;
r.characteristic = r.value - L * std::sqrt(dx * dx + dy * dy);

if (r.characteristic > local_best) {
local_best = r.characteristic;
local_index = i;
}
}

struct {
double value;
int index;
} local, global;

local.value = local_best;
local.index = local_index;

MPI_Allreduce(&local, &global, 1, MPI_DOUBLE_INT, MPI_MAXLOC,
MPI_COMM_WORLD);

if (rank == 0 && global.index >= 0) {
Rect best = rects[global.index];
rects.erase(rects.begin() + global.index);

const double mx = 0.5 * (best.x_left + best.x_right);
const double my = 0.5 * (best.y_left + best.y_right);

rects.emplace_back(best.x_left, mx, best.y_left, my);
rects.emplace_back(mx, best.x_right, best.y_left, my);
rects.emplace_back(best.x_left, mx, my, best.y_right);
rects.emplace_back(mx, best.x_right, my, best.y_right);
}

MPI_Barrier(MPI_COMM_WORLD);
}

if (rank == 0) {
double best_val = rects.front().value;
for (const auto& r : rects) {
best_val = std::min(best_val, r.value);
}
GetOutput() = best_val;
}

return true;
}

bool LikhanovMMultiStepSchemeMPI::PostProcessingImpl() {
return std::isfinite(GetOutput());
}

} // namespace likhanov_m_multi_step_scheme
Loading
Loading