-
Notifications
You must be signed in to change notification settings - Fork 790
Initial version of the proposal of SYCL/DPC++ language features control #1793
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
Changes from all commits
3254bcd
8829abc
e702e9b
39c89f3
1d858ed
385b6a4
349ec2d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
# Controlling SYCL/DPC++ language features | ||
|
||
This documents aims to describe a mechanism which is used to control (i.e. | ||
enable or disable) different SYCL/DPC++ language and library features, like | ||
version of SYCL/DPC++ standard to use, set of extensions to use, etc. | ||
|
||
## Controlling SYCL/DPC++ standard version | ||
|
||
In order to control the language standard to compile for, the following options | ||
can be used: | ||
|
||
`-sycl-std=<value>`, `--sycl-std=<value>`, `--sycl-std <value>` | ||
|
||
SYCL language standard to compile for. | ||
|
||
Possible values: | ||
|
||
- `2017`, `121`, `1.2.1`, `sycl-1.2.1`: corresponds to SYCL 1.2.1 | ||
specification, see [SYCL Registry] for more details and the specification | ||
text. | ||
|
||
- `dpcpp-0.8`: corresponds to DPC++ version documented in oneAPI 0.8 | ||
|
||
Basically, `-sycl-std=dpcpp-0.8` implies support for SYCL 1.2.1 specification | ||
plus several extensions. | ||
|
||
See [oneAPI Specification] for more details and the specification text. | ||
|
||
[SYCL Registry]: https://www.khronos.org/registry/SYCL/ | ||
[oneAPI Specification]: https://spec.oneapi.com/ | ||
|
||
Note: `-sycl-std` **doesn't** imply any C++ standard version to be set, | ||
which means that the same default value as for C++ source is used. If by some | ||
reason, that default version is not a desired one, it is possible to change C++ | ||
version independently of SYCL/DPC++ standard version via specifying additional | ||
option: `-sycl-std=1.2.1 -std=c++14`, for example. | ||
|
||
If SYCL/DPC++ standard version and C++ standard version (either default value | ||
for the compiler or one which was explicitly set via `-std`) are incompatible, | ||
then it is expected to see compilation errors. Incompatible means that C++ | ||
standard version is less than minimum required by SYCL/DPC++ standard. | ||
|
||
`-std=<value>`, `--std=<value>`, `--std <value>` | ||
|
||
One more way to specify SYCL/DPC++ standard version is to use a general clang | ||
option, which allows to specify language standard to compile for. | ||
|
||
Supported values (besides listed in clang documentation/help): | ||
|
||
- `sycl-1.2.1`, `sycl-2017`: corresponds to `-sycl-std=1.2.1` | ||
- `dpcpp-0.8`: corresponds to `-sycl-std=dpcpp-0.8` | ||
|
||
Note: setting SYCL or DPC++ standard version via `-std` option automatically | ||
implies some C++ standard version to be set: it is the larger of the default C++ | ||
version of a compiler and the minimum required version by SYCL/DPC++ spec. | ||
For example, for SYCL 1.2.1 it would be C++14 with current clang version, while | ||
for DPC++ 0.8 it would be C++17. | ||
|
||
Please note that if you specify `-std` flag several times, only the last | ||
value takes effect. This means, that if you want to specify a particular C++ | ||
standard version instead of some default one implied by the SYCL/DPC++ standard, | ||
you have to use two separate options: `-sycl-std` and `-std`. | ||
|
||
## Controlling SYCL/DPC++ language extensions | ||
|
||
Both SYCL and DPC++ has several extensions or proposals about how to expand | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My understanding is that DPC++ is a set of extensions over SYCL 1.2.1 , so defining DPC++ as the -sycl-std version should simply be enabling a set of extensions on top of the sycl-2015 profile? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, I noted it here: https://github.com/intel/llvm/pull/1793/files#diff-e5315c99e6f09a6f7b056a184ea4af5fR32 However, if I understand correctly, some DPC++ extensions might still be optional, at least for some device types. You can find table with full list of extension here. For example, sub-groups are not required to be supported on FPGA and someone might want to disable that extension explicitly it target platform is FPGA: even in DPC++ mode, just to avoid accidental use of it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some DPC++ extensions could become SYCL optional features. The sycl-2020 profile could enable some optional features if the device supports them. So any DPC++ extension that has been included on the SYCL 2020 document but it is only supported on some devices will be enabled when -sycl-std=sycl2020 is set. The -sycl-std=dpcpp-0.XX profile would only add those extensions not yet on SYCL specification document. I guess is a larger discussion than this PR. |
||
standard with new features, which might be vendor- or device-specific. | ||
|
||
Each extension can be separately enabled or disabled depending on user | ||
preferences. List of extensions enabled by default is controlled by SYCL/DPC++ | ||
standard version. | ||
|
||
Enabling/disabling extensions is done via single `-sycl-ext` option. It accepts | ||
comma-separated list of extension names prefixed with `+` or `-` to indicate | ||
whether particular extension should be enabled or disabled. It is possible to | ||
specify that option several times: value from each next occurrence will be added | ||
to already specified ones, forming single extensions string. | ||
|
||
Example: `-sycl-ext=+EXTENSION_NAME1,-EXTENSION_NAME2` - this option specifies | ||
that `EXTENSION_NAME1` extension should be enabled and `EXTENSION_NAME2` should | ||
be disabled. `-sycl-ext=+EXTENSION_NAME1 -sycl-ext=-EXTENSION_NAME2` gives the | ||
same result. | ||
|
||
When the same extension is mentioned several times within single (or several) | ||
`-sycl-ext` options, the last occurrence overrides all previous ones, i.e. | ||
`-sycl-ext=+EXTENSION_NAME1,-EXTENSION_NAME1,+EXTENSION_NAME1` will leave | ||
`EXTENSION_NAME1` enabled. | ||
|
||
When particular extension is enabled, the compiler automatically defines a macro | ||
with the same name, i.e. if `-sycl-ext=EXTENSION_NAME1` command line option was | ||
specified, then `EXTENSION_NAME1` macro will be defined. | ||
|
||
**TODO**: update table with supported extensions with identifiers (macro or | ||
compiler options), which should be used to enable/disable them. | ||
Comment on lines
+93
to
+94
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds great, maybe the macro checks could read +1 for a table to find extension flag names, macros and reference. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BTW, table with extensions and references to corresponding specs already exists: https://github.com/intel/llvm/blob/sycl/sycl/doc/extensions/README.md Will be extended with additional information as we finalize this proposal. I'm not exactly sure about The rest looks like Personally, I think that it would be good to adapt that to SYCL. The 1.2.1 spec doesn't say anything about extensions, but I hope that the next major version will do. We have corresponding proposal, which mentions feature test macro, but with a bit different wording: |
||
|
||
### Materials for discussion | ||
|
||
Details of controlling SYCL/DPC++ language extensions for sure are not settled | ||
down yet and there are few questions and different ways of answering them. | ||
|
||
Information below is provided to highlight main questions and pros and cons of | ||
different solutions to select the best one. | ||
|
||
#### Macro vs. compiler option for header-only extensions | ||
|
||
There are extensions/proposals, which doesn't require any specific changes | ||
in the compiler or underlying components, but just define some helpers or | ||
sugar in the API and therefore, can be purely implemented in header files, | ||
without even changing SYCL/DPC++ runtime. For example, | ||
[SYCL_INTEL_device_specific_kernel_queries] | ||
|
||
[SYCL_INTEL_device_specific_kernel_queries]: https://github.com/intel/llvm/blob/sycl/sycl/doc/extensions/DeviceSpecificKernelQueries/SYCL_INTEL_device_specific_kernel_queries.asciidoc | ||
|
||
On the one hand, it shouldn't be necessary to modify the compiler in order to | ||
enable/disable some new methods or types defined in some header file. It should | ||
be enough to guard the content of a such file with some `#ifdef EXTENSION_NAME` | ||
and user is expected to pass `-DEXTENSION_NAME` to compiler in order to use such | ||
extension. | ||
|
||
So, the main pros here is that no changes to the compiler is needed at all. | ||
|
||
However, there are several downsides of that approach: | ||
|
||
- According to [Predefined macros] section from [SYCL_INTEL_extension_api] | ||
proposal, if toolchain supports extension, it should _automatically_ define | ||
corresponding macro. So, if we require from user to specify the macro for an | ||
extension, it contradicts with the current proposal of extensions mechanism in | ||
SYCL. | ||
|
||
- It is inconsistent for users (and they likely don't really care about how | ||
particular extension is designed internally) why some of them are enabled | ||
via some compiler flag and another ones are enabled via macro. Also, | ||
implementation of every extension might be changed in the future as extension | ||
and the whole SYCL implementation evolves over time. | ||
|
||
- It is easy to make a typo in some extension name and instead of having one | ||
clear error that extension name is invalid, user will get bunch of errors that | ||
particular types/methods or functions are not available. For example: | ||
`-DSYCL_INTEL_SUBGRUOP_ALGORITHMS_ENABLE` - note the typo. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think its better if all extensions are enabled via flags. I don't think this should prevent users from doing it manually, but having a consistent way of enabling/disabling them would be preferable. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Exactly. I guess that internally modifications to header files will be guarded by |
||
|
||
[SYCL_INTEL_extension_api]: https://github.com/intel/llvm/blob/sycl/sycl/doc/extensions/ExtensionMechanism/SYCL_INTEL_extension_api.asciidoc | ||
[Predefined macros]: https://github.com/intel/llvm/blob/sycl/sycl/doc/extensions/ExtensionMechanism/SYCL_INTEL_extension_api.asciidoc#predefined-macros | ||
|
||
#### -sycl-ext vs. -fsycl-extension-name/-fno-sycl-extension-name | ||
|
||
Another one way to enable/disable extensions is to provide separate option | ||
for each extensions. | ||
|
||
There are pros and cons of both approaches: | ||
|
||
##### Single flag, i.e. -sycl-ext | ||
|
||
Pros: | ||
- We don't have to hardcode list of known extensions and update the compiler | ||
for each new extension we have prepared: `-cl-std` works in this manner | ||
|
||
- This simplifies prototyping of new extensions, especially if they are | ||
header-only | ||
|
||
- This allows to easily treat header-only extensions in the same way as | ||
actual compiler extension and change the implementation without any | ||
updates in compiler/toolchain interface (command line options) | ||
|
||
- Enabling/disabling extension via this option could automatically define | ||
corresponding macro, which can be used by header-only extensions to hide | ||
new classes/APIs and other stuff introduced by the extension to avoid it | ||
being accidentally used | ||
|
||
Cons: | ||
- Without list of known extensions, we cannot emit proper diagnostic that some | ||
unknown extension was enabled just because of the typo in its spelling | ||
|
||
- Potentially, we could introduce one more option, which will allow to check | ||
that list of enabled/disabled extensions doesn't contain anything unknown, | ||
but this again means change of the compiler for each even header-only | ||
extension | ||
|
||
- According to [Predefined macros] section from [SYCL_INTEL_extension_api] | ||
proposal, extension-specific macro should not only be defined, but also has a | ||
value in particular form. How can we automatically put any meaningful value | ||
in there without having predefined list of known extensions? Do we need to | ||
extend the format so user can specify which version of the extension is | ||
needed (`-sycl-ext=+EXTENSION_NAME1=123`)? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Having a multiple-option flag can be problematic for build systems, or for users that have scripts to generate command line flags. Is there an example of this type of flag currently in clang/llvm ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Why so? This is just the same strings concatenation, just using comma instead of space as a separator. Moreover, the intent is to allow to pass
Honestly, I'm only aware of There are several flags talking about extensions, but they seem to enable some unspecified set of them, rather than allowing to precisely select desired extensions: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Documented my intent about several occurrences of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Trying to use this combination of -sycl-ext accurately on a build system like CMake could be difficult. I don't know enough about it to answer it, maybe I am just being overly cautious.
This can be confusing. Usually on the compiler command line, the latest command is the winner. However, now you have to go and find the entire command line and count all occurences to figure out which extension is enabled and which one is disabled? When you use it directly on the command line may be fine, but when you use this from some generator (again, like CMake, but may as well be some python script), you may end up having some unexpected outcomes. |
||
|
||
##### Separate flag for each extension | ||
|
||
Generic form of command line option to control SYCL/DPC++ language extension | ||
is `-f[no-]sycl-extension-name`. For example, `-fsycl-usm` flag enables support | ||
for [USM] extension, `-fno-sycl-usm` disables it. | ||
|
||
[USM]: https://github.com/intel/llvm/blob/sycl/sycl/doc/extensions/USM/USM.adoc | ||
|
||
Flags controlling the same extension might be set multiple times in the same | ||
compiler invocation: the last one overrides previous flag. | ||
|
||
Pros: | ||
- We will automatically get a diagnostic if user made a typo in an option name, | ||
which corresponds to a particular extension | ||
|
||
Cons: | ||
- Seems like a significant amount of new flags coming to the compiler | ||
- Harder to prototype and implement new extensions | ||
- What about header-only extensions? Bunch of compiler options which are only | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current list of extensions may be large, but once the next SYCL version is out, most of them will simply be the new "normal" under sycl-2020. I don't think is a huge burden for users to set them individually. Until there is a complete 2020 implementation, using the -sycl-std=dpcpp-07 should set all relevant not-target specific extensions, so the user should only have to add those extensions that are target specific. That list should not be that large, unless I am mistaken, so having separate flags should be fine. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is probably not only about user experience, but also about amount of changes in the compiler: for how long we are going to support older standard with all its extensions and corresponding flags? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Depending on how much of dpc++ gets upstreamed to llvm, this may be a long time. I would assume, however, a large part of the changes and extensions will stabilize. There is a large gap between SYCL 1.2.1 and DPC++ that will be much smaller after SYCL 2020. |
||
used to define a macro doesn't look good |
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.
Rather than listing the values again, it might be better to just refer to the values above. That way we don't need to add every future value twice.
Uh oh!
There was an error while loading. Please reload this page.
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.
This is done on purpose, as I don't think that each value from
-sycl-std
fits-std
option. I.e. with-sycl-std
option it is clear that we are talking about SYCL (or about DPC++) standard, while for-std
it might be as well CUDA, C++, HIP, OpenCL, etc. For example,2017
might be confusing: is it C++17 or SYCL 1.2.1?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.
Yes only options starting with
sycl-
ordpcpp-
should work for with-std
.