-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clarify backend and introduce "backend::none" #577
base: main
Are you sure you want to change the base?
Conversation
Clarify exactly what we mean by "backend". I think it has always been our intention that the `backend` enumeration and the `get_backend` member function tell an application what sort of interoperation is supported by a SYCL object. For example, if a SYCL object returns `backend::opencl` from its `get_backend` function, that SYCL object supports interoperation as defined by the OpenCL backend interoperation specification. This commit clarifies the spec to say that explicitly. It also became clear that we need a `backend::none` enumerator to indicate that a SYCL object does not support any backend interoperation. For example, this would be useful if a vendor implements SYCL directly on hardware, without using a documented low-level offload API. Many of the changes in this commit merely remove sentences that imply that every SYCL object necessarily has some backend. This commit also makes a minor change to the default `event` constructor. Previously, we required the backend for such an event to be the same as the backend for the default device. After some implementation experience, we decided that this is not practical. Requiring interoperation with a particular backend constrains the implementation too much. It also seems arbitrary to require the default-constructed event to have a particular backend. To address these concerns, this commit loosens the requirement, allowing an implementation to choose which backend (if any) the default-constructed event has. Closes KhronosGroup#564
The previous wording placed a lot of emphasis on backends, defining two different kinds of SYCL application. Since backends and backend interoperability are optional, reducing this emphasis is desirable. Additionally, removing this section from the specification simplifies it and makes it easier to read.
Earlier commits reworded several sentences to remove references to "SYCL general" and "SYCL generic" by referring explicitly to backends instead. This commit completes that work by removing the remaining references to these concepts.
@@ -15935,7 +15949,10 @@ The following member functions provide various queries for a <<kernel>>. | |||
backend get_backend() const noexcept; | |||
---- | |||
|
|||
_Returns:_ The backend associated with this kernel. | |||
_Returns:_ The backend (if any) that underlies this object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it's a philosophical question, but is a backend none
a backend or not? If it's then we can remove all the if any
everywhere :) (Russell’s Paradox here I come)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I specified backend::none
as "not a backend". Here is the description from the section on the backend
enumeration:
The enumerator value
backend::none
is used to identify a SYCL object that does not correspond to any backend.
In addition, the section "The SYCL backend model" describes backends this way:
A SYCL implementation may expose devices by layering on top of a heterogeneous API such as OpenCL or it may expose devices in some other way. [...] When a SYCL implementation layers on top of a heterogeneous API such as OpenCL, we refer to this as a SYCL backend.
Thus, when an implementation exposes devices without layering on top of a heterogeneous API, it is not using a backend.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you happen to know the reason for such a choice for restricting backend to "heterogeneous API" ?
That a TBB
or a OpenMP
are not considered backends seems odd. It makes sense that they don't provide any interop, but I think the general usage of the word "backend" is more general.
For example, in the SimSYCL paper, they use the term "AdaptiveCpp (OMP backend)" (https://dl.acm.org/doi/fullHtml/10.1145/3648115.3648136 table 2) who make total sense to me, but are not technically correct.
In short, I don't understand the rationale behind this spec subtility. Every backend can decide if they provide or not some interopts for whatever SYCL function they want.
PS: This also led to a question about an MPI Implementation. As far as I know, MPI is not a "heterogeneous API" (just an API :) ), but I guess we still want to be able to give some interrupt handle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That a TBB or a OpenMP are not considered backends seems odd. It makes sense that they don't provide any interop, but I think the general usage of the word "backend" if more general.
Yes. I'm opposed to tying the notion of a "backend" to the ability of providing interop. Those two have been separate concepts so far in SYCL.
AdaptiveCpp treats OpenMP just like any other backend. I see no reason to change the backend model for "native CPU" approaches. From the AdaptiveCpp point of view, those are perfectly valid backends, and I would disagree with everyone who claims that they are not SYCL backends.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The term "heterogeneous API" is used in the SYCL specification even before this PR. As far as I know, there is no industry standard definition for this term. I was assuming that OMP would also be considered a "heterogeneous API".
I'm not opposed to using a different term if someone has a suggestion. Is there some better collective term for things like OpenCL, OpenMP, CUDA, etc.? Maybe "offload API"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recommend disconnecting "heterogeneous API" from any "backend" consideration. But maybe it is not the best place to discuss this.
My main point is that we tied too much of the SYCL spec to the "heterogeneous API" of the backend.
For example:
A function object that can execute on a device exposed by a SYCL backend API is called a SYCL kernel function.
That means that for an OpenMP pure CPU or Intel TBB, a lambda used in Q.submit is not a kernel function. That also means that we can have "devices" that are not part of any "backend"?
OMP for offloading I I agree, is "heterogenous"; for CPU only OpenMP I don't see why it's "heterogeneous". Same for MPI. Or for a pthread
CPU implementation of SYCL.
I think all this "SYCL is build on top of a backend API" is a relic of OpenCL; we should clarify that it's just implementation details. SYCL provides a "heterogenous API" but doesn't need to one be implemented. The spec should be clear about it.
And I think the easiest way is to define loosely what is a backend; it's whatever the implementation wants it to be, and not tie it to any concept of "heterogenous API"
But yeah, maybe a far more broad conversation; sorry for the side-discussion.
I would be careful to tie the SYCL backend model too closely to the interop model. There may be other use cases for querying the backend, for example if you know that e.g. that a specific backend has certain performance characteristics. I think I am opposed to adding I believe it would be clearer for SYCL if the See discussion here for details: #564 |
Next steps:
|
To clarify my point (sorry if I was unclear earlier), IMO we have two distinct types of "interop errors."
One is an "I Don't Know the Backend. Sorry, general SYCL problem" and the other is a "Not Implement Error for this backend. Contact your vendor.". For me ( If we want to avoid the TLDR: |
I created a separate PR with just this change #582 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds good.
Although the APIs in the SYCL generic programming model are defined according to | ||
this specification and their version is indicated by the macro | ||
Although most APIs in the SYCL programming model are defined according to this | ||
specification and their version is indicated by the macro |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if it was in the previous version, and their version
looks weird to me.
Perhaps we can clarify the meaning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want to clean this up, I would propose deleting this entire paragraph. I don't think it adds any clarity. I don't think the core spec needs to say anything about the versioning of the backend interoperation APIs. This can be left to each backend interoperation specification.
From WG meeting today:
|
Clarify exactly what we mean by "backend". I think it has always been our intention that the
backend
enumeration and theget_backend
member function tell an application what sort of interoperation is supported by a SYCL object. For example, if a SYCL object returnsbackend::opencl
from itsget_backend
function, that SYCL object supports interoperation as defined by the OpenCL backend interoperation specification.This commit clarifies the spec to say that explicitly.
It also became clear that we need a
backend::none
enumerator to indicate that a SYCL object does not support any backend interoperation. For example, this would be useful if a vendor implements SYCL directly on hardware, without using a documented low-level offload API. Many of the changes in this commit merely remove sentences that imply that every SYCL object necessarily has some backend.This commit also makes a minor change to the default
event
constructor. Previously, we required the backend for such an event to be the same as the backend for the default device. After some implementation experience, we decided that this is not practical. Requiring interoperation with a particular backend constrains the implementation too much. It also seems arbitrary to require the default-constructed event to have a particular backend. To address these concerns, this commit loosens the requirement, allowing an implementation to choose which backend (if any) the default-constructed event has.Closes #564