Skip to content

Can multiple kernel name types be associated with the same kernel object type? #893

@tahonermann

Description

@tahonermann

Specification Version

SYCL 2020 (Revision 10)

Section Number(s)

https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#sec:naming.kernels

Issue Description

Discussion in #568 raised a concern regarding whether multiple kernel name types can be associated with the same kernel object type. This concern is tangential to the primary concern for which that issue was reported, so has been moved to this new issue.

See the code example attached to this issue. The initial concern raised in #568 is this:

I don't think code like this should be allowed. MyKernel already has a name, and I can't think of any reason why somebody would want to assign two different names to the same kernel. Assigning two names to the same kernel means that in practice it will have to be compiled twice, even though the body of the kernel will be identical.

... assigning two different names to the same lambda seems broken to me, just like the named function object case.

Further discussion indicated that the suggested duplicate compilation is limited to device entry points (if applicable to the implementation) and SYCL invocation function template instantiations.

The kernel name is what defines the kernel, not the kernel object type. Greg's example requires two distinct device entry points, but I don't think it necessitates multiple compilations of the kernel object type or the functions it calls. Entry points can share common code. Template instantiations would of course be performed for each invocation of the SYCL invocation function with a distinct kernel name type.

Discussion continued with an emphasis on design:

I meant that the design seems broken: it's definitely possible to implement something that allows a user to associate multiple arbitrary type names with the same function object, I just don't understand why that's useful to anybody. It makes the implementation more complicated, means we have to specify the behavior of more weird corner cases, and potentially leads to more confusion for developers.

The code example attached to this issue attempts to demonstrate how a single kernel object type might reasonably used for multiple purposes.

Building off @gmlueck's example: Are get_kernel_id<Name1>() and get_kernel_id<Name2>() required or allowed to return the same kernel_id? Can both Name1 and Name2 be declared in the same kernel bundle? If backend interop is used to extract the underlying OpenCL/Level Zero/CUDA representation of the kernels for Name1 and Name2, can they be the same?

These are questions that should have clear answers in the specification. A useful outcome of this issue discussion might include updating the specification to more clearly specify the correspondence between a kernel ID, a kernel name, and a kernel.

The SYCL specification is not particularly precise in its use of the term "kernel"; see #603.

Code Example (Optional)

struct Kernel {
  bool DoTheOtherThing;
  void operator()() const {
    if (! DoTheOtherThing) { ... }
    else { ... }
  }
};

struct DoTheThing;
struct DoTheOtherThing;

void foo(sycl::queue q) {
  q.submit([=](sycl::handler &cgh) {
    Kernel k { false };
    cgh.single_task<DoTheThing>(k);
  }).wait();
  q.submit([=](sycl::handler &cgh) {
    Kernel k { true };
    cgh.single_task<DoTheOtherThing>(k);
  }).wait();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions