Utopia 2
Framework for studying models of complex & adaptive systems.
|
Overloads for selecting execution policies at runtime. More...
Functions | |
template<class InputIt , class OutputIt > | |
OutputIt | std::copy (const Utopia::ExecPolicy policy, InputIt first, InputIt last, OutputIt d_first) |
Copy the input range to a new range. | |
template<class InputIt , class UnaryFunction > | |
void | std::for_each (const Utopia::ExecPolicy policy, InputIt first, InputIt last, UnaryFunction f) |
Apply a function to a range. | |
template<class InputIt , class OutputIt , class UnaryOperation > | |
OutputIt | std::transform (const Utopia::ExecPolicy policy, InputIt first1, InputIt last1, OutputIt d_first, UnaryOperation unary_op) |
Apply a unary operator to a range and store the result in a new range. | |
template<class InputIt1 , class InputIt2 , class OutputIt , class BinaryOperation > | |
OutputIt | std::transform (const Utopia::ExecPolicy policy, InputIt1 first1, InputIt1 last1, InputIt2 first2, OutputIt d_first, BinaryOperation binary_op) |
Apply a binary operator to two ranges and store the result in a new range. | |
Overloads for selecting execution policies at runtime.
These algorithms are overloads of the respective STL algorithms where the ExecutionPolicy
template parameter has been replaced by the Utopia::ExecPolicy runtime parameter. Developers can use these overloads to have the Utopia Parallel Facilities decide the actual execution policy at runtime. This is done by inserting the algorithm into the Utopia::exec_parallel function.
Using these overloads, developers still have to take care of potential data races, as if they are always executed with the intended execution policy.
To add another algorithm overload, have a look at the original algorithm signature. A list of STL algorithms can be found here. Copy the signature including the ExecutionPolicy
. Remove the ExecutionPolicy
template parameter and replace the ExecutionPolicy
argument with Utopia::ExecPolicy. Inside the function, call Utopia::exec_parallel with the Utopia::ExecPolicy as first argument. The second argument is a generic lambda which captures nothing ([]
) and takes a single generic argument which will be a tuple containing the algorithm's arguments (auto&& args_tpl
). In the lambda body, create a localized version of your STL algorithm which simply takes a list of arguments and calls the STL algorithm. Depending on the algorithm return type, make sure to return the STL algorithm return value. Finally, add the other arguments of the algorithm overload to the call to Utopia::exec_parallel.
The result looks weird, but wrapping the arguments inside a tuple relieves us from writing different code for the case where std::execution
is not defined.
Example:
OutputIt std::copy | ( | const Utopia::ExecPolicy | policy, |
InputIt | first, | ||
InputIt | last, | ||
OutputIt | d_first | ||
) |
Copy the input range to a new range.
See https://en.cppreference.com/w/cpp/algorithm/copy
void std::for_each | ( | const Utopia::ExecPolicy | policy, |
InputIt | first, | ||
InputIt | last, | ||
UnaryFunction | f | ||
) |
Apply a function to a range.
See https://en.cppreference.com/w/cpp/algorithm/for_each
OutputIt std::transform | ( | const Utopia::ExecPolicy | policy, |
InputIt | first1, | ||
InputIt | last1, | ||
OutputIt | d_first, | ||
UnaryOperation | unary_op | ||
) |
Apply a unary operator to a range and store the result in a new range.
See https://en.cppreference.com/w/cpp/algorithm/transform
OutputIt std::transform | ( | const Utopia::ExecPolicy | policy, |
InputIt1 | first1, | ||
InputIt1 | last1, | ||
InputIt2 | first2, | ||
OutputIt | d_first, | ||
BinaryOperation | binary_op | ||
) |
Apply a binary operator to two ranges and store the result in a new range.
See https://en.cppreference.com/w/cpp/algorithm/transform