diff --git a/documentation/library_guide/macros.rst b/documentation/library_guide/macros.rst index 2a1b5e4f8b2..a18ba670ee5 100644 --- a/documentation/library_guide/macros.rst +++ b/documentation/library_guide/macros.rst @@ -99,12 +99,16 @@ Macro Description If all parallel backends are disabled by setting respective macros to 0, algorithms with parallel policies are executed sequentially by the calling thread. ---------------------------------- ------------------------------ -``ONEDPL_USE_DPCPP_BACKEND`` This macro enables the use of the device execution policies. - When the macro is not defined (by default) - or evaluates to non-zero, device policies are enabled. - When the macro is set to 0 there is no dependency on - the |dpcpp_cpp| and runtime libraries. - Trying to use device policies will lead to compilation errors. +``ONEDPL_USE_DPCPP_BACKEND`` This macro enables the use of device execution policies. + + When the macro is not defined (default), + device policies are enabled only if SYCL support can be detected; + otherwise, they are disabled. + If the macro is set to a non-zero value, device policies are enabled unconditionally. + Setting the macro to 0 disables device policies. + + When device policies are disabled, no SYCL dependency is introduced, + and their usage will lead to compilation errors. ---------------------------------- ------------------------------ ``ONEDPL_USE_PREDEFINED_POLICIES`` This macro enables the use of predefined device policy objects, such as ``dpcpp_default`` and ``dpcpp_fpga``. When the macro is not defined (by default) diff --git a/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl.h b/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl.h index 77b2e6c35f9..68dd00188dd 100644 --- a/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl.h +++ b/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl.h @@ -44,7 +44,9 @@ #include "unseq_backend_sycl.h" #include "utils_ranges_sycl.h" -#if _USE_RADIX_SORT +#define _ONEDPL_USE_RADIX_SORT (_ONEDPL_USE_SUB_GROUPS && _ONEDPL_USE_GROUP_ALGOS) + +#if _ONEDPL_USE_RADIX_SORT # include "parallel_backend_sycl_radix_sort.h" #endif @@ -2069,16 +2071,16 @@ template struct __is_radix_sort_usable_for_type { static constexpr bool value = -#if _USE_RADIX_SORT +#if _ONEDPL_USE_RADIX_SORT (::std::is_arithmetic_v<_T> || ::std::is_same_v) && (__internal::__is_comp_ascending<::std::decay_t<_Compare>>::value || __internal::__is_comp_descending<::std::decay_t<_Compare>>::value); #else false; -#endif +#endif // _ONEDPL_USE_RADIX_SORT }; -#if _USE_RADIX_SORT +#if _ONEDPL_USE_RADIX_SORT template < typename _ExecutionPolicy, typename _Range, typename _Compare, typename _Proj, ::std::enable_if_t< @@ -2090,7 +2092,7 @@ __parallel_stable_sort(oneapi::dpl::__internal::__device_backend_tag __backend_t return __parallel_radix_sort<__internal::__is_comp_ascending<::std::decay_t<_Compare>>::value>( __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range>(__rng), __proj); } -#endif +#endif // _ONEDPL_USE_RADIX_SORT template < typename _ExecutionPolicy, typename _Range, typename _Compare, typename _Proj, diff --git a/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_utils.h b/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_utils.h index e7fbfb7ae7c..f4eb557170e 100644 --- a/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_utils.h +++ b/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_utils.h @@ -77,7 +77,7 @@ __slm_adjusted_work_group_size(const _ExecutionPolicy& __policy, _Size __local_m return sycl::min(__local_mem_size / __local_mem_per_wi, __wg_size); } -#if _USE_SUB_GROUPS +#if _ONEDPL_USE_SUB_GROUPS template ::std::size_t __max_sub_group_size(const _ExecutionPolicy& __policy) @@ -86,7 +86,7 @@ __max_sub_group_size(const _ExecutionPolicy& __policy) //The result of get_info() can be empty; if so, return 0 return __supported_sg_sizes.empty() ? 0 : __supported_sg_sizes.back(); } -#endif +#endif // _ONEDPL_USE_SUB_GROUPS template ::std::uint32_t diff --git a/include/oneapi/dpl/pstl/hetero/dpcpp/sycl_defs.h b/include/oneapi/dpl/pstl/hetero/dpcpp/sycl_defs.h index 83c44a8a07d..fbe9bd24080 100644 --- a/include/oneapi/dpl/pstl/hetero/dpcpp/sycl_defs.h +++ b/include/oneapi/dpl/pstl/hetero/dpcpp/sycl_defs.h @@ -26,6 +26,13 @@ #else # include #endif + +// If SYCL_LANGUAGE_VERSION is still not set after including the SYCL header, issue an error +#if !(SYCL_LANGUAGE_VERSION || CL_SYCL_LANGUAGE_VERSION) +# error "Device execution policies are enabled, \ + but SYCL_LANGUAGE_VERSION/CL_SYCL_LANGUAGE_VERSION macros are not defined" +#endif + #include // Combine SYCL runtime library version diff --git a/include/oneapi/dpl/pstl/hetero/dpcpp/unseq_backend_sycl.h b/include/oneapi/dpl/pstl/hetero/dpcpp/unseq_backend_sycl.h index b17c619de89..2caa6add318 100644 --- a/include/oneapi/dpl/pstl/hetero/dpcpp/unseq_backend_sycl.h +++ b/include/oneapi/dpl/pstl/hetero/dpcpp/unseq_backend_sycl.h @@ -30,7 +30,7 @@ namespace dpl namespace unseq_backend { -#if _USE_GROUP_ALGOS && defined(SYCL_IMPLEMENTATION_INTEL) +#if _ONEDPL_USE_GROUP_ALGOS && defined(SYCL_IMPLEMENTATION_INTEL) //This optimization depends on Intel(R) oneAPI DPC++ Compiler implementation such as support of binary operators from std namespace. //We need to use defined(SYCL_IMPLEMENTATION_INTEL) macro as a guard. @@ -71,12 +71,12 @@ using __has_known_identity = ::std::conditional_t< # endif //_ONEDPL_LIBSYCL_VERSION >= 50200 ::std::false_type>; // This is for the case of __can_use_known_identity<_Tp>==false -#else //_USE_GROUP_ALGOS && defined(SYCL_IMPLEMENTATION_INTEL) +#else //_ONEDPL_USE_GROUP_ALGOS && defined(SYCL_IMPLEMENTATION_INTEL) template using __has_known_identity = std::false_type; -#endif //_USE_GROUP_ALGOS && defined(SYCL_IMPLEMENTATION_INTEL) +#endif //_ONEDPL_USE_GROUP_ALGOS && defined(SYCL_IMPLEMENTATION_INTEL) template struct __known_identity_for_plus diff --git a/include/oneapi/dpl/pstl/onedpl_config.h b/include/oneapi/dpl/pstl/onedpl_config.h index 2ef13c46f83..05b91087078 100644 --- a/include/oneapi/dpl/pstl/onedpl_config.h +++ b/include/oneapi/dpl/pstl/onedpl_config.h @@ -16,27 +16,11 @@ #ifndef _ONEDPL_CONFIG_H #define _ONEDPL_CONFIG_H -#include "../internal/version_impl.h" // The version header also defines a few configuration macros used in this file +#include "../internal/version_impl.h" -#if defined(ONEDPL_FPGA_DEVICE) -# undef _ONEDPL_FPGA_DEVICE -# define _ONEDPL_FPGA_DEVICE ONEDPL_FPGA_DEVICE -#endif - -#if defined(ONEDPL_FPGA_EMULATOR) -# undef _ONEDPL_FPGA_EMU -# define _ONEDPL_FPGA_EMU ONEDPL_FPGA_EMULATOR -#endif - -#if defined(ONEDPL_USE_PREDEFINED_POLICIES) -# undef _ONEDPL_PREDEFINED_POLICIES -# define _ONEDPL_PREDEFINED_POLICIES ONEDPL_USE_PREDEFINED_POLICIES -#elif !defined(_ONEDPL_PREDEFINED_POLICIES) -# define _ONEDPL_PREDEFINED_POLICIES 1 -#endif +// -- Check availability of parallel backends -- -// Check availability of parallel backends #if __has_include() # define _ONEDPL_TBB_AVAILABLE 1 #endif @@ -54,15 +38,35 @@ but OpenMP headers are not found or the compiler does not support OpenMP" #endif -#if (defined(SYCL_LANGUAGE_VERSION) || defined(CL_SYCL_LANGUAGE_VERSION)) && \ - (__has_include() || __has_include()) -# define _ONEDPL_SYCL_AVAILABLE 1 +// -- Check availability of heterogeneous backends -- + +// If DPCPP backend is explicitly requested, optimistically assume SYCL availability; +// otherwise, make sure that it is definitely available additionally checking SYCL_LANGUAGE_VERSION +#if __has_include() || __has_include() +# if SYCL_LANGUAGE_VERSION || CL_SYCL_LANGUAGE_VERSION || ONEDPL_USE_DPCPP_BACKEND +# define _ONEDPL_SYCL_AVAILABLE 1 +# endif +#else +# if ONEDPL_USE_DPCPP_BACKEND +# error "Device execution policies are requested, but SYCL* headers are not found" +# endif #endif -#if ONEDPL_USE_DPCPP_BACKEND && !_ONEDPL_SYCL_AVAILABLE -# error "Device execution policies are enabled, \ - but SYCL* headers are not found or the compiler does not support SYCL" + +// If DPCPP backend is not explicitly turned off and SYCL is available, enable it +#if (ONEDPL_USE_DPCPP_BACKEND || !defined(ONEDPL_USE_DPCPP_BACKEND)) && _ONEDPL_SYCL_AVAILABLE +# define _ONEDPL_BACKEND_SYCL 1 #endif +// If at least one heterogeneous backend is available, enable them +#if _ONEDPL_BACKEND_SYCL +# if _ONEDPL_HETERO_BACKEND +# undef _ONEDPL_HETERO_BACKEND +# endif +# define _ONEDPL_HETERO_BACKEND 1 +#endif + +// -- Configure host backends and common parts -- + // Check the user-defined macro for warnings #if !defined(_PSTL_USAGE_WARNINGS) && defined(PSTL_USAGE_WARNINGS) # define _PSTL_USAGE_WARNINGS PSTL_USAGE_WARNINGS @@ -252,37 +256,6 @@ #define _ONEDPL_HAS_NUMERIC_SERIAL_IMPL \ (__GLIBCXX__ && (_GLIBCXX_RELEASE < 9 || (_GLIBCXX_RELEASE == 9 && __GLIBCXX__ < 20200312))) -#if ONEDPL_USE_DPCPP_BACKEND || (!defined(ONEDPL_USE_DPCPP_BACKEND) && _ONEDPL_SYCL_AVAILABLE) -# define _ONEDPL_BACKEND_SYCL 1 -#endif - -// if SYCL policy switch on then let's switch hetero policy macro on -#if _ONEDPL_BACKEND_SYCL -# if _ONEDPL_HETERO_BACKEND -# undef _ONEDPL_HETERO_BACKEND -# endif -# define _ONEDPL_HETERO_BACKEND 1 -// Include sycl specific options -// FPGA doesn't support sub-groups -# if !(_ONEDPL_FPGA_DEVICE) -# define _USE_SUB_GROUPS 1 -# define _USE_GROUP_ALGOS 1 -# endif - -# define _USE_RADIX_SORT (_USE_SUB_GROUPS && _USE_GROUP_ALGOS) - -// Compilation of a kernel is requiried to obtain valid work_group_size -// when target devices are CPU or FPGA emulator. Since CPU and GPU devices -// cannot be distinguished during compilation, the macro is enabled by default. -# if !defined(_ONEDPL_COMPILE_KERNEL) -# define _ONEDPL_COMPILE_KERNEL 1 -# endif -#endif - -#if !defined(ONEDPL_ALLOW_DEFERRED_WAITING) -# define ONEDPL_ALLOW_DEFERRED_WAITING 0 -#endif - //'present' macros // shift_left, shift_right; GCC 10; VS 2019 16.1 #define _ONEDPL_CPP20_SHIFT_LEFT_RIGHT_PRESENT \ @@ -311,8 +284,6 @@ # define _ONEDPL_CPP20_REQUIRES(req) #endif -#define _ONEDPL_BUILT_IN_STABLE_NAME_PRESENT __has_builtin(__builtin_sycl_unique_stable_name) - #if defined(_MSC_VER) && __INTEL_LLVM_COMPILER < 20240100 # define _ONEDPL_ICPX_OMP_SIMD_DESTROY_WINDOWS_BROKEN 1 #else @@ -333,4 +304,44 @@ # define _ONEDPL_STD_RANGES_ALGO_CPP_FUN 0 #endif +// -- Configure heterogeneous backends -- + +#if !defined(ONEDPL_ALLOW_DEFERRED_WAITING) +# define ONEDPL_ALLOW_DEFERRED_WAITING 0 +#endif + +#if defined(ONEDPL_USE_PREDEFINED_POLICIES) +# undef _ONEDPL_PREDEFINED_POLICIES +# define _ONEDPL_PREDEFINED_POLICIES ONEDPL_USE_PREDEFINED_POLICIES +#elif !defined(_ONEDPL_PREDEFINED_POLICIES) +# define _ONEDPL_PREDEFINED_POLICIES 1 +#endif + +#if defined(ONEDPL_FPGA_DEVICE) +# undef _ONEDPL_FPGA_DEVICE +# define _ONEDPL_FPGA_DEVICE ONEDPL_FPGA_DEVICE +#endif +#if defined(ONEDPL_FPGA_EMULATOR) +# undef _ONEDPL_FPGA_EMU +# define _ONEDPL_FPGA_EMU ONEDPL_FPGA_EMULATOR +#endif + +#if _ONEDPL_BACKEND_SYCL +// Include sycl specific options +// FPGA doesn't support sub-groups +# if !(_ONEDPL_FPGA_DEVICE) +# define _ONEDPL_USE_SUB_GROUPS 1 +# define _ONEDPL_USE_GROUP_ALGOS 1 +# endif + +// Compilation of a kernel is requiried to obtain valid work_group_size +// when target devices are CPU or FPGA emulator. Since CPU and GPU devices +// cannot be distinguished during compilation, the macro is enabled by default. +# if !defined(_ONEDPL_COMPILE_KERNEL) +# define _ONEDPL_COMPILE_KERNEL 1 +# endif + +# define _ONEDPL_BUILT_IN_STABLE_NAME_PRESENT __has_builtin(__builtin_sycl_unique_stable_name) +#endif // _ONEDPL_BACKEND_SYCL + #endif // _ONEDPL_CONFIG_H diff --git a/test/support/test_config.h b/test/support/test_config.h index 5814a4a4a07..b0fe4c8a9c9 100644 --- a/test/support/test_config.h +++ b/test/support/test_config.h @@ -29,7 +29,7 @@ // // This section contains macros representing the "Latest" version of compilers, STL implementations, etc. for use in // broken macros to represent the latest version of something which still has an ongoing issue. The intention is to -// update this section regularly to reflect the latest version. +// update this section regularly to reflect the latest version. // // When such an issue is fixed, we must replace the usage of these "Latest" macros with the appropriate version number // before updating to the newest version in this section. @@ -88,13 +88,20 @@ #define _PSTL_SYCL_TEST_USM 1 -// Enable test when the DPC++ backend is available -#if ((defined(CL_SYCL_LANGUAGE_VERSION) || defined(SYCL_LANGUAGE_VERSION)) && \ - (__has_include() || __has_include())) && \ - (!defined(ONEDPL_USE_DPCPP_BACKEND) || ONEDPL_USE_DPCPP_BACKEND != 0) -#define TEST_DPCPP_BACKEND_PRESENT 1 +#define TEST_SYCL_HEADER_PRESENT (__has_include() || __has_include()) +#define TEST_SYCL_LANGUAGE_VERSION_PRESENT (SYCL_LANGUAGE_VERSION || CL_SYCL_LANGUAGE_VERSION) +#define TEST_SYCL_AVAILABLE (TEST_SYCL_HEADER_PRESENT && TEST_SYCL_LANGUAGE_VERSION_PRESENT) + +// If SYCL is available, and DPCPP backend is not explicitly turned off, enable its testing +#if TEST_SYCL_AVAILABLE && !defined(ONEDPL_USE_DPCPP_BACKEND) +# define TEST_DPCPP_BACKEND_PRESENT 1 +// If DPCPP backend was explicitly requested, enable its testing, even if SYCL availability has not been proven +// this can be used to force DPCPP backend testing for environments where SYCL_LANGUAGE_VERSION is not predefined +#elif ONEDPL_USE_DPCPP_BACKEND +# define TEST_DPCPP_BACKEND_PRESENT 1 +// Define to 0 in other cases since some tests may rely at the macro value at runtime #else -#define TEST_DPCPP_BACKEND_PRESENT 0 +# define TEST_DPCPP_BACKEND_PRESENT 0 #endif #ifdef __SYCL_UNNAMED_LAMBDA__