mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-16 17:37:03 +00:00

https://github.com/codespell-project/codespell % `codespell --ignore-words-list=archtype,hsa,identty,inout,iself,nd,te,ths,vertexes --write-changes`
151 lines
6.8 KiB
Markdown
151 lines
6.8 KiB
Markdown
# Offload API definitions
|
|
|
|
**Note**: This is a work-in-progress. It is loosely based on equivalent
|
|
tooling in Unified Runtime.
|
|
|
|
The Tablegen files in this directory are used to define the Offload API. They
|
|
are used with the `offload-tblgen` tool to generate API headers, print headers,
|
|
and other implementation details.
|
|
|
|
The root file is `OffloadAPI.td` - additional `.td` files can be included in
|
|
this file to add them to the API.
|
|
|
|
## API Objects
|
|
The API consists of a number of objects, which always have a *name* field and
|
|
*description* field, and are one of the following types:
|
|
|
|
### Function
|
|
Represents an API entry point function. Has a list of returns and parameters.
|
|
Also has fields for details (representing a bullet-point list of
|
|
information about the function that would otherwise be too detailed for the
|
|
description), and analogues (equivalent functions in other APIs).
|
|
|
|
#### Parameter
|
|
Represents a parameter to a function, has *type*, *name*, and *desc* fields.
|
|
Also has a *flags* field containing flags representing whether the parameter is
|
|
in, out, or optional.
|
|
|
|
The *type* field is used to infer if the parameter is a pointer or handle type.
|
|
A *handle* type is a pointer to an opaque struct, used to abstract over
|
|
plugin-specific implementation details.
|
|
|
|
There are two special variants of a *parameter*:
|
|
* **RangedParameter** - Represents a parameter that has a range described by other parameters. Generally these are pointers to an arbitrary number of objects. The range is used for generating validation and printing code. E.g, a range might be between `(0, NumDevices)`
|
|
* **TypeTaggedParameter** - Represents a parameter (usually of `void*` type) that has the type and size of its pointee data described by other function parameters. The type is usually described by a type-tagged enum. This allows functions (e.g. `olGetDeviceInfo`) to return data of an arbitrary type.
|
|
|
|
#### Return
|
|
A return represents a possible return code from the function, and optionally a
|
|
list of conditions in which this value may be returned. The conditions list is
|
|
not expected to be exhaustive. A condition is considered free-form text, but
|
|
if it is wrapped in \`backticks\` then it is treated as literal code
|
|
representing an error condition (e.g. `someParam < 1`). These conditions are
|
|
used to automatically create validation checks by the `offload-tblgen`
|
|
validation generator.
|
|
|
|
Returns are automatically generated for functions with pointer or handle
|
|
parameters, so API authors do not need to exhaustively add null checks for
|
|
these types of parameters. All functions also get a number of default return
|
|
values automatically.
|
|
|
|
|
|
### Struct
|
|
Represents a struct. Contains a list of members, which each have a *type*,
|
|
*name*, and *desc*.
|
|
|
|
Also optionally takes a *base_class* field. If this is either of the special
|
|
`offload_base_properties_t` or `offload_base_desc_t` structs, then the struct
|
|
will inherit members from those structs. The generated struct does **not** use
|
|
actual C++ inheritance, but instead explicitly has those members copied in,
|
|
which preserves ABI compatibility with C.
|
|
|
|
### Enum
|
|
Represents a C-style enum. Contains a list of `etor` values, which have a name
|
|
and description.
|
|
|
|
A `TaggedEtor` record type also exists which additionally takes a type. This type
|
|
is used when the enum is used as a parameter to a function with a type-tagged
|
|
function parameter (e.g. `olGetDeviceInfo`).
|
|
|
|
All enums automatically get a `<enum_name>_FORCE_UINT32 = 0x7fffffff` value,
|
|
which forces the underlying type to be uint32.
|
|
|
|
### Handle
|
|
Represents a pointer to an opaque struct, as described in the Parameter section.
|
|
It does not take any extra fields.
|
|
|
|
### Typedef
|
|
Represents a typedef, contains only a *value* field.
|
|
|
|
### Macro
|
|
Represents a C preprocessor `#define`. Contains a *value* field. Optionally
|
|
takes a *condition* field, which allows the macro to be conditionally defined,
|
|
and an *alt_value* field, which represents the value if the condition is false.
|
|
|
|
Macro arguments are presented in the *name* field (e.g. name = `mymacro(arg)`).
|
|
|
|
While there may seem little point generating a macro from tablegen, doing this
|
|
allows the entire source of the header file to be generated from the tablegen
|
|
files, rather than requiring a mix of C source and tablegen.
|
|
|
|
## Generation
|
|
|
|
### API header
|
|
```
|
|
./offload-tblgen -I <path-to-llvm>/offload/API <path-to-llvm>/offload/API/OffloadAPI.td --gen-api
|
|
```
|
|
The comments in the generated header are in Doxygen format, although
|
|
generating documentation from them hasn't been implemented yet.
|
|
|
|
The entirety of this header is generated by Tablegen, rather than having a predefined header file that includes one or more `.inc` files. This is because this header is expected to be part of the installation and distributed to end-users, so should be self-contained.
|
|
|
|
### Entry Points
|
|
```
|
|
./offload-tblgen -I <path-to-llvm>/offload/API <path-to-llvm>/offload/API/OffloadAPI.td --gen-entry-points
|
|
```
|
|
These functions form the actual Offload interface, and are wrappers over the
|
|
functions that contain the actual implementation (see
|
|
'Adding a new entry point').
|
|
|
|
They implement automatically generated validation checks, and tracing of
|
|
function calls with arguments and results. The tracing can be enabled with the
|
|
`OFFLOAD_TRACE` environment variable.
|
|
|
|
### Implementation function declarations
|
|
```
|
|
./offload-tblgen -I <path-to-llvm>/offload/API <path-to-llvm>/offload/API/OffloadAPI.td --gen-impl-func-decls
|
|
```
|
|
Generates declarations of the implementation of functions of every entry point
|
|
in the API, e.g. `offloadDeviceFoo_impl` for `offloadDeviceFoo`.
|
|
|
|
### Print header
|
|
```
|
|
./offload-tblgen -I <path-to-llvm>/offload/API <path-to-llvm>/offload/API/OffloadAPI.td --gen-print-header
|
|
```
|
|
This header contains `std::ostream &operator<<(std::ostream&)` definitions for
|
|
various API objects, including function parameters.
|
|
|
|
As with the API header, it is expected that this header is part of the installed
|
|
package, so it is entirely generated by Tablegen.
|
|
|
|
For ease of implementation, and since it is not strictly part of the API, this
|
|
is a C++ header file. If a C version is desirable it could be added.
|
|
|
|
### Future Tablegen backends
|
|
`RecordTypes.hpp` contains wrappers for all of the API object types, which will
|
|
allow more backends to be easily added in future.
|
|
|
|
## Adding to the API
|
|
|
|
A new object can be added to the API by adding to one of the existing `.td`
|
|
files. It is also possible to add a new tablegen file to the API by adding it
|
|
to the includes in `OffloadAPI.td`. When the offload target is rebuilt, the
|
|
new definition will be included in the generated files.
|
|
|
|
### Adding a new entry point
|
|
|
|
When a new entry point is added (e.g. `offloadDeviceFoo`), the actual entry
|
|
point is automatically generated, which contains validation and tracing code.
|
|
It expects an implementation function (`offloadDeviceFoo_impl`) to be defined,
|
|
which it will call into. The definition of this implementation function should
|
|
be added to `src/offload_impl.cpp`
|