1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef _LIBCPP___PSTL_BACKENDS_STD_THREAD_H 10 #define _LIBCPP___PSTL_BACKENDS_STD_THREAD_H 11 12 #include <__config> 13 #include <__pstl/backend_fwd.h> 14 #include <__pstl/cpu_algos/any_of.h> 15 #include <__pstl/cpu_algos/cpu_traits.h> 16 #include <__pstl/cpu_algos/fill.h> 17 #include <__pstl/cpu_algos/find_if.h> 18 #include <__pstl/cpu_algos/for_each.h> 19 #include <__pstl/cpu_algos/merge.h> 20 #include <__pstl/cpu_algos/stable_sort.h> 21 #include <__pstl/cpu_algos/transform.h> 22 #include <__pstl/cpu_algos/transform_reduce.h> 23 #include <__utility/empty.h> 24 #include <__utility/move.h> 25 #include <optional> 26 27 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 28 # pragma GCC system_header 29 #endif 30 31 _LIBCPP_PUSH_MACROS 32 #include <__undef_macros> 33 34 #if _LIBCPP_STD_VER >= 17 35 36 _LIBCPP_BEGIN_NAMESPACE_STD 37 namespace __pstl { 38 39 // 40 // This partial backend implementation is for testing purposes only and not meant for production use. This will be 41 // replaced by a proper implementation once the PSTL implementation is somewhat stable. 42 // 43 // This is intended to be used on top of the "default backend". 44 // 45 46 template <> 47 struct __cpu_traits<__std_thread_backend_tag> { 48 template <class _RandomAccessIterator, class _Fp> 49 _LIBCPP_HIDE_FROM_ABI static optional<__empty> 50 __for_each(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) { 51 __f(__first, __last); 52 return __empty{}; 53 } 54 55 template <class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce> 56 _LIBCPP_HIDE_FROM_ABI static optional<_Tp> 57 __transform_reduce(_Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce) { 58 return __reduce(std::move(__first), std::move(__last), std::move(__init)); 59 } 60 61 template <class _RandomAccessIterator, class _Compare, class _LeafSort> 62 _LIBCPP_HIDE_FROM_ABI static optional<__empty> 63 __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort) { 64 __leaf_sort(__first, __last, __comp); 65 return __empty{}; 66 } 67 68 _LIBCPP_HIDE_FROM_ABI static void __cancel_execution() {} 69 70 template <class _RandomAccessIterator1, 71 class _RandomAccessIterator2, 72 class _RandomAccessIterator3, 73 class _Compare, 74 class _LeafMerge> 75 _LIBCPP_HIDE_FROM_ABI static optional<__empty> 76 __merge(_RandomAccessIterator1 __first1, 77 _RandomAccessIterator1 __last1, 78 _RandomAccessIterator2 __first2, 79 _RandomAccessIterator2 __last2, 80 _RandomAccessIterator3 __outit, 81 _Compare __comp, 82 _LeafMerge __leaf_merge) { 83 __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp); 84 return __empty{}; 85 } 86 87 static constexpr size_t __lane_size = 64; 88 }; 89 90 // Mandatory implementations of the computational basis 91 template <class _ExecutionPolicy> 92 struct __find_if<__std_thread_backend_tag, _ExecutionPolicy> 93 : __cpu_parallel_find_if<__std_thread_backend_tag, _ExecutionPolicy> {}; 94 95 template <class _ExecutionPolicy> 96 struct __for_each<__std_thread_backend_tag, _ExecutionPolicy> 97 : __cpu_parallel_for_each<__std_thread_backend_tag, _ExecutionPolicy> {}; 98 99 template <class _ExecutionPolicy> 100 struct __merge<__std_thread_backend_tag, _ExecutionPolicy> 101 : __cpu_parallel_merge<__std_thread_backend_tag, _ExecutionPolicy> {}; 102 103 template <class _ExecutionPolicy> 104 struct __stable_sort<__std_thread_backend_tag, _ExecutionPolicy> 105 : __cpu_parallel_stable_sort<__std_thread_backend_tag, _ExecutionPolicy> {}; 106 107 template <class _ExecutionPolicy> 108 struct __transform<__std_thread_backend_tag, _ExecutionPolicy> 109 : __cpu_parallel_transform<__std_thread_backend_tag, _ExecutionPolicy> {}; 110 111 template <class _ExecutionPolicy> 112 struct __transform_binary<__std_thread_backend_tag, _ExecutionPolicy> 113 : __cpu_parallel_transform_binary<__std_thread_backend_tag, _ExecutionPolicy> {}; 114 115 template <class _ExecutionPolicy> 116 struct __transform_reduce<__std_thread_backend_tag, _ExecutionPolicy> 117 : __cpu_parallel_transform_reduce<__std_thread_backend_tag, _ExecutionPolicy> {}; 118 119 template <class _ExecutionPolicy> 120 struct __transform_reduce_binary<__std_thread_backend_tag, _ExecutionPolicy> 121 : __cpu_parallel_transform_reduce_binary<__std_thread_backend_tag, _ExecutionPolicy> {}; 122 123 // Not mandatory, but better optimized 124 template <class _ExecutionPolicy> 125 struct __any_of<__std_thread_backend_tag, _ExecutionPolicy> 126 : __cpu_parallel_any_of<__std_thread_backend_tag, _ExecutionPolicy> {}; 127 128 template <class _ExecutionPolicy> 129 struct __fill<__std_thread_backend_tag, _ExecutionPolicy> 130 : __cpu_parallel_fill<__std_thread_backend_tag, _ExecutionPolicy> {}; 131 132 } // namespace __pstl 133 _LIBCPP_END_NAMESPACE_STD 134 135 #endif // _LIBCPP_STD_VER >= 17 136 137 _LIBCPP_POP_MACROS 138 139 #endif // _LIBCPP___PSTL_BACKENDS_STD_THREAD_H 140