@@ -458,34 +458,33 @@ The SYCL kernel in the previous code sample meets these expectations.
458458def SYCLKernelEntryPointDocs : Documentation {
459459 let Category = DocCatFunction;
460460 let Content = [{
461- The ``sycl_kernel_entry_point`` attribute specifies that a function definition
462- defines a pattern for an offload kernel entry point function to be emitted when
463- the source code is compiled with ``-fsycl`` for a device target. Such functions
464- serve as the execution entry point for a SYCL run-time library to invoke a SYCL
465- kernel on a device. The function's parameters define the parameters to the
466- offload kernel.
461+ The ``sycl_kernel_entry_point`` attribute facilitates the generation of an
462+ offload kernel entry point, sometimes called a SYCL kernel caller function,
463+ suitable for invoking a SYCL kernel on an offload device. The attribute is
464+ intended for use in the implementation of SYCL kernel invocation functions
465+ like the ``single_task`` and ``parallel_for`` member functions of the
466+ ``sycl::handler`` class specified in section 4.9.4, "Command group ``handler``
467+ class", of the SYCL 2020 specification.
467468
468469The attribute requires a single type argument that specifies a class type that
469470meets the requirements for a SYCL kernel name as described in section 5.2,
470471"Naming of kernels", of the SYCL 2020 specification. A unique kernel name type
471472is required for each function declared with the attribute. The attribute may
472473not first appear on a declaration that follows a definition of the function.
473474
474- The attribute appertains only to non-member functions and static member
475- functions that meet the following requirements:
475+ The attribute only appertains to functions and only those that meet the
476+ following requirements.
476477
477- - Has a ``void`` return type.
478- - Is not a variadic function.
479- - Is not a coroutine.
480- - Is not defined as deleted or as defaulted.
481- - Is not declared with the ``constexpr`` or ``consteval`` specifiers.
482- - Is not declared with the ``[[noreturn]]`` attribute.
478+ * Has a ``void`` return type.
479+ * Is not a non-static member function, constructor, or destructor.
480+ * Is not a C variadic function.
481+ * Is not a coroutine.
482+ * Is not defined as deleted or as defaulted.
483+ * Is not declared with the ``constexpr`` or ``consteval`` specifiers.
484+ * Is not declared with the ``[[noreturn]]`` attribute.
483485
484- This attribute is intended for use in the implementation of SYCL run-time
485- libraries that implement SYCL kernel invocation functions like the
486- ``single_task`` and ``parallel_for`` member functions of the ``sycl::handler``
487- class specified in section 4.9.4, "Command group ``handler`` class" of the
488- SYCL 2020 specification. Such use might look something like the following.
486+ Use in the implementation of a SYCL kernel invocation function might look as
487+ follows.
489488
490489.. code-block:: c++
491490
@@ -500,16 +499,127 @@ SYCL 2020 specification. Such use might look something like the following.
500499 public:
501500 template<typename KernelNameType, typename KernelType>
502501 void single_task(KernelType kernel) {
502+ // Call kernel_entry_point() to trigger generation of an offload
503+ // kernel entry point.
503504 kernel_entry_point<KernelNameType>(kernel);
505+ // Call functions appropriate for the desired offload backend
506+ // (OpenCL, CUDA, HIP, Level Zero, etc...).
504507 }
505508 };
506509 } // namespace sycl
507510
508- It is not necessary for a SYCL kernel entry point function to be called for
509- the offload kernel entry point to be emitted. For inline functions and function
510- templates, any ODR-use will suffice. For other functions, an ODR-use is not
511- required; the offload kernel entry point will be emitted if the function is
512- defined.
511+ A SYCL kernel is a callable object of class type that is constructed on a host,
512+ often via a lambda expression, and then passed to a SYCL kernel invocation
513+ function to be executed on an offload device. A SYCL kernel invocation function
514+ is responsible for copying the provided SYCL kernel object to an offload
515+ device and initiating a call to it. The SYCL kernel object and its data members
516+ constitute the parameters of an offload kernel.
517+
518+ A SYCL kernel type is required to satisfy the device copyability requirements
519+ specified in section 3.13.1, "Device copyable", of the SYCL 2020 specification.
520+ Additionally, any data members of the kernel object type are required to satisfy
521+ section 4.12.4, "Rules for parameter passing to kernels". For most types, these
522+ rules require that the type is trivially copyable. However, the SYCL
523+ specification mandates that certain special SYCL types, such as
524+ ``sycl::accessor`` and ``sycl::stream`` be device copyable even if they are not
525+ trivially copyable. These types require special handling because they cannot
526+ be copied to device memory as if by ``memcpy()``. Additionally, some offload
527+ backends, OpenCL for example, require objects of some of these types to be
528+ passed as individual arguments to the offload kernel.
529+
530+ An offload kernel consists of an entry point function that declares the
531+ parameters of the offload kernel and the set of all functions and variables that
532+ are directly or indirectly used by the entry point function.
533+
534+ A SYCL kernel invocation function invokes a SYCL kernel on a device by
535+ performing the following tasks (likely with the help of an offload backend
536+ like OpenCL):
537+
538+ #. Identifying the offload kernel entry point to be used for the SYCL kernel.
539+
540+ #. Deconstructing the SYCL kernel object, if necessary, to produce the set of
541+ offload kernel arguments required by the offload kernel entry point.
542+
543+ #. Copying the offload kernel arguments to device memory.
544+
545+ #. Initiating execution of the offload kernel entry point.
546+
547+ The offload kernel entry point for a SYCL kernel performs the following tasks:
548+
549+ #. Reconstituting the SYCL kernel object, if necessary, using the offload
550+ kernel parameters.
551+
552+ #. Calling the ``operator()`` member function of the (reconstituted) SYCL kernel
553+ object.
554+
555+ The ``sycl_kernel_entry_point`` attribute automates generation of an offload
556+ kernel entry point that performs those latter tasks. The parameters and body of
557+ a function declared with the ``sycl_kernel_entry_point`` attribute specify a
558+ pattern from which the parameters and body of the entry point function are
559+ derived. Consider the following call to a SYCL kernel invocation function.
560+
561+ .. code-block:: c++
562+
563+ struct S { int i; };
564+ void f(sycl::handler &handler, sycl::stream &sout, S s) {
565+ handler.single_task<struct KN>([=] {
566+ sout << "The value of s.i is " << s.i << "\n";
567+ });
568+ }
569+
570+ The SYCL kernel object is the result of the lambda expression. It has two
571+ data members corresponding to the captures of ``sout`` and ``s``. Since one
572+ of these data members corresponds to a special SYCL type that must be passed
573+ individually as an offload kernel parameter, it is necessary to decompose the
574+ SYCL kernel object into its constituent parts; the offload kernel will have
575+ two kernel parameters. Given a SYCL implementation that uses a
576+ ``sycl_kernel_entry_point`` attributed function like the one shown above, an
577+ offload kernel entry point function will be generated that looks approximately
578+ as follows.
579+
580+ .. code-block:: c++
581+
582+ void sycl-kernel-caller-for-KN(sycl::stream sout, S s) {
583+ kernel-type kernel = { sout, s );
584+ kernel();
585+ }
586+
587+ There are a few items worthy of note:
588+
589+ #. The name of the generated function incorporates the SYCL kernel name,
590+ ``KN``, that was passed as the ``KernelNameType`` template parameter to
591+ ``kernel_entry_point()`` and provided as the argument to the
592+ ``sycl_kernel_entry_point`` attribute. There is a one-to-one correspondence
593+ between SYCL kernel names and offload kernel entry points.
594+
595+ #. The SYCL kernel is a lambda closure type and therefore has no name;
596+ ``kernel-type`` is substituted above and corresponds to the ``KernelType``
597+ template parameter deduced in the call to ``kernel_entry_point()``.
598+ Lambda types cannot be declared and initialized using the aggregate
599+ initialization syntax used above, but the intended behavior should be clear.
600+
601+ #. ``S`` is a device copyable type that does not directly or indirectly contain
602+ a data member of a SYCL special type. It therefore does not need to be
603+ decomposed into its constituent members to be passed as a kernel argument.
604+
605+ #. The call to ``kernel_entry_point()`` has no effect other than to trigger
606+ emission of the entry point function. The statments that make up the body
607+ of the function are not executed when the function is called; they are
608+ only used in the generation of the entry point function.
609+
610+ It is not necessary for a function declared with the ``sycl_kernel_entry_point``
611+ attribute to be called for the offload kernel entry point to be emitted. For
612+ inline functions and function templates, any ODR-use will suffice. For other
613+ functions, an ODR-use is not required; the offload kernel entry point will be
614+ emitted if the function is defined.
615+
616+ Functions declared with the ``sycl_kernel_entry_point`` attribute are not
617+ limited to the simple example shown above. They may have additional template
618+ parameters, declare additional function parameters, and have complex control
619+ flow in the function body. Function parameter decomposition and reconstitution
620+ is performed for all function parameters. The function must abide by the
621+ language feature restrictions described in section 5.4, "Language restrictions
622+ for device functions" in the SYCL 2020 specification.
513623 }];
514624}
515625
0 commit comments