-
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
What does "Exception-handling cannot be used inside a device function" actually mean? #543
Comments
This is a good point. It does seem like we should allow try / catch blocks in device code for the same reason they are allowed in C++ constexpr functions. If there is no way to throw an exception in device code, the catch blocks are just no-ops, so why disallow them? Therefore, I would be in favor of changing this restriction to say:
This is already disallowed in device code by the following bullet point that appears later in this same section of the SYCL spec:
Answering narrowly ... such an implementation would be conformant unless we say that violation of the rules in section 5.4 make a program "ill-formed". (My understanding is that the core C++ spec defines "ill-formed" as a requirement that the implementation must diagnose an error in this case, right?) As the wording is now, we don't say that violations of these requirements make a program ill-formed, so I think it is up to the quality of the implementation to decide whether a diagnostic is emitted. Answering more broadly ... this doesn't seem like a good implementation to me. Implementing all |
We could require any SYCL kernel or device function to be |
@AlexeySachkov When you say you want to require that and SYCL kernel/device function be
Both are problematic. Most functions, even though they don't throw, aren't marked As of C++17, It also doesn't solve the problem. This is perfectly valid C++ code which doesn't involve functions being declared void foo() {
try {
throw 0;
}
catch (int) {
DoSomething();
}
} (A non-library only implementation of SYCL could obviously make the above work inside a kernel, but it isn't terribly useful.) I agree with others in that |
The motivation for filing this issue was a developer complaining that they cannot use the
|
My understanding of ill-formed matches yours.
Ideally, I agree. I don't know the history of why exceptions are not allowed in device code though I can imagine questions of what happens when a worker spawned for a Specifying that |
Agreed. That is consistent with use of
|
I think this illustrates a common problem that we will have if we want to allow applications to call (some of the)
This last part isn't true. It's actually quite difficult to implement This is also the reason we prohibit the features listed in section 5.7 "Optional kernel features" from appearing in device code (vs. being used in device code). We can diagnose an error at the point when a kernel is submitted to a device if the kernel contains a feature that the device doesn't support. The logic for doing this is all on the host. By contrast, if we allowed a kernel to contain an unsupported feature and tried to diagnose an error only if the feature is actually used, then we would somehow need to implement assert-like functionality in the device. |
Thank you, I wasn't aware of the motivation for these limitations. |
Because it is not handled well by others APIs SYCL was built on top of at the first place.
Actually we speculatively followed some optimistic C++17 |
This will be handled by #388 |
I think there might be some confusion here. I believe @tahonermann is suggesting that |
Thank you for that correction, @gmlueck. Yes, you understood my intent correctly. I read #388, but it wasn't clear (to me) from its description how relevant it is to this request. The suggestion in this issue is to allow a function like the following in device code unconditionally.
And to perhaps allow a function like the following with a restriction that calling it with a
Alternatively, a function that contains a |
Just tried, @tahonermann's godbolt example compiles and runs with AdaptiveCpp generic SSCP compiler on CPU/Intel GPU/NVIDIA GPU/AMD GPU. But I'm not sure how reliable it is. Here it just generates an empty kernel, so it's quite possible that in this simple example it could just optimize anything away that could cause a problem. I wouldn't be surprised if some backends choked if some instructions around try/catch actually made it to backend code generation. |
Instead of trying to support all of something like optional, would it be sufficient to just support the freestanding parts? I do t think any of those require exceptions. |
Instead of trying to support all of something like optional, would it be sufficient to just support the freestanding parts? I don't think any of those require exceptions. |
I don't know if the freestanding definition helps us much here. My knowledge of "freestanding" is limited to what cppreference says, but it seems like
In addition, I see that |
Perhaps. It looks like the only parts of @gmlueck, freestanding requires full C++ language support ([intro.compliance.general]p7) and support for the |
Does the CUDA implementation actually throw an exception if the requested value does not exist? If so, can you catch and handle the exception? |
Sound unlikely (at least in pure cuda):
|
The |
NVC++ works with |
Can even take the "std::optional" as a parameter (https://godbolt.org/z/no94G1sK6) |
Section 5.4 (Language restrictions for device functions) of revision 8 of the SYCL 2020 specification states:
What does "Exception-handling cannot be used" mean? (and why is that hyphen there?)
throw
expressions? Shouldtry
andcatch
be allowed given that they are allowed inconstexpr
evaluation in C++20 courtesy of adoption of P1002R1 (Try-catch blocks in constexpr functions)?std::current_exception()
?throw
expression perhaps results in some unspecified or undefined behavior?Would an implementation that allows use of exception handling language features in device code such that evaluation of a
throw
expression results in an immediate call tostd::terminate()
orstd::abort()
be a conforming implementation? Such a translation mode would allow more C++ code, including C++ standard library features, to be usable in device code.The text was updated successfully, but these errors were encountered: