Home | History | Annotate | Line # | Download | only in pstl
      1 // -*- C++ -*-
      2 //===-- parallel_backend_serial.h -----------------------------------------===//
      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 namespace __pstl
     20 {
     21 namespace __serial_backend
     22 {
     23 
     24 template <typename _Tp>
     25 class __buffer
     26 {
     27     std::allocator<_Tp> __allocator_;
     28     _Tp* __ptr_;
     29     const std::size_t __buf_size_;
     30     __buffer(const __buffer&) = delete;
     31     void
     32     operator=(const __buffer&) = delete;
     33 
     34   public:
     35     __buffer(std::size_t __n) : __allocator_(), __ptr_(__allocator_.allocate(__n)), __buf_size_(__n) {}
     36 
     37     operator bool() const { return __ptr_ != nullptr; }
     38     _Tp*
     39     get() const
     40     {
     41         return __ptr_;
     42     }
     43     ~__buffer() { __allocator_.deallocate(__ptr_, __buf_size_); }
     44 };
     45 
     46 inline void
     47 __cancel_execution()
     48 {
     49 }
     50 
     51 template <class _ExecutionPolicy, class _Index, class _Fp>
     52 void
     53 __parallel_for(_ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f)
     54 {
     55     __f(__first, __last);
     56 }
     57 
     58 template <class _ExecutionPolicy, class _Value, class _Index, typename _RealBody, typename _Reduction>
     59 _Value
     60 __parallel_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, const _Value& __identity,
     61                   const _RealBody& __real_body, const _Reduction&)
     62 {
     63     if (__first == __last)
     64     {
     65         return __identity;
     66     }
     67     else
     68     {
     69         return __real_body(__first, __last, __identity);
     70     }
     71 }
     72 
     73 template <class _ExecutionPolicy, class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce>
     74 _Tp
     75 __parallel_transform_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp,
     76                             _Reduce __reduce)
     77 {
     78     return __reduce(__first, __last, __init);
     79 }
     80 
     81 template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap>
     82 void
     83 __parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __reduce, _Cp __combine, _Sp __scan,
     84                        _Ap __apex)
     85 {
     86     _Tp __sum = __initial;
     87     if (__n)
     88         __sum = __combine(__sum, __reduce(_Index(0), __n));
     89     __apex(__sum);
     90     if (__n)
     91         __scan(_Index(0), __n, __initial);
     92 }
     93 
     94 template <class _ExecutionPolicy, class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce, class _Scan>
     95 _Tp
     96 __parallel_transform_scan(_ExecutionPolicy&&, _Index __n, _UnaryOp, _Tp __init, _BinaryOp, _Reduce, _Scan __scan)
     97 {
     98     return __scan(_Index(0), __n, __init);
     99 }
    100 
    101 template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
    102 void
    103 __parallel_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
    104                        _LeafSort __leaf_sort, std::size_t = 0)
    105 {
    106     __leaf_sort(__first, __last, __comp);
    107 }
    108 
    109 template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2,
    110           typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge>
    111 void
    112 __parallel_merge(_ExecutionPolicy&&, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
    113                  _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _RandomAccessIterator3 __outit,
    114                  _Compare __comp, _LeafMerge __leaf_merge)
    115 {
    116     __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
    117 }
    118 
    119 template <class _ExecutionPolicy, typename _F1, typename _F2>
    120 void
    121 __parallel_invoke(_ExecutionPolicy&&, _F1&& __f1, _F2&& __f2)
    122 {
    123     std::forward<_F1>(__f1)();
    124     std::forward<_F2>(__f2)();
    125 }
    126 
    127 } // namespace __serial_backend
    128 } // namespace __pstl
    129 
    130 #endif /* _PSTL_PARALLEL_BACKEND_SERIAL_H */
    131