Contribution Guide
Contents
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 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:
The feature exists to enable an experimental feature in a parallel language runtime being built on top of Unified Runtime.
The design phase of the feature is expected to span multiple oneAPI releases.
A proof of concept implementation exists for a single adapter but multiple adapters are intended to be supported. It is important to consider as early as possible whether the feature is appropriate for other adapters to evaluate its portability.
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 issue asking for 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.
Generating Source#
The specification and many other components in the Unified Runtime repository are generated from a set of YAML files which are used as inputs to a Mako based 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, instructions are available in the README file. 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 core/INTRO: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 while
Generating Source.
Additionally, the following conventions must be followed for function arguments:
Argument names are
camelCase
.Arguments with pointer types are prefixed with
p
for each pointer in the type i.e.char *pMessage
,char **ppMessage
, etc.Handle arguments are prefixed with
h
i.e.hQueue
.Pointer to handle arguments, such as out parameters, are prefixed with
ph
i.e.phQueue
.
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 oneapi-src/unified-runtime:main
. Please add the experimental
label to you pull request.
When making changes to the specification you must commit all changes to files in the repository 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 no less than two 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.
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/core
directory. Most of the files are named after the API object who’s interface is
defined within them, with the following exceptions:
scripts/core/common.yml defines symbols which are used by multiple interfaces through the specification, e.g. macros, object handles, result enumerations, and structure type enumerations.
scripts/core/enqueue.yml defines commands which can be enqueued on a queue object.
scripts/core/runtime.yml defines global symbols pertaining to initialization and tear down of the entire runtime.
scripts/core/registry.yml contains an enumeration of all entry-points, past and present, for use in the XPTI tracing framework. It is automatically updated so shouldn’t require manual editing.
scripts/core/exp-<feature>.yml
see Experimental Features.
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 form
UR_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.
All tests in the Unified Runtime project are configured to use CTest to run.
All conformance tests have the conformance
label attached to them which
allows them to be run independently. To run all the conformance tests, execute
the following command from the build directory.
ctest -L "conformance"
Experimental Features#
Warning
Experimental features:
May be replaced, updated, or removed at any time.
Do not require maintaining API/ABI stability of their own additions over time.
Do not require conformance testing of their own additions.
Experimental features must be defined in two new files, where
<FEATURE>
/<feature>
are replaced with an appropriate name:
scripts/core/EXP-<FEATURE>.rst
document specifying the experimental feature in natural language.scripts/core/exp-<feature>.yml
defines the interface as an input to Generating Source.
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 <name-of-your-experimental-feature>
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:
All functions must be prefixed with
ur
All functions must use camel case
urObjectAction
conventionAll macros must use all caps
UR_NAME
conventionAll structures, enumerations and other types must follow
ur_name_t
snake case conventionAll structure members and function parameters must use camel case convention
All enumerator values must use all caps
UR_ENUM_ETOR_NAME
conventionAll handle types must end with
handle_t
All descriptor structures must end with
desc_t
All property structures must end with
properties_t
All flag enumerations must end with
flags_t
The following coding conventions must be followed:
All descriptor structures must be derived from ur_base_desc_t
All property structures must be derived from ur_base_properties_t
All function input parameters must precede output parameters
All functions must return ur_result_t
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:
All functions must use camel case
urObjectActionExp
convention.All macros must use all caps
UR_NAME_EXP
convention.All structures, enumerations, and other types must follow
ur_exp_name_t
name case convention.