blob: 2b17814abffcfbdec59ab044b59317cbb8faa63f [file] [view]
# Libsycl Coding Standards
:::{contents}
:local: true
:::
## Introduction
The `libsycl` project follows the
[LLVM Coding Standards](https://llvm.org/docs/CodingStandards.html) with
exceptions as described in this document.
### Naming
#### Names of Macros, Types, Functions, Variables, and Enumerators
Entities specified by the SYCL specification are named as required by the SYCL
specification. Names of all other entities follow the guidance in the LLVM
Coding Standards.
#### Names of Files and Directories
- **Directory Names** should be in snake case (e.g. `test_e2e`) except in
cases where LLVM project wide conventions are used. For example, LIT tests
often use an `Inputs` directory to hold files that are used by tests but
that should be excluded from test discovery.
- **File Names in snake case** should be used for all C++ implementation files.
For example files in directories `include`, `src`, `test`, `utils`,
and `tools` should be named in snake case.
- **File Names in camel case** should be used for most other files. For example
files in directories `cmake/modules` and `docs` should be named in camel
case.
### Extension Naming Policy
`libsycl` implements two kinds of SYCL extensions:
- **Khronos extensions** (KHR extensions) are ratified by the Khronos Group
and published alongside the SYCL specification.
- **Vendor extensions** are defined by a single vendor, which may be the LLVM
community itself.
The two kinds follow different naming rules, described below.
#### Khronos Extensions
KHR extensions are defined only by the Khronos Group. Their APIs are declared
in the `sycl::khr` namespace, and their feature-test macros are named
`SYCL_KHR_<NAME>`.
If `libsycl` adopts a KHR extension, it is implemented according to the KHR
extension specification, following the same rules as extensions adopted from
another vendor (see below).
#### Vendor Extensions
`libsycl` follows the "Guidelines for portable extensions" described in
[Chapter 6](https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#chapter.extensions)
of the SYCL 2020 specification. These guidelines require each vendor extension
to be named with a vendor string. Specifically, the extension's APIs are
declared in the `sycl::ext::<vendor>` namespace, its feature-test macro is
`SYCL_EXT_<VENDOR>_<NAME>`, and any enumerators or members it adds to core SYCL
classes (for example, aspects) are prefixed with `ext_<vendor>_`.
The vendor string tells users who defines the behavior of the feature.
| Origin of the extension | Vendor string |
| ------------------------------------------------------ | ---------------------------------------------- |
| Defined by the LLVM community | `llvm` |
| Defined by another vendor and implemented as specified | The original vendor's (e.g. `oneapi`, `intel`) |
##### Community Extensions
An extension that the LLVM community designs itself uses the `llvm` vendor
string, for example, `sycl::ext::llvm::<name>` with the feature-test macro
`SYCL_EXT_LLVM_<NAME>`. The community determines what such a feature is, so its
specification must be reviewed and committed before or together with the
implementation.
##### Extensions Adopted From Another Vendor
When `libsycl` implements an extension defined by another vendor, the extension
keeps its original name. For example, the `sycl_ext_oneapi_<name>` extension
from the Intel DPC++ compiler is implemented as `sycl::ext::oneapi::<name>`
with the feature-test macro `SYCL_EXT_ONEAPI_<NAME>`. The original vendor's
specification defines the feature:
- Any behavioral difference from that specification is a `libsycl` bug.
- The implementation refers to the specification and to the revision that it
implements.
- The feature-test macro is defined with the value of the implemented revision
only after that revision is fully implemented.
- Differences that the specification does not make observable, such as
implementation details, unspecified behavior, or diagnostic wording, are not
deviations.
- If the specification appears to be wrong, the problem is raised with the
vendor that owns it rather than fixed only in `libsycl`.
- When the vendor publishes a new revision of the specification, `libsycl` is
updated to conform to it.
If the community does not agree with some part of a vendor's extension
specification, it works with the vendor to come to an agreement. If an
agreement cannot be reached, the community is free to draft a new extension
specification with different behavior. However, this extension uses the `llvm`
vendor string. `libsycl` never intentionally implements an extension from
another vendor in a way that deviates from that vendor's specification.
#### Rationale
C++ attributes follow the same model. When GCC defines an attribute and Clang
implements it with the same behavior, Clang accepts the `gnu` spelling, as in
`struct [[gnu::packed]] S`, because GCC defines what the attribute means.
Adding it only as `[[clang::packed]]` would leave users unsure how
`gnu::packed` and `clang::packed` differ and would require more `#if` blocks
in portable code. Clang uses its own `clang` namespace for attributes it
defines itself.