Skip to content

Instantly share code, notes, and snippets.

@keichi
Created December 28, 2022 00:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keichi/2dec19868aca01f8bad4c3522174fbb1 to your computer and use it in GitHub Desktop.
Save keichi/2dec19868aca01f8bad4c3522174fbb1 to your computer and use it in GitHub Desktop.
#pragma once
#include <iterator>
namespace proto
{
template <class ExecutionPolicy, class ForwardIterator, class T>
void fill(ExecutionPolicy &&exec, ForwardIterator first, ForwardIterator last,
const T &value)
{
size_t size = std::distance(first, last);
#pragma omp parallel for
#pragma _NEC ivdep
for (size_t i = 0; i < size; i++) {
first[i] = value;
}
}
template <class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
ForwardIterator2 copy(ExecutionPolicy &&exec, ForwardIterator1 first,
ForwardIterator1 last, ForwardIterator2 result)
{
size_t size = std::distance(first, last);
#pragma omp parallel for
#pragma _NEC ivdep
for (size_t i = 0; i < size; i++) {
result[i] = first[i];
}
return result + size;
}
template <class ExecutionPolicy, class ForwardIterator, class Function>
void for_each(ExecutionPolicy &&exec, ForwardIterator first,
ForwardIterator last, Function f)
{
size_t size = std::distance(first, last);
#pragma omp parallel for
#pragma _NEC ivdep
for (size_t i = 0; i < size; i++) {
#pragma _NEC inline
f(first[i]);
}
}
template <class ExecutionPolicy, class ForwardIterator, class Size,
class Function>
ForwardIterator for_each_n(ExecutionPolicy &&exec, ForwardIterator first,
Size n, Function f)
{
#pragma omp parallel for
#pragma _NEC ivdep
for (size_t i = 0; i < n; i++) {
#pragma _NEC inline
f(first[i]);
}
}
template <class ExecutionPolicy, class InputIterator, class OutputIterator,
class UnaryOperation>
OutputIterator transform(ExecutionPolicy &&exec, InputIterator first,
InputIterator last, OutputIterator result,
UnaryOperation op)
{
size_t size = std::distance(first, last);
#pragma omp parallel for
#pragma _NEC ivdep
for (size_t i = 0; i < size; i++) {
#pragma _NEC inline
result[i] = op(first[i]);
}
return result + size;
}
template <class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
class ForwardIterator, class BinaryOperation>
ForwardIterator transform(ExecutionPolicy &&exec, ForwardIterator1 first1,
ForwardIterator1 last1, ForwardIterator2 first2,
ForwardIterator result, BinaryOperation binary_op)
{
size_t size = std::distance(first1, last1);
#pragma omp parallel for
#pragma _NEC ivdep
for (size_t i = 0; i < size; i++) {
#pragma _NEC inline
result[i] = binary_op(first1[i], first2[i]);
}
return result + size;
}
template <class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
class T>
T transform_reduce(ExecutionPolicy &&exec, ForwardIterator1 first1,
ForwardIterator1 last1, ForwardIterator2 first2, T init)
{
size_t size = std::distance(first1, last1);
T sum = init;
#pragma omp parallel for reduction(+ : sum)
for (size_t i = 0; i < size; i++) {
sum += first1[i] * first2[i];
}
return sum;
}
template <class ExecutionPolicy, class ForwardIt, class T,
class BinaryReductionOp, class UnaryTransformOp>
T transform_reduce(ExecutionPolicy &&policy, ForwardIt first, ForwardIt last,
T init, BinaryReductionOp reduce, UnaryTransformOp transform)
{
size_t size = std::distance(first, last);
T sum = init;
#pragma omp parallel
{
T local_sum = init;
#pragma omp for
for (size_t i = 0; i < size; i++) {
#pragma _NEC inline
local_sum = reduce(local_sum, transform(first[i]));
}
#pragma omp critical
{
sum = reduce(sum, local_sum);
}
}
return sum;
}
} // namespace proto
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment