diff --git a/pstl/CMakeLists.txt b/pstl/CMakeLists.txt index d8614a06fa38..a11487ffe93f 100644 --- a/pstl/CMakeLists.txt +++ b/pstl/CMakeLists.txt @@ -35,19 +35,16 @@ add_library(pstl::ParallelSTL ALIAS ParallelSTL) target_compile_features(ParallelSTL INTERFACE cxx_std_17) if (PARALLELSTL_USE_PARALLEL_POLICIES) - message(STATUS "Using Parallel Policies") - if (PARALLELSTL_BACKEND STREQUAL "tbb") + if (PARALLELSTL_BACKEND STREQUAL "serial") + message(STATUS "Parallel STL uses the serial backend") + target_compile_definitions(ParallelSTL INTERFACE -D_PSTL_PAR_BACKEND_SERIAL) + elseif (PARALLELSTL_BACKEND STREQUAL "tbb") find_package(TBB 2018 REQUIRED tbb OPTIONAL_COMPONENTS tbbmalloc) message(STATUS "Parallel STL uses TBB ${TBB_VERSION} (interface version: ${TBB_INTERFACE_VERSION})") target_link_libraries(ParallelSTL INTERFACE TBB::tbb) - else() - message(STATUS "Using Parallel Policies, but not tbb") - if (TARGET ${PARALLELSTL_BACKEND}) - target_link_libraries(ParallelSTL INTERFACE ${PARALLELSTL_BACKEND}) - else() - find_package(${PARALLELSTL_BACKEND} REQUIRED) - target_link_libraries(ParallelSTL INTERFACE ${${PARALLELSTL_BACKEND}_IMPORTED_TARGETS}) - endif() + target_compile_definitions(ParallelSTL INTERFACE -D_PSTL_PAR_BACKEND_TBB) + else() + message(FATAL_ERROR "Requested unknown Parallel STL backend '${PARALLELSTL_BACKEND}'.") endif() else() target_compile_definitions(ParallelSTL INTERFACE PSTL_USE_PARALLEL_POLICIES=0) diff --git a/pstl/include/pstl/internal/parallel_backend.h b/pstl/include/pstl/internal/parallel_backend.h index 438f87e9f0b4..85d2d4b478a1 100644 --- a/pstl/include/pstl/internal/parallel_backend.h +++ b/pstl/include/pstl/internal/parallel_backend.h @@ -10,7 +10,9 @@ #ifndef _PSTL_PARALLEL_BACKEND_H #define _PSTL_PARALLEL_BACKEND_H -#if _PSTL_PAR_BACKEND_TBB +#if defined(_PSTL_PAR_BACKEND_SERIAL) +# include "parallel_backend_serial.h" +#elif defined(_PSTL_PAR_BACKEND_TBB) # include "parallel_backend_tbb.h" #else _PSTL_PRAGMA_MESSAGE("Parallel backend was not specified"); diff --git a/pstl/include/pstl/internal/parallel_backend_serial.h b/pstl/include/pstl/internal/parallel_backend_serial.h new file mode 100644 index 000000000000..e4b3a700d1f8 --- /dev/null +++ b/pstl/include/pstl/internal/parallel_backend_serial.h @@ -0,0 +1,138 @@ +// -*- C++ -*- +//===-- parallel_backend_serial.h -----------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _PSTL_PARALLEL_BACKEND_SERIAL_H +#define _PSTL_PARALLEL_BACKEND_SERIAL_H + +#include +#include +#include +#include +#include + +namespace __pstl +{ +namespace __serial +{ + +template +class __buffer +{ + std::allocator<_Tp> __allocator_; + _Tp* __ptr_; + const std::size_t __buf_size_; + __buffer(const __buffer&) = delete; + void + operator=(const __buffer&) = delete; + + public: + __buffer(std::size_t __n) : __allocator_(), __ptr_(__allocator_.allocate(__n)), __buf_size_(__n) {} + + operator bool() const { return __ptr_ != nullptr; } + _Tp* + get() const + { + return __ptr_; + } + ~__buffer() { __allocator_.deallocate(__ptr_, __buf_size_); } +}; + +inline void +__cancel_execution() +{ +} + +template +void +__parallel_for(_ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f) +{ + __f(__first, __last); +} + +template +_Value +__parallel_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, const _Value& __identity, + const _RealBody& __real_body, const _Reduction&) +{ + if (__first == __last) + { + return __identity; + } + else + { + return __real_body(__first, __last, __identity); + } +} + +template +_Tp +__parallel_transform_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, + _Reduce __reduce) +{ + return __reduce(__first, __last, __init); +} + +template +void +__parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __reduce, _Cp __combine, _Sp __scan, + _Ap __apex) +{ + _Tp __sum = __initial; + if (__n) + __sum = __combine(__sum, __reduce(_Index(0), __n)); + __apex(__sum); + if (__n) + __scan(_Index(0), __n, __initial); +} + +template +_Tp +__parallel_transform_scan(_ExecutionPolicy&&, _Index __n, _UnaryOp, _Tp __init, _BinaryOp, _Reduce, _Scan __scan) +{ + return __scan(_Index(0), __n, __init); +} + +template +void +__parallel_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, + _LeafSort __leaf_sort, std::size_t = 0) +{ + __leaf_sort(__first, __last, __comp); +} + +template +void +__parallel_merge(_ExecutionPolicy&&, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _RandomAccessIterator3 __out, + _Compare __comp, _LeafMerge __leaf_merge) +{ + __leaf_merge(__first1, __last1, __first2, __last2, __out, __comp); +} + +template +void +__parallel_invoke(_ExecutionPolicy&&, _F1&& __f1, _F2&& __f2) +{ + std::forward<_F1>(__f1)(); + std::forward<_F2>(__f2)(); +} + +} // namespace __serial +} // namespace __pstl + +namespace __pstl +{ +namespace __par_backend +{ +using namespace __pstl::__serial; +} +} // namespace __pstl + +#endif /* _PSTL_PARALLEL_BACKEND_SERIAL_H */ diff --git a/pstl/include/pstl/internal/pstl_config.h b/pstl/include/pstl/internal/pstl_config.h index e6728d39ffbb..7f32725ad689 100644 --- a/pstl/include/pstl/internal/pstl_config.h +++ b/pstl/include/pstl/internal/pstl_config.h @@ -25,12 +25,8 @@ # define _PSTL_USE_PAR_POLICIES 1 #endif -#if _PSTL_USE_PAR_POLICIES -# if !defined(_PSTL_PAR_BACKEND_TBB) -# define _PSTL_PAR_BACKEND_TBB 1 -# endif -#else -# undef _PSTL_PAR_BACKEND_TBB +#if !defined(_PSTL_PAR_BACKEND_SERIAL) && !defined(_PSTL_PAR_BACKEND_TBB) +# error "The parallel backend is neither serial nor TBB" #endif // Check the user-defined macro for warnings