1*4c3eb207Smrg // -*- C++ -*-
2*4c3eb207Smrg //===-- parallel_backend_serial.h -----------------------------------------===//
3*4c3eb207Smrg //
4*4c3eb207Smrg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*4c3eb207Smrg // See https://llvm.org/LICENSE.txt for license information.
6*4c3eb207Smrg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*4c3eb207Smrg //
8*4c3eb207Smrg //===----------------------------------------------------------------------===//
9*4c3eb207Smrg
10*4c3eb207Smrg #ifndef _PSTL_PARALLEL_BACKEND_SERIAL_H
11*4c3eb207Smrg #define _PSTL_PARALLEL_BACKEND_SERIAL_H
12*4c3eb207Smrg
13*4c3eb207Smrg #include <algorithm>
14*4c3eb207Smrg #include <cstddef>
15*4c3eb207Smrg #include <memory>
16*4c3eb207Smrg #include <numeric>
17*4c3eb207Smrg #include <utility>
18*4c3eb207Smrg
19*4c3eb207Smrg namespace __pstl
20*4c3eb207Smrg {
21*4c3eb207Smrg namespace __serial
22*4c3eb207Smrg {
23*4c3eb207Smrg
24*4c3eb207Smrg template <typename _Tp>
25*4c3eb207Smrg class __buffer
26*4c3eb207Smrg {
27*4c3eb207Smrg std::allocator<_Tp> __allocator_;
28*4c3eb207Smrg _Tp* __ptr_;
29*4c3eb207Smrg const std::size_t __buf_size_;
30*4c3eb207Smrg __buffer(const __buffer&) = delete;
31*4c3eb207Smrg void
32*4c3eb207Smrg operator=(const __buffer&) = delete;
33*4c3eb207Smrg
34*4c3eb207Smrg public:
__buffer(std::size_t __n)35*4c3eb207Smrg __buffer(std::size_t __n) : __allocator_(), __ptr_(__allocator_.allocate(__n)), __buf_size_(__n) {}
36*4c3eb207Smrg
37*4c3eb207Smrg operator bool() const { return __ptr_ != nullptr; }
38*4c3eb207Smrg _Tp*
get()39*4c3eb207Smrg get() const
40*4c3eb207Smrg {
41*4c3eb207Smrg return __ptr_;
42*4c3eb207Smrg }
~__buffer()43*4c3eb207Smrg ~__buffer() { __allocator_.deallocate(__ptr_, __buf_size_); }
44*4c3eb207Smrg };
45*4c3eb207Smrg
46*4c3eb207Smrg inline void
__cancel_execution()47*4c3eb207Smrg __cancel_execution()
48*4c3eb207Smrg {
49*4c3eb207Smrg }
50*4c3eb207Smrg
51*4c3eb207Smrg template <class _ExecutionPolicy, class _Index, class _Fp>
52*4c3eb207Smrg void
__parallel_for(_ExecutionPolicy &&,_Index __first,_Index __last,_Fp __f)53*4c3eb207Smrg __parallel_for(_ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f)
54*4c3eb207Smrg {
55*4c3eb207Smrg __f(__first, __last);
56*4c3eb207Smrg }
57*4c3eb207Smrg
58*4c3eb207Smrg template <class _ExecutionPolicy, class _Value, class _Index, typename _RealBody, typename _Reduction>
59*4c3eb207Smrg _Value
__parallel_reduce(_ExecutionPolicy &&,_Index __first,_Index __last,const _Value & __identity,const _RealBody & __real_body,const _Reduction &)60*4c3eb207Smrg __parallel_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, const _Value& __identity,
61*4c3eb207Smrg const _RealBody& __real_body, const _Reduction&)
62*4c3eb207Smrg {
63*4c3eb207Smrg if (__first == __last)
64*4c3eb207Smrg {
65*4c3eb207Smrg return __identity;
66*4c3eb207Smrg }
67*4c3eb207Smrg else
68*4c3eb207Smrg {
69*4c3eb207Smrg return __real_body(__first, __last, __identity);
70*4c3eb207Smrg }
71*4c3eb207Smrg }
72*4c3eb207Smrg
73*4c3eb207Smrg template <class _ExecutionPolicy, class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce>
74*4c3eb207Smrg _Tp
__parallel_transform_reduce(_ExecutionPolicy &&,_Index __first,_Index __last,_UnaryOp,_Tp __init,_BinaryOp,_Reduce __reduce)75*4c3eb207Smrg __parallel_transform_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp,
76*4c3eb207Smrg _Reduce __reduce)
77*4c3eb207Smrg {
78*4c3eb207Smrg return __reduce(__first, __last, __init);
79*4c3eb207Smrg }
80*4c3eb207Smrg
81*4c3eb207Smrg template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap>
82*4c3eb207Smrg void
__parallel_strict_scan(_ExecutionPolicy &&,_Index __n,_Tp __initial,_Rp __reduce,_Cp __combine,_Sp __scan,_Ap __apex)83*4c3eb207Smrg __parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __reduce, _Cp __combine, _Sp __scan,
84*4c3eb207Smrg _Ap __apex)
85*4c3eb207Smrg {
86*4c3eb207Smrg _Tp __sum = __initial;
87*4c3eb207Smrg if (__n)
88*4c3eb207Smrg __sum = __combine(__sum, __reduce(_Index(0), __n));
89*4c3eb207Smrg __apex(__sum);
90*4c3eb207Smrg if (__n)
91*4c3eb207Smrg __scan(_Index(0), __n, __initial);
92*4c3eb207Smrg }
93*4c3eb207Smrg
94*4c3eb207Smrg template <class _ExecutionPolicy, class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce, class _Scan>
95*4c3eb207Smrg _Tp
__parallel_transform_scan(_ExecutionPolicy &&,_Index __n,_UnaryOp,_Tp __init,_BinaryOp,_Reduce,_Scan __scan)96*4c3eb207Smrg __parallel_transform_scan(_ExecutionPolicy&&, _Index __n, _UnaryOp, _Tp __init, _BinaryOp, _Reduce, _Scan __scan)
97*4c3eb207Smrg {
98*4c3eb207Smrg return __scan(_Index(0), __n, __init);
99*4c3eb207Smrg }
100*4c3eb207Smrg
101*4c3eb207Smrg template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
102*4c3eb207Smrg void
103*4c3eb207Smrg __parallel_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
104*4c3eb207Smrg _LeafSort __leaf_sort, std::size_t = 0)
105*4c3eb207Smrg {
106*4c3eb207Smrg __leaf_sort(__first, __last, __comp);
107*4c3eb207Smrg }
108*4c3eb207Smrg
109*4c3eb207Smrg template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2,
110*4c3eb207Smrg typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge>
111*4c3eb207Smrg void
__parallel_merge(_ExecutionPolicy &&,_RandomAccessIterator1 __first1,_RandomAccessIterator1 __last1,_RandomAccessIterator2 __first2,_RandomAccessIterator2 __last2,_RandomAccessIterator3 __out,_Compare __comp,_LeafMerge __leaf_merge)112*4c3eb207Smrg __parallel_merge(_ExecutionPolicy&&, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
113*4c3eb207Smrg _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _RandomAccessIterator3 __out,
114*4c3eb207Smrg _Compare __comp, _LeafMerge __leaf_merge)
115*4c3eb207Smrg {
116*4c3eb207Smrg __leaf_merge(__first1, __last1, __first2, __last2, __out, __comp);
117*4c3eb207Smrg }
118*4c3eb207Smrg
119*4c3eb207Smrg template <class _ExecutionPolicy, typename _F1, typename _F2>
120*4c3eb207Smrg void
__parallel_invoke(_ExecutionPolicy &&,_F1 && __f1,_F2 && __f2)121*4c3eb207Smrg __parallel_invoke(_ExecutionPolicy&&, _F1&& __f1, _F2&& __f2)
122*4c3eb207Smrg {
123*4c3eb207Smrg std::forward<_F1>(__f1)();
124*4c3eb207Smrg std::forward<_F2>(__f2)();
125*4c3eb207Smrg }
126*4c3eb207Smrg
127*4c3eb207Smrg } // namespace __serial
128*4c3eb207Smrg } // namespace __pstl
129*4c3eb207Smrg
130*4c3eb207Smrg namespace __pstl
131*4c3eb207Smrg {
132*4c3eb207Smrg namespace __par_backend
133*4c3eb207Smrg {
134*4c3eb207Smrg using namespace __pstl::__serial;
135*4c3eb207Smrg }
136*4c3eb207Smrg } // namespace __pstl
137*4c3eb207Smrg
138*4c3eb207Smrg #endif /* _PSTL_PARALLEL_BACKEND_SERIAL_H */
139