================ @@ -455,6 +455,174 @@ The SYCL kernel in the previous code sample meets these expectations. }]; } +def SYCLKernelEntryPointDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``sycl_kernel_entry_point`` attribute facilitates the generation of an +offload kernel entry point, sometimes called a SYCL kernel caller function, +suitable for invoking a SYCL kernel on an offload device. The attribute is +intended for use in the implementation of SYCL kernel invocation functions +like the ``single_task`` and ``parallel_for`` member functions of the +``sycl::handler`` class specified in section 4.9.4, "Command group ``handler`` +class", of the SYCL 2020 specification. + +The attribute requires a single type argument that specifies a class type that +meets the requirements for a SYCL kernel name as described in section 5.2, +"Naming of kernels", of the SYCL 2020 specification. A unique kernel name type +is required for each function declared with the attribute. The attribute may +not first appear on a declaration that follows a definition of the function. + +The attribute only appertains to functions and only those that meet the +following requirements. + +* Has a ``void`` return type. +* Is not a non-static member function, constructor, or destructor. +* Is not a C variadic function. +* Is not a coroutine. +* Is not defined as deleted or as defaulted. +* Is not declared with the ``constexpr`` or ``consteval`` specifiers. +* Is not declared with the ``[[noreturn]]`` attribute. + +Use in the implementation of a SYCL kernel invocation function might look as +follows. + +.. code-block:: c++ + + namespace sycl { + class handler { + template<typename KernelNameType, typename KernelType> + [[ clang::sycl_kernel_entry_point(KernelNameType) ]] + static void kernel_entry_point(KernelType kernel) { + kernel(); + } + + public: + template<typename KernelNameType, typename KernelType> + void single_task(KernelType kernel) { + // Call kernel_entry_point() to trigger generation of an offload + // kernel entry point. + kernel_entry_point<KernelNameType>(kernel); + // Call functions appropriate for the desired offload backend + // (OpenCL, CUDA, HIP, Level Zero, etc...). + } + }; + } // namespace sycl + +A SYCL kernel is a callable object of class type that is constructed on a host, +often via a lambda expression, and then passed to a SYCL kernel invocation +function to be executed on an offload device. A SYCL kernel invocation function +is responsible for copying the provided SYCL kernel object to an offload +device and initiating a call to it. The SYCL kernel object and its data members +constitute the parameters of an offload kernel. + +A SYCL kernel type is required to satisfy the device copyability requirements +specified in section 3.13.1, "Device copyable", of the SYCL 2020 specification. +Additionally, any data members of the kernel object type are required to satisfy +section 4.12.4, "Rules for parameter passing to kernels". For most types, these +rules require that the type is trivially copyable. However, the SYCL +specification mandates that certain special SYCL types, such as +``sycl::accessor`` and ``sycl::stream`` be device copyable even if they are not +trivially copyable. These types require special handling because they cannot +be copied to device memory as if by ``memcpy()``. Additionally, some offload +backends, OpenCL for example, require objects of some of these types to be +passed as individual arguments to the offload kernel. + +An offload kernel consists of an entry point function that declares the +parameters of the offload kernel and the set of all functions and variables that +are directly or indirectly used by the entry point function. + +A SYCL kernel invocation function invokes a SYCL kernel on a device by +performing the following tasks (likely with the help of an offload backend +like OpenCL): + +#. Identifying the offload kernel entry point to be used for the SYCL kernel. + +#. Deconstructing the SYCL kernel object, if necessary, to produce the set of + offload kernel arguments required by the offload kernel entry point. + +#. Copying the offload kernel arguments to device memory. + +#. Initiating execution of the offload kernel entry point. + +The offload kernel entry point for a SYCL kernel performs the following tasks: + +#. Reconstituting the SYCL kernel object, if necessary, using the offload + kernel parameters. + +#. Calling the ``operator()`` member function of the (reconstituted) SYCL kernel + object. + +The ``sycl_kernel_entry_point`` attribute automates generation of an offload +kernel entry point that performs those latter tasks. The parameters and body of +a function declared with the ``sycl_kernel_entry_point`` attribute specify a +pattern from which the parameters and body of the entry point function are +derived. Consider the following call to a SYCL kernel invocation function. + +.. code-block:: c++ + + struct S { int i; }; + void f(sycl::handler &handler, sycl::stream &sout, S s) { + handler.single_task<struct KN>([=] { + sout << "The value of s.i is " << s.i << "\n"; + }); + } + +The SYCL kernel object is the result of the lambda expression. It has two +data members corresponding to the captures of ``sout`` and ``s``. Since one +of these data members corresponds to a special SYCL type that must be passed +individually as an offload kernel parameter, it is necessary to decompose the +SYCL kernel object into its constituent parts; the offload kernel will have +two kernel parameters. Given a SYCL implementation that uses a ---------------- erichkeane wrote:
Why only `two`? If `stream` is a special type that needs decomposing, it presumably results in more than 1 kernel parameters, and `S` is its own, correct? https://github.com/llvm/llvm-project/pull/111389 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits