Skip to content

Commit

Permalink
Make SYCL backend detection more portable (#1881)
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitriy Sobolev <[email protected]>
  • Loading branch information
dmitriy-sobolev authored Nov 15, 2024
1 parent 91f1cd4 commit 658621d
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 80 deletions.
16 changes: 10 additions & 6 deletions documentation/library_guide/macros.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
12 changes: 7 additions & 5 deletions include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -2069,16 +2071,16 @@ template <typename _T, typename _Compare>
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<sycl::half, _T>) &&
(__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<
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename _ExecutionPolicy>
::std::size_t
__max_sub_group_size(const _ExecutionPolicy& __policy)
Expand All @@ -86,7 +86,7 @@ __max_sub_group_size(const _ExecutionPolicy& __policy)
//The result of get_info<sycl::info::device::sub_group_sizes>() can be empty; if so, return 0
return __supported_sg_sizes.empty() ? 0 : __supported_sg_sizes.back();
}
#endif
#endif // _ONEDPL_USE_SUB_GROUPS

template <typename _ExecutionPolicy>
::std::uint32_t
Expand Down
7 changes: 7 additions & 0 deletions include/oneapi/dpl/pstl/hetero/dpcpp/sycl_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
#else
# include <CL/sycl.hpp>
#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 <memory>
// Combine SYCL runtime library version
Expand Down
6 changes: 3 additions & 3 deletions include/oneapi/dpl/pstl/hetero/dpcpp/unseq_backend_sycl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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 <typename _BinaryOp, typename _Tp>
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 <typename _BinaryOp, typename _Tp>
struct __known_identity_for_plus
Expand Down
125 changes: 68 additions & 57 deletions include/oneapi/dpl/pstl/onedpl_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(<tbb/tbb.h>)
# define _ONEDPL_TBB_AVAILABLE 1
#endif
Expand All @@ -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(<sycl/sycl.hpp>) || __has_include(<CL/sycl.hpp>))
# 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(<sycl/sycl.hpp>) || __has_include(<CL/sycl.hpp>)
# 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
Expand Down Expand Up @@ -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 \
Expand Down Expand Up @@ -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
Expand All @@ -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
21 changes: 14 additions & 7 deletions test/support/test_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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(<sycl/sycl.hpp>) || __has_include(<CL/sycl.hpp>))) && \
(!defined(ONEDPL_USE_DPCPP_BACKEND) || ONEDPL_USE_DPCPP_BACKEND != 0)
#define TEST_DPCPP_BACKEND_PRESENT 1
#define TEST_SYCL_HEADER_PRESENT (__has_include(<sycl/sycl.hpp>) || __has_include(<CL/sycl.hpp>))
#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__
Expand Down

0 comments on commit 658621d

Please sign in to comment.