Contribution Guide — Unified Runtime Specification documentation (original) (raw)

Contribution Guide#

This contribution guide explains how to contribute to the Unified Runtime project and what processes you must follow in order to have your changes accepted into the project.

Important

Before making a contribution to the specification you should determine if the change should be made directly to the core specification or introduced as an experimental feature. The criteria we use to make this distinction are as follows:

If the feature in question matches any of these criteria, please refer to the Experimental Features section, otherwise refer to the Core Features section. If you are unsure how to proceed please create an issueasking or clarification.

If you are unsure whether a feature can be supported by certain adapters please seek the advice of an appropriate stakeholder or ask the Unified Runtime team via the GitHub issue tracker.

When creating issues pertaining the to unified runtime, please include the [UR] tag in the issue title.

Build Environment#

To be able to generate the source from the YAML files, the build environment must be configured correctly and all dependencies must be installed. The instructions for a basic setup are available in the README.

The following additional dependencies are required to support the generatetarget:

Doxygen can be installed via your system’s package manager, e.g. on Ubuntusudo apt install doxygen, or by downloading it from the Doxygen website. It must be available on the current PATH when the script is run.

One way to install the requirements for the script is using a Python virtual environment. This can be set up by running the following commands from the project root:

$ python3 -m venv .local $ source .local/bin/activate $ pip install -r third_party/requirements.txt

The virtual environment can be subsequently reactivated before any builds without needing to reinstall the requirements:

$ source .local/bin/activate

Alternatively, a Docker container can be used instead of a virtual environment. Instructions on building and using a Docker image can be found in.github/docker

You must also enable the UR_FORMAT_CPP_STYLE CMake option to allow formatting of the generated code, or the generate target will not be available.

$ cmake -B build/ -DUR_FORMAT_CPP_STYLE=ON

You can then follow the instructions below to use the generate target to regenerate the source.

Generating Source#

The specification and many other components in the Unified Runtime project are generated from a set of YAML files which are used as inputs to a Makobased templating system. The YAML file syntax is defined in YAML syntax. To generate the outputs of the Mako templates a build directory must be configured as detailed above. Upon successfully configuring a build directory, generate the outputs with the following command (or suitable build system equivalent):

$ cmake --build build --target generate

Note

The generated source and header files are placed into /source and/include directories respectively. You should make no attempt to modify them directly. When the generator is run all your changes will be overwritten.

Writing YAML#

Please read the Naming Convention section prior to making a contribution and refer to the YAML syntax for specifics of how to define the required constructs.

When writing *.yml files and ur or UR should exist in the output use $x or $X respectively. These will be replaced whileGenerating Source.

Additionally, the following conventions must be followed for function arguments:

Limitations#

There are some limitations on the patterns our spec generator can handle. These limitations are due to convenience of implementation rather than design: if they are preventing you from implementing a feature please open an issue and we will be happy to try and accommodate your use case. Otherwise beware of the following:

Forks and Pull Requests#

To submit a pull request to Unified Runtime, you must first create your own personal fork of the project and submit your changes to a branch. By convention we name our branches <your_name>/<short_description>, where the description indicates the intent of your change. You can then raise a pull request targeting intel/llvm:sycl.

Please ensure you include the [UR] tag in the title of your pull request.

When making changes to the specification you must commit all changes to files in the project as a result of Generating Source.

Before your pull request is merged it must pass all jobs in the GitHub Actions workflow and must be reviewed by all reviewer teams tagged as code-owners.

Hint

When rebasing a branch on top of main results in merged conflicts it is recommended to resolve conflicts in the *.yml files then Generating Source. This will automatically resolve conflicts in the generated source files, leaving only conflicts in non-generated source files to be resolved, if any.

By default, any new fork has all GitHub Actions workflows disabled. If you would like to, e.g., test your branch using our CI workflows before creating a pull request, you have to enter the Actions tab on your fork and enable workflows for this repository. When they are not needed anymore, you can disable them again, but it has to be done one by one. The CI on the upstream repository gets busy from time to time. That’s why you may want to enable workflows on your fork to get the testing results quicker. The disadvantage of the CI on your fork is that it may report some failing jobs you may not expect, and it does not run some of the jobs (due to a lack of specific hardware from self-hosted runners).

Core Features#

A core feature must have a stable API/ABI and should strive to be supported across all adapters. However, core features may be optional and thus only supported in one or more adapters. A core feature should also strive to enable similar functionality in parallel language runtimes (such as SYCL, OpenMP, …) where possible although this is a secondary concern.

Hint

Optional features should be avoided as much as possible to maximize portability across adapters and reduce the overhead required to make use of features in parallel language runtimes.

Core features are defined in the *.yml files in the scripts/coredirectory. Most of the files are named after the API object who’s interface is defined within them, with the following exceptions:

Core Optional Features#

Optional core features must be supported in at least one adapter. Support for an optional core feature must be programmatically exposed to the user via boolean query call to urDeviceGetInfo and a new enumerator of the formUR_DEVICE_INFO_<FEATURE_NAME>_SUPPORT in ur_device_info_t.

Conformance Testing#

For contributions to the core specification conformance tests should be included as part of your change. The conformance tests can be found under test/conformance/<component>, where component refers to the API object an entry-point belongs to i.e. platform, enqueue, device.

The conformance tests should ideally include end-to-end testing of all the changes to the specification if possible. At minimum, they must cover at least one test for each of the possible error codes returned, excluding any disaster cases like UR_RESULT_ERROR_OUT_OF_HOST_MEMORY or similar.

Conformance tests must not make assumptions about the adapter under test. Tests fixtures or cases must query for support of optional features and skip testing if unsupported by the adapter.

Conformance tests are ran as part of the main test target, but can also be executed using the check-unified-runtime-conformance target as follows:

cmake --build build --target check-unified-runtime-conformance

A specific device/adapter can be specified by using ONEAPI_DEVICE_SELECTORin the same way as in the DPC++ compiler.

A number of tests are skipped on certain adapters due to being known failures. To force all tests to run, including known failures,UR_CTS_ALSO_RUN_KNOWN_FAILURES may be set to 1 as an environment variable.

Experimental Features#

Warning

Experimental features:

Experimental features must be defined in two new files, where<FEATURE>/<feature> are replaced with an appropriate name:

To simplify this process please use the provided python script which will create these template files for you. You can then freely modify these files to implement your experimental feature.

$ python scripts/add_experimental_feature.py

Experimental features must not make any changes to the core YaML files and_must_ be described entirely in their own YaML file. Sometimes, however experimental feature require extending enumerations of the core specification. If this is necessary, create a new enum with the extend field set to true and list the required enumerations to support the experimental feature. These additional enumerations will updated the specification with the appropriate values.

Naming Convention#

The following naming conventions must be followed:

The following coding conventions must be followed:

In addition to the requirements referred to in the Writing YAML section, and to easily differentiate experimental feature symbols, the following conventions_must_ be adhered to when defining experimental features:

New Adapters#

The UR loader will only load UR adapter libraries made known to it via entries in scripts/core/manifests.yml. New adapters must have their own entry in that file before the loader will recognize them. See YaML.md for details about manifest semantics.