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
22 changes: 22 additions & 0 deletions tasks/sosnina_a_radix_simple_merge/omp/include/ops_omp.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

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

namespace sosnina_a_radix_simple_merge {

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

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

} // namespace sosnina_a_radix_simple_merge
119 changes: 119 additions & 0 deletions tasks/sosnina_a_radix_simple_merge/omp/src/ops_omp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#include "sosnina_a_radix_simple_merge/omp/include/ops_omp.hpp"

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <vector>

#include "sosnina_a_radix_simple_merge/common/include/common.hpp"

namespace sosnina_a_radix_simple_merge {

namespace {

constexpr int kRadixBits = 8;
constexpr int kRadixSize = 1 << kRadixBits;
constexpr int kNumPasses = sizeof(int) / sizeof(uint8_t);
constexpr uint32_t kSignFlip = 0x80000000U;

void RadixSortLSD(std::vector<int> &data, std::vector<int> &buffer) {
size_t idx = 0;
for (int elem : data) {
buffer[idx++] = static_cast<int>(static_cast<uint32_t>(elem) ^ kSignFlip);
}
std::swap(data, buffer);

for (int pass = 0; pass < kNumPasses; ++pass) {
std::vector<int> count(kRadixSize + 1, 0);

for (auto elem : data) {
auto digit = static_cast<uint8_t>((static_cast<uint32_t>(elem) >> (pass * kRadixBits)) & 0xFF);
++count[digit + 1];
}

for (int i = 1; i <= kRadixSize; ++i) {
count[i] += count[i - 1];
}

for (auto elem : data) {
auto digit = static_cast<uint8_t>((static_cast<uint32_t>(elem) >> (pass * kRadixBits)) & 0xFF);
buffer[count[digit]++] = elem;
}

std::swap(data, buffer);
}

for (int &elem : data) {
elem = static_cast<int>(static_cast<uint32_t>(elem) ^ kSignFlip);
}
}

void SimpleMerge(const std::vector<int> &left, const std::vector<int> &right, std::vector<int> &result) {
size_t i = 0;
size_t j = 0;
size_t k = 0;

while (i < left.size() && j < right.size()) {
if (left[i] <= right[j]) {
result[k++] = left[i++];
} else {
result[k++] = right[j++];
}
}

while (i < left.size()) {
result[k++] = left[i++];
}

while (j < right.size()) {
result[k++] = right[j++];
}
}

} // namespace

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

bool SosninaATestTaskOMP::ValidationImpl() {
return !GetInput().empty();
}

bool SosninaATestTaskOMP::PreProcessingImpl() {
GetOutput() = GetInput();
return true;
}

bool SosninaATestTaskOMP::RunImpl() {
std::vector<int> &data = GetOutput();
if (data.size() <= 1) {
return true;
}

size_t mid = data.size() / 2;
std::vector<int> left_part(data.begin(), data.begin() + static_cast<std::ptrdiff_t>(mid));
std::vector<int> right_part(data.begin() + static_cast<std::ptrdiff_t>(mid), data.end());
std::vector<int> left_buffer(left_part.size());
std::vector<int> right_buffer(right_part.size());

#pragma omp parallel sections default(none) shared(left_part, left_buffer, right_part, right_buffer)
{
#pragma omp section
RadixSortLSD(left_part, left_buffer);
#pragma omp section
RadixSortLSD(right_part, right_buffer);
}

SimpleMerge(left_part, right_part, data);

return std::ranges::is_sorted(data);
}

bool SosninaATestTaskOMP::PostProcessingImpl() {
return !GetOutput().empty();
}

} // namespace sosnina_a_radix_simple_merge
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <vector>

#include "sosnina_a_radix_simple_merge/common/include/common.hpp"
#include "sosnina_a_radix_simple_merge/omp/include/ops_omp.hpp"
#include "sosnina_a_radix_simple_merge/seq/include/ops_seq.hpp"
#include "util/include/func_test_util.hpp"
#include "util/include/util.hpp"
Expand Down Expand Up @@ -118,8 +119,9 @@ const std::array<TestType, 48> kTestParam = []() {
return arr;
}();

const auto kTestTasksList =
ppc::util::AddFuncTask<SosninaATestTaskSEQ, InType>(kTestParam, PPC_SETTINGS_sosnina_a_radix_simple_merge);
const auto kTestTasksList = std::tuple_cat(
ppc::util::AddFuncTask<SosninaATestTaskSEQ, InType>(kTestParam, PPC_SETTINGS_sosnina_a_radix_simple_merge),
ppc::util::AddFuncTask<SosninaATestTaskOMP, InType>(kTestParam, PPC_SETTINGS_sosnina_a_radix_simple_merge));

const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <random>

#include "sosnina_a_radix_simple_merge/common/include/common.hpp"
#include "sosnina_a_radix_simple_merge/omp/include/ops_omp.hpp"
#include "sosnina_a_radix_simple_merge/seq/include/ops_seq.hpp"
#include "util/include/perf_test_util.hpp"

Expand Down Expand Up @@ -43,8 +44,8 @@ TEST_P(SosninaARunPerfTestRadixSort, RunPerfRadixSort) {

namespace {

const auto kAllPerfTasks =
ppc::util::MakeAllPerfTasks<InType, SosninaATestTaskSEQ>(PPC_SETTINGS_sosnina_a_radix_simple_merge);
const auto kAllPerfTasks = ppc::util::MakeAllPerfTasks<InType, SosninaATestTaskSEQ, SosninaATestTaskOMP>(
PPC_SETTINGS_sosnina_a_radix_simple_merge);

const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks);

Expand Down
Loading