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