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(__pstl::__internal::__serial_backend_tag, _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(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last,
     61                   const _Value& __identity, 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(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last,
     76                             _UnaryOp, _Tp __init, _BinaryOp, _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(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __n, _Tp __initial,
     84                        _Rp __reduce, _Cp __combine, _Sp __scan, _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(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __n, _UnaryOp,
     97                           _Tp __init, _BinaryOp, _Reduce, _Scan __scan)
     98 {
     99     return __scan(_Index(0), __n, __init);
    100 }
    101 
    102 template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
    103 void
    104 __parallel_stable_sort(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first,
    105                        _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort, std::size_t = 0)
    106 {
    107     __leaf_sort(__first, __last, __comp);
    108 }
    109 
    110 template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2,
    111           typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge>
    112 void
    113 __parallel_merge(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator1 __first1,
    114                  _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2,
    115                  _RandomAccessIterator3 __outit, _Compare __comp, _LeafMerge __leaf_merge)
    116 {
    117     __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
    118 }
    119 
    120 template <class _ExecutionPolicy, typename _F1, typename _F2>
    121 void
    122 __parallel_invoke(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _F1&& __f1, _F2&& __f2)
    123 {
    124     std::forward<_F1>(__f1)();
    125     std::forward<_F2>(__f2)();
    126 }
    127 
    128 } // namespace __serial_backend
    129 } // namespace __pstl
    130 
    131 #endif /* _PSTL_PARALLEL_BACKEND_SERIAL_H */
    132