This is an archive of the discontinued LLVM Phabricator instance.

[AST] Enable expression of OpenCL language address spaces an attribute
ClosedPublic

Authored by bader on Dec 4 2019, 4:35 AM.

Details

Summary

Enable a way to set OpenCL language address space using attributes
in addition to existing keywords.

Signed-off-by: Victor Lomuller victor@codeplay.com

Diff Detail

Event Timeline

bader created this revision.Dec 4 2019, 4:35 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 4 2019, 4:35 AM
Anastasia added inline comments.Dec 4 2019, 5:07 AM
clang/include/clang/Basic/Attr.td
1123

We don't really use ocl prefix for opencl currently? Can it be opencl_private and etc?

Build result: pass - 60453 tests passed, 0 failed and 726 were skipped.

Log files: console-log.txt, CMakeCache.txt

bader updated this revision to Diff 232098.Dec 4 2019, 5:39 AM

Change attribute prefix: ocl_ -> opencl_.

Updated OpenCL spelling in the comments.

bader marked 2 inline comments as done.Dec 4 2019, 5:39 AM
bader added inline comments.
clang/include/clang/Basic/Attr.td
1123

Sure. Done.

Build result: pass - 60453 tests passed, 0 failed and 726 were skipped.

Log files: console-log.txt, CMakeCache.txt

Anastasia accepted this revision.Dec 5 2019, 3:01 AM

LGTM! Thanks!

I presume OpenCL addr space logic won't apply in all cases in non-OpenCL compilations i.e. for example C++ because we enclose some of the logic under LangOpts checks.

This revision is now accepted and ready to land.Dec 5 2019, 3:01 AM
bader marked an inline comment as done.Dec 5 2019, 3:13 AM

LGTM! Thanks!

I presume OpenCL addr space logic won't apply in all cases in non-OpenCL compilations i.e. for example C++ because we enclose some of the logic under LangOpts checks.

I think so too.

This revision was automatically updated to reflect the committed changes.
aaron.ballman added inline comments.Dec 5 2019, 4:53 AM
clang/include/clang/Basic/Attr.td
1123

This looks like we're adding two levels of namespace -- is there a reason this should be clang::opencl_private as opposed to opencl::private? Is there something clang-specific to these?

bader marked an inline comment as done.Dec 5 2019, 5:07 AM
bader added inline comments.
clang/include/clang/Basic/Attr.td
1123

is there a reason this should be clang::opencl_private as opposed to opencl::private?

I'm okay with [[opencl::private]] as well. I have only one problem - currently OpenCL address spaces are exposed as keywords and using them in C++ breaks valid C++ code.

Is there something clang-specific to these?

I guess no (except that it's implemented in only Clang :-) ).

@aaron.ballman, I already committed this version, sorry about that. I'll open another review with attribute renaming.

aaron.ballman added inline comments.Dec 5 2019, 5:14 AM
clang/include/clang/Basic/Attr.td
1123

is there a reason this should be clang::opencl_private as opposed to opencl::private?

I'm okay with [[opencl::private]] as well. I have only one problem - currently OpenCL address spaces are exposed as keywords and using them in C++ breaks valid C++ code.

I'm not certain who controls the OpenCL spec, but this seems like it should be a decision that comes from there. Or is this functionality outside of the OpenCL spec?

In attributes, when an identifier can be interpreted as a keyword it is required to be interpreted as an identifier. We have the same issue with [[gnu::const]]. See http://eel.is/c++draft/dcl.attr.grammar#4.sentence-5

Is there something clang-specific to these?

I guess no (except that it's implemented in only Clang :-) ).

I mostly mean: will other implementations of OpenCL want to have the same functionality? Or is this something we expect other OpenCL implementations to largely ignore?

@aaron.ballman, I already committed this version, sorry about that. I'll open another review with attribute renaming.

The turnaround time between opening the review and closing it was pretty quick, but you had a reasonable LG so it's no big deal. We can continue chatting about it on this review until we decide that changes really are needed.

bader added a comment.Dec 5 2019, 6:57 AM

is there a reason this should be clang::opencl_private as opposed to opencl::private?

I'm okay with [[opencl::private]] as well. I have only one problem - currently OpenCL address spaces are exposed as keywords and using them in C++ breaks valid C++ code.

I'm not certain who controls the OpenCL spec, but this seems like it should be a decision that comes from there. Or is this functionality outside of the OpenCL spec?

I guess I owe you some background here. OpenCL spec is controlled by Khronos organization, but Khronos provides only C-based language specification "OpenCL C" and I think this functionality is outside of the OpenCL spec.

Today Khronos organization rely on SPIR-V standard to enable high-level languages. This standard defines binary form of low-level intermediate language, which can be targeted by high-level language compiler like C++/Python/Java/Haskel/etc. High level level languages usually have separate working groups or standardization committees defining language features.

In addition to that SYCL working group within Khronos organization defines a C++-based abstraction interface to program accelerators like GPU, FPGA, DPS. SYCL interfaces do not expose any new C++ keywords or attributes and can be implemented as library using standard C++, but this implementation won't be able to offload execution of C++ code to an accelerator as standard C++ do not provide required facilities. To enable execution on accelerators, we implemented "SYCL device compiler" mode in clang and enhanced SYCL library with a few non-standard C++ extensions (e.g. attributes). Our implementation targets SPIR-V format for accelerated code and OpenCL API to communicate with accelerators. AFAIK, Codeplay team uses CUDA to enable execution of the SYCL code on NVIDIA GPUs.

In our implementation we are trying to re-use existing clang infrastructure developed for other GPU programming models OpenCL/OpenMP offload/CUDA/HIP, but due to design differences it can't always be re-used as is. For instance, if I understand it correctly, we can't use OpenCL address space attributes exposed as keywords as they might break valid C++ code - https://godbolt.org/z/fF5Ng5.
That's the basic motivation for this change.

In attributes, when an identifier can be interpreted as a keyword it is required to be interpreted as an identifier. We have the same issue with [[gnu::const]]. See http://eel.is/c++draft/dcl.attr.grammar#4.sentence-5

If I understand it correctly, it's the reason why const attribute has "GCC" spelling, instead of "Keyword" here https://github.com/llvm/llvm-project/blob/master/clang/include/clang/Basic/Attr.td#L940. Right?

will other implementations of OpenCL want to have the same functionality? Or is this something we expect other OpenCL implementations to largely ignore?

Exposing these attributes as non-keywords is useful for SYCL implementations. Actually this patch was developed by Codeplay team for ComputeCPP compiler - another SYCL implementation and "donated" by @Naghasan to our open source implementation to avoid implementation divergence.

To summarize: SYCL implementation need some instruments to express OpenCL address spaces in C++ code w/o breaking existing C++ code. We find that attributes fit well for this use case, but I'm open for alternative ideas.

is there a reason this should be clang::opencl_private as opposed to opencl::private?

I'm okay with [[opencl::private]] as well. I have only one problem - currently OpenCL address spaces are exposed as keywords and using them in C++ breaks valid C++ code.

I'm not certain who controls the OpenCL spec, but this seems like it should be a decision that comes from there. Or is this functionality outside of the OpenCL spec?

I guess I owe you some background here. OpenCL spec is controlled by Khronos organization, but Khronos provides only C-based language specification "OpenCL C" and I think this functionality is outside of the OpenCL spec.

Today Khronos organization rely on SPIR-V standard to enable high-level languages. This standard defines binary form of low-level intermediate language, which can be targeted by high-level language compiler like C++/Python/Java/Haskel/etc. High level level languages usually have separate working groups or standardization committees defining language features.

In addition to that SYCL working group within Khronos organization defines a C++-based abstraction interface to program accelerators like GPU, FPGA, DPS. SYCL interfaces do not expose any new C++ keywords or attributes and can be implemented as library using standard C++, but this implementation won't be able to offload execution of C++ code to an accelerator as standard C++ do not provide required facilities. To enable execution on accelerators, we implemented "SYCL device compiler" mode in clang and enhanced SYCL library with a few non-standard C++ extensions (e.g. attributes). Our implementation targets SPIR-V format for accelerated code and OpenCL API to communicate with accelerators. AFAIK, Codeplay team uses CUDA to enable execution of the SYCL code on NVIDIA GPUs.

In our implementation we are trying to re-use existing clang infrastructure developed for other GPU programming models OpenCL/OpenMP offload/CUDA/HIP, but due to design differences it can't always be re-used as is. For instance, if I understand it correctly, we can't use OpenCL address space attributes exposed as keywords as they might break valid C++ code - https://godbolt.org/z/fF5Ng5.
That's the basic motivation for this change.

Thank you for the background! Now for some background of my own. :-)

Double square bracket-style attributes (which are supported in both C and C++) can only have a single level of vendor namespacing. So we can go with clang:: or opencl:: but cannot go with clang::opencl::. We control the clang vendor namespace for attributes, but we do not control the opencl vendor namespace (if one even exists). However, these attributes seem like they don't really "belong" to clang because they're OpenCL-specific moreso than clang-specific. That's why I was asking if it would make more sense to put them under an opencl namespace -- this allows Microsoft or GCC (or whatever other implementation) to implement the same semantics for their OpenCL implementations but without requiring them to introduce our vendor namespace into their products. However, I wasn't certain what entity could make decisions about that vendor namespace. Based on what you wrote, it sounds like the Khronos group is the most likely one to want to control that namespace, but I'm not certain.

To be clear, there's nothing invalid or incorrect about clang::opencl_whatever, it just looks strange because that's basically adding a second-level namespace.

In attributes, when an identifier can be interpreted as a keyword it is required to be interpreted as an identifier. We have the same issue with [[gnu::const]]. See http://eel.is/c++draft/dcl.attr.grammar#4.sentence-5

If I understand it correctly, it's the reason why const attribute has "GCC" spelling, instead of "Keyword" here https://github.com/llvm/llvm-project/blob/master/clang/include/clang/Basic/Attr.td#L940. Right?

I may not have been sufficiently clear. I was talking about attributes within double square brackets, like [[gnu::const]] -- that const is interpreted as an identifier rather than a keyword, making this a legal attribute in C and C++. So there's nothing wrong with [[opencl::private]] as an attribute, despite private being a keyword. I think you're talking about turning the keyword-like attribute __private into private, then you're correct that we do not have a way to support something like that.

will other implementations of OpenCL want to have the same functionality? Or is this something we expect other OpenCL implementations to largely ignore?

Exposing these attributes as non-keywords is useful for SYCL implementations. Actually this patch was developed by Codeplay team for ComputeCPP compiler - another SYCL implementation and "donated" by @Naghasan to our open source implementation to avoid implementation divergence.

To summarize: SYCL implementation need some instruments to express OpenCL address spaces in C++ code w/o breaking existing C++ code. We find that attributes fit well for this use case, but I'm open for alternative ideas.

I think attributes are a great approach to solving the problem. I'm only pushing back on the names of the attributes and whether we think they should be in the clang vendor namespace or an opencl one. Now that C2x has support for attributes, I would think that Khronos could be approached to see if they would like to see [[opencl::private]] as an attribute in C that could then also be used with the same semantics in a C++ program. WDYT? If they wanted to "own" the opencl vendor namespace, that would make me more comfortable adding a new attribute under that namespace. If they don't want to own that namespace, or if they don't want to use the attribute syntax in C at all, that's also fine -- we can go with what's already committed in the clang vendor namespace.

When I try to run tablegen on this file for clang/docs (as described in clang/docs/InternalsManual.rst), I get an error, introduced by this change:

$ ./bin/clang-tblgen -gen-attr-docs -I ../llvm-project/clang/include ../llvm-project/clang/include/clang/Basic/Attr.td -o /tmp/AttributeReference.rst

../llvm-project/clang/include/clang/Basic/Attr.td:1137:1: error: This attribute requires a heading to be specified
def OpenCLConstantAddressSpace : TypeAttr {
^

I'm at a loss as to what is wrong, but I would like to revert this change until it is fixed.

When I try to run tablegen on this file for clang/docs (as described in clang/docs/InternalsManual.rst), I get an error, introduced by this change:

$ ./bin/clang-tblgen -gen-attr-docs -I ../llvm-project/clang/include ../llvm-project/clang/include/clang/Basic/Attr.td -o /tmp/AttributeReference.rst

../llvm-project/clang/include/clang/Basic/Attr.td:1137:1: error: This attribute requires a heading to be specified
def OpenCLConstantAddressSpace : TypeAttr {
^

I'm at a loss as to what is wrong, but I would like to revert this change until it is fixed.

This should be fixed in f5193d87feaedb411255e92979abd6b62522bc38 now, thank you for pointing it out!

bader added a comment.Dec 6 2019, 10:07 AM

@aaron.ballman, thank you for fixing the problem with documentation generation.

With regards to attributes naming question, let me check if I get it right.

  1. You suggest checking with Khronos if they want to adopt [[opencl::private]] attribute names in OpenCL kernel language standard. Right? @Anastasia, can you help with this?
  2. If Khronos leaves this decision to implementers, are current names (e.g. [[clang::opencl_private]]) look okay or we should consider other options?

@aaron.ballman, thank you for fixing the problem with documentation generation.

No problem!

With regards to attributes naming question, let me check if I get it right.

  1. You suggest checking with Khronos if they want to adopt [[opencl::private]] attribute names in OpenCL kernel language standard. Right? @Anastasia, can you help with this?

That's correct.

  1. If Khronos leaves this decision to implementers, are current names (e.g. [[clang::opencl_private]]) look okay or we should consider other options?

If they want to leave it to implementers, I think the names you have now are fine.