Program Listing for File numeric.h¶
↰ Return to documentation for file (include/shad/core/numeric.h
)
//===------------------------------------------------------------*- C++ -*-===//
//
// SHAD
//
// The Scalable High-performance Algorithms and Data Structure Library
//
//===----------------------------------------------------------------------===//
//
// Copyright 2018 Battelle Memorial Institute
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
//
//===----------------------------------------------------------------------===//
#ifndef INCLUDE_SHAD_CORE_NUMERIC_H
#define INCLUDE_SHAD_CORE_NUMERIC_H
#include <functional>
#include <iterator>
#include <tuple>
#include <utility>
#include <vector>
#include "shad/core/execution.h"
#include "shad/core/impl/numeric_ops.h"
#include "shad/distributed_iterator_traits.h"
#include "shad/runtime/runtime.h"
namespace shad {
template <class ForwardIterator, class T>
void iota(ForwardIterator first, ForwardIterator last, T value) {
return impl::iota(first, last, value);
}
//
// accumulate
//
template <class InputIt, class T, class BinaryOperation>
T accumulate(InputIt first, InputIt last, T init, BinaryOperation op) {
return impl::accumulate(first, last, init, op);
}
template <class InputIt, class T>
T accumulate(InputIt first, InputIt last, T init) {
return impl::accumulate(first, last, init, std::plus<T>());
}
//
// inner product
//
template <class InputIt1, class InputIt2, class T>
T inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init) {
return impl::inner_product(first1, last1, first2, init);
}
template <class InputIt1, class InputIt2, class T, class BinaryOperation1,
class BinaryOperation2>
T inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init,
BinaryOperation1 op1, BinaryOperation2 op2) {
return impl::inner_product(first1, last1, first2, init, op1, op2);
}
//
// adjacent_difference
//
template <class InputIt, class OutputIt>
OutputIt adjacent_difference(InputIt first, InputIt last, OutputIt d_first) {
using value_t = typename distributed_iterator_traits<InputIt>::value_type;
return impl::adjacent_difference(distributed_sequential_tag{}, first, last,
d_first, std::minus<value_t>());
}
template <typename ExecutionPolicy, class InputIt, class OutputIt>
std::enable_if_t<shad::is_execution_policy<ExecutionPolicy>::value, OutputIt>
adjacent_difference(ExecutionPolicy&& policy, InputIt first, InputIt last,
OutputIt d_first) {
using value_t = typename distributed_iterator_traits<InputIt>::value_type;
return impl::adjacent_difference(std::forward<ExecutionPolicy>(policy), first,
last, d_first, std::minus<value_t>());
}
template <class InputIt, class OutputIt, class BinaryOperation>
std::enable_if_t<!shad::is_execution_policy<InputIt>::value, OutputIt>
adjacent_difference(InputIt first, InputIt last, OutputIt d_first,
BinaryOperation op) {
return impl::adjacent_difference(distributed_sequential_tag{}, first, last,
d_first, op);
}
template <typename ExecutionPolicy, class InputIt, class OutputIt,
class BinaryOperation>
OutputIt adjacent_difference(ExecutionPolicy&& policy, InputIt first,
InputIt last, OutputIt d_first,
BinaryOperation op) {
return impl::adjacent_difference(std::forward<ExecutionPolicy>(policy), first,
last, d_first, op);
}
//
// partial sum
//
template <class InputIt, class OutputIt>
OutputIt partial_sum(InputIt first, InputIt last, OutputIt d_first) {
using value_t = typename distributed_iterator_traits<InputIt>::value_type;
return impl::partial_sum(first, last, d_first, std::plus<value_t>());
}
template <class InputIt, class OutputIt, class BinaryOperation>
OutputIt partial_sum(InputIt first, InputIt last, OutputIt d_first,
BinaryOperation op) {
return impl::partial_sum(first, last, d_first, op);
}
//
// reduce
//
template <class ExecutionPolicy, class ForwardIt, class T, class BinaryOp>
T reduce(ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, T init,
BinaryOp binary_op) {
return impl::reduce(std::forward<ExecutionPolicy>(policy), first, last, init,
binary_op);
}
template <class InputIt>
typename std::iterator_traits<InputIt>::value_type reduce(InputIt first,
InputIt last) {
using val_t = typename std::iterator_traits<InputIt>::value_type;
return reduce(distributed_sequential_tag{}, first, last, val_t{},
std::plus<val_t>());
}
template <class ExecutionPolicy, class ForwardIt>
std::enable_if_t<shad::is_execution_policy<ExecutionPolicy>::value,
typename std::iterator_traits<ForwardIt>::value_type>
reduce(ExecutionPolicy&& policy, ForwardIt first, ForwardIt last) {
using val_t = typename std::iterator_traits<ForwardIt>::value_type;
return reduce(std::forward<ExecutionPolicy>(policy), first, last, val_t{},
std::plus<val_t>());
}
template <class InputIt, class T>
std::enable_if_t<!shad::is_execution_policy<InputIt>::value, T> reduce(
InputIt first, InputIt last, T init) {
return reduce(distributed_sequential_tag{}, first, last, init,
std::plus<T>());
}
template <class ExecutionPolicy, class ForwardIt, class T>
std::enable_if_t<shad::is_execution_policy<ExecutionPolicy>::value, T> reduce(
ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, T init) {
return reduce(std::forward<ExecutionPolicy>(policy), first, last, init,
std::plus<T>());
}
template <class InputIt, class T, class BinaryOp>
std::enable_if_t<!shad::is_execution_policy<InputIt>::value, T> reduce(
InputIt first, InputIt last, T init, BinaryOp binary_op) {
return reduce(distributed_sequential_tag{}, first, last, init, binary_op);
}
//
// exclusive_scan
//
template <class InputIt, class OutputIt, class T>
OutputIt exclusive_scan(InputIt first, InputIt last, OutputIt d_first, T init) {
return impl::exclusive_scan(shad::distributed_sequential_tag{}, first, last,
d_first, std::plus<T>(), init);
}
template <class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class T>
std::enable_if_t<shad::is_execution_policy<ExecutionPolicy>::value, ForwardIt2>
exclusive_scan(ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first, T init) {
return impl::exclusive_scan(std::forward<ExecutionPolicy>(policy), first,
last, d_first, std::plus<T>(), init);
}
template <class InputIt, class OutputIt, class T, class BinaryOperation>
std::enable_if_t<!shad::is_execution_policy<InputIt>::value, OutputIt>
exclusive_scan(InputIt first, InputIt last, OutputIt d_first, T init,
BinaryOperation binary_op) {
return impl::exclusive_scan(shad::distributed_sequential_tag{}, first, last,
d_first, binary_op, init);
}
template <class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class T,
class BinaryOperation>
ForwardIt2 exclusive_scan(ExecutionPolicy&& policy, ForwardIt1 first,
ForwardIt1 last, ForwardIt2 d_first, T init,
BinaryOperation binary_op) {
return impl::exclusive_scan(std::forward<ExecutionPolicy>(policy), first,
last, d_first, binary_op, init);
}
//
// inclusive_scan
//
template <class InputIt, class OutputIt>
OutputIt inclusive_scan(InputIt first, InputIt last, OutputIt d_first) {
return impl::inclusive_scan(shad::distributed_sequential_tag{}, first, last,
d_first, std::plus<>());
}
template <class ExecutionPolicy, class ForwardIt1, class ForwardIt2>
std::enable_if_t<shad::is_execution_policy<ExecutionPolicy>::value, ForwardIt2>
inclusive_scan(ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first) {
return impl::inclusive_scan(std::forward<ExecutionPolicy>(policy), first,
last, d_first, std::plus<>());
}
template <class InputIt, class OutputIt, class BinaryOperation>
std::enable_if_t<!shad::is_execution_policy<InputIt>::value, OutputIt>
inclusive_scan(InputIt first, InputIt last, OutputIt d_first,
BinaryOperation binary_op) {
return impl::inclusive_scan(shad::distributed_sequential_tag{}, first, last,
d_first, binary_op);
}
template <class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
class BinaryOperation>
std::enable_if_t<shad::is_execution_policy<ExecutionPolicy>::value, ForwardIt2>
inclusive_scan(ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first, BinaryOperation binary_op) {
return impl::inclusive_scan(std::forward<ExecutionPolicy>(policy), first,
last, d_first, binary_op);
}
template <class InputIt, class OutputIt, class BinaryOperation, class T>
std::enable_if_t<!shad::is_execution_policy<InputIt>::value, OutputIt>
inclusive_scan(InputIt first, InputIt last, OutputIt d_first,
BinaryOperation binary_op, T init) {
return impl::inclusive_scan(shad::distributed_sequential_tag{}, first, last,
d_first, binary_op, init);
}
template <class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
class BinaryOperation, class T>
ForwardIt2 inclusive_scan(ExecutionPolicy&& policy, ForwardIt1 first,
ForwardIt1 last, ForwardIt2 d_first,
BinaryOperation binary_op, T init) {
return impl::inclusive_scan(std::forward<ExecutionPolicy>(policy), first,
last, d_first, binary_op, init);
}
//
// transform_reduce
//
// single range
template <class ExecutionPolicy, class ForwardIt, class T, class BinaryOp,
class UnaryOp>
std::enable_if_t<shad::is_execution_policy<ExecutionPolicy>::value, T>
transform_reduce(ExecutionPolicy&& policy, ForwardIt first, ForwardIt last,
T init, BinaryOp binary_op, UnaryOp unary_op) {
return impl::transform_reduce(std::forward<ExecutionPolicy>(policy), first,
last, init, binary_op, unary_op);
}
// two ranges
template <class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class T,
class BinaryOp1, class BinaryOp2>
T transform_reduce(ExecutionPolicy&& policy, ForwardIt1 first1,
ForwardIt1 last1, ForwardIt2 first2, T init,
BinaryOp1 binary_op1, BinaryOp2 binary_op2) {
return impl::transform_reduce(std::forward<ExecutionPolicy>(policy), first1,
last1, first2, init, binary_op1, binary_op2);
}
template <class InputIt1, class InputIt2, class T>
T transform_reduce(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init) {
return transform_reduce(distributed_sequential_tag{}, first1, last1, first2,
init, std::plus<>(), std::multiplies<>());
}
template <class InputIt1, class InputIt2, class T, class BinaryOp1,
class BinaryOp2>
std::enable_if_t<!shad::is_execution_policy<InputIt1>::value, T>
transform_reduce(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init,
BinaryOp1 binary_op1, BinaryOp2 binary_op2) {
return transform_reduce(distributed_sequential_tag{}, first1, last1, first2,
init, binary_op1, binary_op2);
}
template <class InputIt, class T, class BinaryOp, class UnaryOp>
std::enable_if_t<!shad::is_execution_policy<InputIt>::value, T>
transform_reduce(InputIt first, InputIt last, T init, BinaryOp binop,
UnaryOp unary_op) {
return transform_reduce(distributed_sequential_tag{}, first, last, init,
binop, unary_op);
}
template <class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class T>
std::enable_if_t<shad::is_execution_policy<ExecutionPolicy>::value, T>
transform_reduce(ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, T init) {
return transform_reduce(std::forward<ExecutionPolicy>(policy), first1, last1,
first2, init, std::plus<>(), std::multiplies<>());
}
//
// transform_exclusive_scan
//
template <class InputIt, class OutputIt, class T, class BinaryOperation,
class UnaryOperation>
OutputIt transform_exclusive_scan(InputIt first, InputIt last, OutputIt d_first,
T init, BinaryOperation binary_op,
UnaryOperation unary_op) {
return impl::transform_exclusive_scan(distributed_sequential_tag{}, first,
last, d_first, init, binary_op,
unary_op);
}
template <class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class T,
class BinaryOperation, class UnaryOperation>
ForwardIt2 transform_exclusive_scan(ExecutionPolicy&& policy, ForwardIt1 first,
ForwardIt1 last, ForwardIt2 d_first, T init,
BinaryOperation binary_op,
UnaryOperation unary_op) {
return impl::transform_exclusive_scan(std::forward<ExecutionPolicy>(policy),
first, last, d_first, init, binary_op,
unary_op);
}
//
// transform_inclusive_scan
//
template <class InputIt, class OutputIt, class BinaryOperation,
class UnaryOperation>
OutputIt transform_inclusive_scan(InputIt first, InputIt last, OutputIt d_first,
BinaryOperation binary_op,
UnaryOperation unary_op) {
return impl::transform_inclusive_scan(distributed_sequential_tag{}, first,
last, d_first, binary_op, unary_op);
}
template <class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
class BinaryOperation, class UnaryOperation>
std::enable_if_t<shad::is_execution_policy<ExecutionPolicy>::value, ForwardIt2>
transform_inclusive_scan(ExecutionPolicy&& policy, ForwardIt1 first,
ForwardIt1 last, ForwardIt2 d_first,
BinaryOperation binary_op, UnaryOperation unary_op) {
return impl::transform_inclusive_scan(std::forward<ExecutionPolicy>(policy),
first, last, d_first, binary_op,
unary_op);
}
template <class InputIt, class OutputIt, class BinaryOperation,
class UnaryOperation, class T>
std::enable_if_t<!shad::is_execution_policy<InputIt>::value, OutputIt>
transform_inclusive_scan(InputIt first, InputIt last, OutputIt d_first,
BinaryOperation binary_op, UnaryOperation unary_op,
T init) {
return impl::transform_inclusive_scan(distributed_sequential_tag{}, first,
last, d_first, binary_op, unary_op,
init);
}
template <class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
class BinaryOperation, class UnaryOperation, class T>
ForwardIt2 transform_inclusive_scan(ExecutionPolicy&& policy, ForwardIt1 first,
ForwardIt1 last, ForwardIt2 d_first,
BinaryOperation binary_op,
UnaryOperation unary_op, T init) {
return impl::transform_inclusive_scan(std::forward<ExecutionPolicy>(policy),
first, last, d_first, binary_op,
unary_op, init);
}
} // namespace shad
#endif /* INCLUDE_SHAD_CORE_NUMERIC_H */