-
Notifications
You must be signed in to change notification settings - Fork 0
Clarification for kernel named functions #4
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
base: SYCL-1.2.1/master
Are you sure you want to change the base?
Conversation
Clarify that SYCL_EXTERNAL cannot be used for the "operator()" member
function of a kernel function object, or for any member function.
Also use consistent formatting for "operator()". Most occurences used
\codeinline{}, but a few were using \tf{}. Standardize on the former.
|
Please consider this carefully. Our compiler gives an error that SYCL_EXTERNAL cannot be used for member functions. Is that intent of the spec, or is it a compiler bug? Obviously, this PR assumes it is the intent of the spec. |
|
I believe that the compiler behavior matches the spec via:
That said:
|
|
I'd like to drive this PR to conclusion. If we are agreed that the intent of the 1.2.1 spec is to disallow SYCL_EXTERNAL on member functions, then I think we should update the wording as I suggest to make this more clear. I believe the C++ standard uses the term "member function", not "method", so using that term in SYCL would be more precise. I'm certainly not opposed to expanding the SYCL spec to allow SYCL_EXTERNAL on member functions. If that is our desire, shall we treat that as a separate PR? It would probably make sense to prototype that support in our own compiler before proposing a change to the spec. |
I currently believe that SYCL_EXTERNAL on a member function is a rare use case, so don't think it's worth effort to generalize now. @rolandschulz @Pennycook @jbrodman any disagreement? So the action, unless anyone objects, is to clarify in the spec that SYCL_EXTERNAL is not allowed on member functions. |
|
I think the restrictions proposed here are too strong, but I might have misunderstood something. I agree that allowing SYCL_EXTERNAL on arbitrary member functions of arbitrary classes is a bad idea and could lead to problems. It's not clear to me what would be expected to happen if a member function accessed a member of the class it is defined in, for example. However, the proposed wording forbids a use-case that I assumed we wanted to support. If we forbid kernels defined as functors in different translation units, doesn't that force library developers to ship their library as a header or as a precompiled kernel object? Can we and should we also support applying SYCL_EXTERNAL to an entire class definition if that class is a kernel functor? |
Is your suggestion that operator() of a class in a different xlation unit should be legal to mark as SYCL_EXTERNAL, and an entire class should potentially be able to be marked that way as well if it has operator() defined? |
Just the second part. Marking an entire class as SYCL_EXTERNAL could instruct the compiler to try and compile it as a kernel, rather than waiting until it sees that type used as a kernel function (which I think is what we implement today). I'm a little uncertain because I'm not sure if applying it to the class is any different to applying it to all functions and operators inside of the class. But marking the class seems clearer, and the behavior is easier to specify. I think I am suggesting that:
|
|
I agree it is likely rare. But I don't see any good reason to disallow it.
Why would it be a bad idea? I don't see any difference between a (non-virtual) member function and a non-member function. From a compiler perspective Therefore I disagree. I don't see any good reason to disallow it. The only challenging case is virtual member functions (because it is problematic to build a vtable if some but not all functions are external) but given that they are so far disallowed that's not something we need to worry about until then. Do we know why our compiler disallows member functions currently? |
The concern I mentioned about member data is invalid -- you have to have an instance of the class to call a member function, so the data has to be on the device already. Thinking about it as I still think there is more to specify if we allow member functions, though. Would a user have to put SYCL_EXTERNAL on every function in the class? Does every function in the class need to be compatible with device compilation, or only the ones marked SYCL_EXTERNAL? These questions may already have answers for classes that meet the definition of a SYCL functor, but it's not obvious to me what behavior is expected of general classes. |
I would expect that the user has to put it on every function to be able to call it as external function. Until/unless we also allow |
|
FWIW, my original expectation matches what @rolandschulz describes. I expected to be able to define If we were to allow SYCL_EXTERNAL to apply to the entire class definition, would this mean that all member functions would be compiled for the device? It will be common, though, for some member functions not to be needed on the device. Does that mean we will need a way for the programmer to disable device compilation for these member functions? It seems like it would be clearer to just allow SYCL_EXTERNAL on specific member functions that are needed on the device and not called from the same translation unit. |
Why did you change it? Did you ask the compiler team why it is disallowed?
I think we should at the very least do this for now. If people think it's too cumbersome to have to put it on each method we can revisit that and try to answer the other questions which follow from that. |
|
Would this mean that SYCL_EXTERNAL on an |
Yes, it would mean that you could put SYCL_EXTERNAL on I looked at intel/llvm#640, and it looks like a different issue to me. FWIW, I also found the SYCL spec confusing w.r.t. the
No, I did not ask the compiler team. @mkinsner says above (in the second comment) that he thinks a strict reading of the current SYCL 1.2.1 spec is that SYC_EXTERNAL is not allowed on member functions. Therefore, the compiler team might disallow this simply because that's what the spec says. My original goal of this PR was just to clarify what I thought was the intent of the spec -- that SYCL_EXTERNAL is not allowed for member functions. It seems like there is not a consensus that this is the right direction, though. I can gather some more information from the compiler team to see if there is a reason for disallowing it for member functions. I'll likely make this a lower priority, though, after trying to get the extension API proposal in order. |
Got it, thanks.
I agree they're not exactly the same issue, but I think they're related. Both problems have the same root cause: "the compiler doesn't know that this function/kernel needs to be available on the device because it didn't appear in a parallel_for in this translation unit". Adding SYCL_EXTERNAL to the code in intel/llvm#640 would force the compiler to make that The current solution in SYCL 1.2.1 is very specific to one use-case, and I'm wondering whether it's too specific. I guess it really depends on what the expected behavior is for the |
Not sure if I interpret the question right, but the Can you please clarify the question if it's something else? |
The reminder that The question I'm really asking is demonstrated very well by intel/llvm#640: does a class actually have to appear in an instantiation of a |
|
I hadn't heard of the new module proposal before. Searching around, I found this. Is that the latest version? |
1 similar comment
|
I hadn't heard of the new module proposal before. Searching around, I found this. Is that the latest version? |
I think that anything that looks like a kernel or could be a device function needs to be compiled for every device. Is there another option? Alternatives that I don't think are tractable are to whitelist or to blacklist functions within the xlation unit using a [[kernel]] or [[device]] attr, but I don't think that's where we want to go. For the kernel side (not function called by a kernel), the signature of a legal kernel function is a pretty specific subset of possible signatures. So finding them should be tractable, correct? |
I agree that this is the way to go. I was worried we were in a situation where we might need SYCL_EXTERNAL even within a translation unit to handle |
Clarify that SYCL_EXTERNAL cannot be used for the "operator()" member
function of a kernel function object, or for any member function.
Also use consistent formatting for "operator()". Most occurences used
\codeinline{}, but a few were using \tf{}. Standardize on the former.