Skip to content
Open
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
93 changes: 63 additions & 30 deletions tasks/redkina_a_integral_simpson/omp/src/ops_omp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,41 @@
#include "redkina_a_integral_simpson/common/include/common.hpp"

namespace redkina_a_integral_simpson {
namespace {

std::vector<std::vector<double>> PrecomputeWeights(const std::vector<int> &n) {
const size_t dim = n.size();
std::vector<std::vector<double>> weights(dim);
for (size_t i = 0; i < dim; ++i) {
const int ni = n[i];
weights[i].resize(ni + 1);
for (int idx = 0; idx <= ni; ++idx) {
if (idx == 0 || idx == ni) {
weights[i][idx] = 1.0;
} else if (idx % 2 == 1) {
weights[i][idx] = 4.0;
} else {
weights[i][idx] = 2.0;
}
}
}
return weights;
}

std::vector<size_t> ComputeStrides(const std::vector<int> &n) {
const size_t dim = n.size();
std::vector<size_t> strides(dim);
if (dim == 0) {
return strides;
}
strides[dim - 1] = 1;
for (size_t i = dim - 1; i > 0; --i) {
strides[i - 1] = strides[i] * static_cast<size_t>(n[i] + 1);
}
return strides;
}

} // namespace

RedkinaAIntegralSimpsonOMP::RedkinaAIntegralSimpsonOMP(const InType &in) {
SetTypeOfTask(GetStaticTypeOfTask());
Expand All @@ -32,7 +67,6 @@ bool RedkinaAIntegralSimpsonOMP::ValidationImpl() {
return false;
}
}

return static_cast<bool>(in.func);
}

Expand All @@ -47,57 +81,56 @@ bool RedkinaAIntegralSimpsonOMP::PreProcessingImpl() {
}

bool RedkinaAIntegralSimpsonOMP::RunImpl() {
size_t dim = a_.size();

const std::vector<double> a_local = a_;
const std::vector<double> b_local = b_;
const std::vector<int> n_local = n_;
const auto func_local = func_;
if (!func_) {
return false;
}
const size_t dim = a_.size();
if (dim == 0) {
return false;
}

std::vector<double> h(dim);
double h_prod = 1.0;
for (size_t i = 0; i < dim; ++i) {
h[i] = (b_local[i] - a_local[i]) / static_cast<double>(n_local[i]);
h[i] = (b_[i] - a_[i]) / static_cast<double>(n_[i]);
h_prod *= h[i];
}

std::vector<int> strides(dim);
strides[dim - 1] = 1;
for (int i = static_cast<int>(dim) - 2; i >= 0; --i) {
strides[i] = strides[i + 1] * (n_local[i + 1] + 1);
const auto weights = PrecomputeWeights(n_);
const auto strides = ComputeStrides(n_);
if (strides.empty()) {
return false;
}
int total_nodes = strides[0] * (n_local[0] + 1);

const int total_nodes = static_cast<int>(strides[0] * static_cast<size_t>(n_[0] + 1));

double total_sum = 0.0;

#pragma omp parallel default(none) shared(total_nodes, h, strides, a_local, n_local, func_local, dim) \
reduction(+ : total_sum)
const std::vector<double> &a_local = a_;
const std::vector<double> &h_local = h;
const auto &weights_local = weights;
const auto &strides_local = strides;
const auto &func_local = func_;

#pragma omp parallel default(none) \
shared(total_nodes, a_local, h_local, weights_local, strides_local, func_local, dim) reduction(+ : total_sum)
{
std::vector<int> indices(dim);
std::vector<double> point(dim);

#pragma omp for schedule(static)
for (int idx = 0; idx < total_nodes; ++idx) {
int remainder = idx;
auto remainder = static_cast<size_t>(idx);
for (size_t dim_idx = 0; dim_idx < dim; ++dim_idx) {
indices[dim_idx] = remainder / strides[dim_idx];
remainder %= strides[dim_idx];
indices[dim_idx] = static_cast<int>(remainder / strides_local[dim_idx]);
remainder %= strides_local[dim_idx];
}

double w_prod = 1.0;
for (size_t dim_idx = 0; dim_idx < dim; ++dim_idx) {
int i_idx = indices[dim_idx];
point[dim_idx] = a_local[dim_idx] + (i_idx * h[dim_idx]);

int w = 0;
if (i_idx == 0 || i_idx == n_local[dim_idx]) {
w = 1;
} else if (i_idx % 2 == 1) {
w = 4;
} else {
w = 2;
}
w_prod *= static_cast<double>(w);
const int i_idx = indices[dim_idx];
point[dim_idx] = a_local[dim_idx] + (static_cast<double>(i_idx) * h_local[dim_idx]);
w_prod *= weights_local[dim_idx][i_idx];
}

total_sum += w_prod * func_local(point);
Expand Down
Loading