Skip to content

Commit

Permalink
[SYCL] Use built-ins to retrieve kernel information (#15070)
Browse files Browse the repository at this point in the history
Using built-ins is going to be the preferred way to fetch kernel
information, while integration headers are still going to be used for
cases where built-ins are unavailable (i.e., different host compiler).

Additionally, switch to the new entry point attribute when using the
built-ins.
  • Loading branch information
sergey-semenov committed Sep 10, 2024
1 parent ad494e9 commit c87f6b2
Show file tree
Hide file tree
Showing 7 changed files with 207 additions and 80 deletions.
104 changes: 103 additions & 1 deletion sycl/include/sycl/detail/kernel_desc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,26 @@

// FIXME: include export.hpp because integration header emitted by the compiler
// uses the macro defined in this header, but it doesn't explicitly include it.
#include <sycl/detail/defines_elementary.hpp>
#include <sycl/detail/export.hpp>

// This header file must not include any standard C++ header files.

#ifndef __INTEL_SYCL_USE_INTEGRATION_HEADERS
#if __has_builtin(__builtin_sycl_kernel_name)
static_assert(__has_builtin(__builtin_sycl_kernel_param_count) &&
__has_builtin(__builtin_sycl_kernel_name) &&
__has_builtin(__builtin_sycl_kernel_param_access_target) &&
__has_builtin(__builtin_sycl_kernel_param_size) &&
__has_builtin(__builtin_sycl_kernel_param_offset) &&
__has_builtin(__builtin_sycl_kernel_file_name) &&
__has_builtin(__builtin_sycl_kernel_function_name) &&
__has_builtin(__builtin_sycl_kernel_line_number) &&
__has_builtin(__builtin_sycl_kernel_column_number));
#else
#define __INTEL_SYCL_USE_INTEGRATION_HEADERS 1
#endif
#endif

namespace sycl {
inline namespace _V1 {
namespace detail {
Expand Down Expand Up @@ -151,6 +167,92 @@ template <class KernelNameType> struct KernelInfo {
};
#endif //__SYCL_UNNAMED_LAMBDA__

// Built-ins accept an object due to lacking infrastructure support for
// accepting types. The kernel name type itself isn't used because it might be
// incomplete, cv-qualified, or not default constructible. Passing an object
// also allows future extension for SYCL kernels defined as free functions.
template <typename KNT> struct KernelIdentity {
using type = KNT;
};

template <typename KernelNameType> constexpr unsigned getKernelNumParams() {
#ifndef __INTEL_SYCL_USE_INTEGRATION_HEADERS
return __builtin_sycl_kernel_param_count(KernelIdentity<KernelNameType>());
#else
return KernelInfo<KernelNameType>::getNumParams();
#endif
}

template <typename KernelNameType>
kernel_param_desc_t getKernelParamDesc(int Idx) {
#ifndef __INTEL_SYCL_USE_INTEGRATION_HEADERS
kernel_param_desc_t ParamDesc;
ParamDesc.kind =
__builtin_sycl_kernel_param_kind(KernelIdentity<KernelNameType>(), Idx);
ParamDesc.info = ParamDesc.kind == kernel_param_kind_t::kind_accessor
? __builtin_sycl_kernel_param_access_target(
KernelIdentity<KernelNameType>(), Idx)
: __builtin_sycl_kernel_param_size(
KernelIdentity<KernelNameType>(), Idx);
ParamDesc.offset =
__builtin_sycl_kernel_param_offset(KernelIdentity<KernelNameType>(), Idx);
return ParamDesc;
#else
return KernelInfo<KernelNameType>::getParamDesc(Idx);
#endif
}

template <typename KernelNameType> constexpr const char *getKernelName() {
#ifndef __INTEL_SYCL_USE_INTEGRATION_HEADERS
return __builtin_sycl_kernel_name(KernelIdentity<KernelNameType>());
#else
return KernelInfo<KernelNameType>::getName();
#endif
}

template <typename KernelNameType> constexpr bool isKernelESIMD() {
// TODO Needs a builtin counterpart
return KernelInfo<KernelNameType>::isESIMD();
}

template <typename KernelNameType> constexpr const char *getKernelFileName() {
#ifndef __INTEL_SYCL_USE_INTEGRATION_HEADERS
return __builtin_sycl_kernel_file_name(KernelIdentity<KernelNameType>());
#else
return KernelInfo<KernelNameType>::getFileName();
#endif
}

template <typename KernelNameType>
constexpr const char *getKernelFunctionName() {
#ifndef __INTEL_SYCL_USE_INTEGRATION_HEADERS
return __builtin_sycl_kernel_function_name(KernelIdentity<KernelNameType>());
#else
return KernelInfo<KernelNameType>::getFunctionName();
#endif
}

template <typename KernelNameType> constexpr unsigned getKernelLineNumber() {
#ifndef __INTEL_SYCL_USE_INTEGRATION_HEADERS
return __builtin_sycl_kernel_line_number(KernelIdentity<KernelNameType>());
#else
return KernelInfo<KernelNameType>::getLineNumber();
#endif
}

template <typename KernelNameType> constexpr unsigned getKernelColumnNumber() {
#ifndef __INTEL_SYCL_USE_INTEGRATION_HEADERS
return __builtin_sycl_kernel_column_number(KernelIdentity<KernelNameType>());
#else
return KernelInfo<KernelNameType>::getColumnNumber();
#endif
}

template <typename KernelNameType> constexpr int64_t getKernelSize() {
// TODO needs a builtin counterpart, but is currently only used for checking
// cases with external host compiler, which use integration headers.
return KernelInfo<KernelNameType>::getKernelSize();
}
} // namespace detail
} // namespace _V1
} // namespace sycl
Loading

0 comments on commit c87f6b2

Please sign in to comment.