Skip to content

Commit acb52a8

Browse files
[Offload] Improve liboffload documentation (#142403)
- Update the main README to reflect the current project status - Rework the main API generation documentation. General fixes/tidying, but also spell out explicitly how to make API changes at the top of the document since this is what most people will care about. --------- Co-authored-by: Martin Grant <martingrant@outlook.com>
1 parent 4e21315 commit acb52a8

File tree

3 files changed

+102
-43
lines changed

3 files changed

+102
-43
lines changed

offload/liboffload/API/README.md

Lines changed: 69 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,54 @@
11
# Offload API definitions
22

3-
**Note**: This is a work-in-progress. It is loosely based on equivalent
4-
tooling in Unified Runtime.
5-
63
The Tablegen files in this directory are used to define the Offload API. They
74
are used with the `offload-tblgen` tool to generate API headers, print headers,
85
and other implementation details.
96

107
The root file is `OffloadAPI.td` - additional `.td` files can be included in
118
this file to add them to the API.
129

10+
## Modifying the API
11+
12+
API modifications, including additions, can be made by modifying the existing
13+
`.td` files. It is also possible to add a new tablegen file to the API by adding
14+
it to the includes in `OffloadAPI.td`. When Offload is rebuilt the new
15+
definition will be included in the generated files.
16+
17+
Most API changes and additions do not require any additional work beyond this,
18+
other than new functions which are described below.
19+
20+
### Adding a new function to the API
21+
22+
When a new function is added (e.g. `offloadDeviceFoo`), the actual entry
23+
point is automatically generated, which contains validation and tracing code.
24+
It expects an implementation function (`offloadDeviceFoo_impl`) to be defined,
25+
which it will call into. The definition of this implementation function should
26+
be added to `liboffload/src/OffloadImpl.cpp`
27+
28+
In short, the steps to add a new function are:
29+
* Add the new function definition to the `.td` files.
30+
* Build the `LLVMOffload` target. The relevant files will be regenerated, but
31+
the library will fail to link because it is missing the implementation
32+
function.
33+
* Add the new implementation function to `liboffload/src/OffloadImpl.cpp`. You
34+
can copy the new function declaration from the generated
35+
`OffloadImplFuncDecls.inc` file.
36+
* Rebuild `LLVMOffload`
37+
1338
## API Objects
39+
1440
The API consists of a number of objects, which always have a *name* field and
1541
*description* field, and are one of the following types:
1642

1743
### Function
44+
1845
Represents an API entry point function. Has a list of returns and parameters.
19-
Also has fields for details (representing a bullet-point list of
20-
information about the function that would otherwise be too detailed for the
21-
description), and analogues (equivalent functions in other APIs).
46+
Also has fields for details (representing a bullet-point list of information
47+
about the function that would otherwise be too detailed for the description),
48+
and analogues (equivalent functions in other APIs).
2249

2350
#### Parameter
51+
2452
Represents a parameter to a function, has *type*, *name*, and *desc* fields.
2553
Also has a *flags* field containing flags representing whether the parameter is
2654
in, out, or optional.
@@ -30,17 +58,24 @@ A *handle* type is a pointer to an opaque struct, used to abstract over
3058
plugin-specific implementation details.
3159

3260
There are two special variants of a *parameter*:
33-
* **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)`
34-
* **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.
61+
* **RangedParameter** - Represents a parameter that has a range described by
62+
other parameters. Generally these are pointers to an arbitrary number of
63+
objects. The range is used for generating validation and printing code. E.g,
64+
a range might be between `(0, NumDevices)`
65+
* **TypeTaggedParameter** - Represents a parameter (usually of `void*` type)
66+
that has the type and size of its pointee data described by other function
67+
parameters. The type is usually described by a type-tagged enum. This allows
68+
functions (e.g. `olGetDeviceInfo`) to return data of an arbitrary type.
3569

3670
#### Return
71+
3772
A return represents a possible return code from the function, and optionally a
3873
list of conditions in which this value may be returned. The conditions list is
39-
not expected to be exhaustive. A condition is considered free-form text, but
40-
if it is wrapped in \`backticks\` then it is treated as literal code
41-
representing an error condition (e.g. `someParam < 1`). These conditions are
42-
used to automatically create validation checks by the `offload-tblgen`
43-
validation generator.
74+
not expected to be exhaustive. A condition is considered free-form text, but if
75+
it is wrapped in \`backticks\` then it is treated as literal code representing
76+
an error condition (e.g. `someParam < 1`). These conditions are used to
77+
automatically create validation checks by the `offload-tblgen` validation
78+
generator.
4479

4580
Returns are automatically generated for functions with pointer or handle
4681
parameters, so API authors do not need to exhaustively add null checks for
@@ -49,6 +84,7 @@ values automatically.
4984

5085

5186
### Struct
87+
5288
Represents a struct. Contains a list of members, which each have a *type*,
5389
*name*, and *desc*.
5490

@@ -59,24 +95,28 @@ actual C++ inheritance, but instead explicitly has those members copied in,
5995
which preserves ABI compatibility with C.
6096

6197
### Enum
98+
6299
Represents a C-style enum. Contains a list of `etor` values, which have a name
63100
and description.
64101

65-
A `TaggedEtor` record type also exists which additionally takes a type. This type
66-
is used when the enum is used as a parameter to a function with a type-tagged
67-
function parameter (e.g. `olGetDeviceInfo`).
102+
A `TaggedEtor` record type also exists which additionally takes a type. This
103+
type is used when the enum is used as a parameter to a function with a
104+
type-tagged function parameter (e.g. `olGetDeviceInfo`).
68105

69106
All enums automatically get a `<enum_name>_FORCE_UINT32 = 0x7fffffff` value,
70107
which forces the underlying type to be uint32.
71108

72109
### Handle
110+
73111
Represents a pointer to an opaque struct, as described in the Parameter section.
74112
It does not take any extra fields.
75113

76114
### Typedef
115+
77116
Represents a typedef, contains only a *value* field.
78117

79118
### Macro
119+
80120
Represents a C preprocessor `#define`. Contains a *value* field. Optionally
81121
takes a *condition* field, which allows the macro to be conditionally defined,
82122
and an *alt_value* field, which represents the value if the condition is false.
@@ -90,15 +130,20 @@ files, rather than requiring a mix of C source and tablegen.
90130
## Generation
91131

92132
### API header
133+
93134
```
94135
./offload-tblgen -I <path-to-llvm>/offload/API <path-to-llvm>/offload/API/OffloadAPI.td --gen-api
95136
```
96137
The comments in the generated header are in Doxygen format, although
97138
generating documentation from them hasn't been implemented yet.
98139

99-
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.
140+
The entirety of this header is generated by Tablegen, rather than having a
141+
predefined header file that includes one or more `.inc` files. This is because
142+
this header is expected to be part of the installation and distributed to
143+
end-users, so should be self-contained.
100144

101145
### Entry Points
146+
102147
```
103148
./offload-tblgen -I <path-to-llvm>/offload/API <path-to-llvm>/offload/API/OffloadAPI.td --gen-entry-points
104149
```
@@ -111,40 +156,28 @@ function calls with arguments and results. The tracing can be enabled with the
111156
`OFFLOAD_TRACE` environment variable.
112157

113158
### Implementation function declarations
159+
114160
```
115161
./offload-tblgen -I <path-to-llvm>/offload/API <path-to-llvm>/offload/API/OffloadAPI.td --gen-impl-func-decls
116162
```
117163
Generates declarations of the implementation of functions of every entry point
118164
in the API, e.g. `offloadDeviceFoo_impl` for `offloadDeviceFoo`.
119165

120166
### Print header
167+
121168
```
122169
./offload-tblgen -I <path-to-llvm>/offload/API <path-to-llvm>/offload/API/OffloadAPI.td --gen-print-header
123170
```
124-
This header contains `std::ostream &operator<<(std::ostream&)` definitions for
125-
various API objects, including function parameters.
171+
This header contains `llvm::raw_ostream &operator<<(llvm::raw_ostream &)`
172+
definitions for various API objects, including function parameters.
126173

127174
As with the API header, it is expected that this header is part of the installed
128175
package, so it is entirely generated by Tablegen.
129176

130177
For ease of implementation, and since it is not strictly part of the API, this
131178
is a C++ header file. If a C version is desirable it could be added.
132179

133-
### Future Tablegen backends
134-
`RecordTypes.hpp` contains wrappers for all of the API object types, which will
135-
allow more backends to be easily added in future.
136-
137-
## Adding to the API
138-
139-
A new object can be added to the API by adding to one of the existing `.td`
140-
files. It is also possible to add a new tablegen file to the API by adding it
141-
to the includes in `OffloadAPI.td`. When the `OffloadGenerate` target is
142-
rebuilt, the new definition will be included in the generated files.
143-
144-
### Adding a new entry point
180+
### Additional Tablegen backends
145181

146-
When a new entry point is added (e.g. `offloadDeviceFoo`), the actual entry
147-
point is automatically generated, which contains validation and tracing code.
148-
It expects an implementation function (`offloadDeviceFoo_impl`) to be defined,
149-
which it will call into. The definition of this implementation function should
150-
be added to `src/OffloadImpl.cpp`
182+
`RecordTypes.hpp` contains wrappers for all of the API object types, which
183+
allows new backends to be easily added if needed.

offload/liboffload/README.md

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,34 @@
1-
# Offload New API
1+
# Liboffload
22

3-
This directory contains the implementation of the experimental work-in-progress
4-
new API for Offload. It builds on top of the existing plugin implementations but
5-
provides a single level of abstraction suitable for runtimes for languages other
6-
than OpenMP to be built on top of.
3+
This directory contains the implementation of the work-in-progress new API for
4+
Offload. It builds on top of the existing plugin implementations but provides a
5+
single level of abstraction suitable for implementation of many offloading
6+
language runtimes, rather than just OpenMP.
77

8-
See the [API definition readme](API/README.md) for implementation details.
8+
## Testing liboffload
9+
10+
The main test suite for liboffload can be run with the `check-offload-unit`
11+
target, which runs the `offload.unittests` executable. The test suite will
12+
automatically run on every available device, but can be restricted to a single
13+
platform (CUDA, AMDGPU) with a command line argument:
14+
15+
```sh
16+
$ ./offload.unittests --platform=CUDA
17+
```
18+
19+
Tracing of Offload API calls can be enabled by setting the `OFFLOAD_TRACE`
20+
environment variable. This works with any program that uses liboffload.
21+
22+
```sh
23+
$ OFFLOAD_TRACE=1 ./offload.unittests
24+
---> olInit()-> OL_SUCCESS
25+
# etc
26+
```
27+
28+
The host plugin is not currently supported.
29+
30+
## Modifying liboffload
31+
32+
The main header (`OffloadAPI.h`) and some implementation details are
33+
autogenerated with tablegen. See the [API definition README](API/README.md)
34+
for implementation details.

offload/tools/offload-tblgen/MiscGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ void EmitOffloadErrcodes(const RecordKeeper &Records, raw_ostream &OS) {
8282
#endif
8383
8484
// Error codes are shared between PluginInterface and liboffload.
85-
// To add new error codes, add them to offload/liboffload/API/Common.td and run the GenerateOffload target.
85+
// To add new error codes, add them to offload/liboffload/API/Common.td.
8686
8787
)";
8888

0 commit comments

Comments
 (0)