[llvm] [Offload] Introduce offload-tblgen and initial new API implementation (PR #108413)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 12 08:58:51 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-offload
Author: Callum Fare (callumfare)
<details>
<summary>Changes</summary>
Introduce `offload-tblgen` and an initial implementation of a subset of the new API. The tablegen files are intended to be the single source of truth for the new API, with the header files, documentation, and others bits of source all automatically generated.
### offload-tblgen
See the included [README](https://github.com/callumfare/llvm-project/blob/d80db06491d85444bb6f7e59d8068a22cef3a6b4/offload/new-api/API/README.md) for more information on how the API definition and generation works. I'm happy to answer any questions about it and plan to walk through it in a future LLVM Offload call.
It should be noted that struct definitions have not been fully implemented/tested as they aren't used by the initial API definitions, but finishing that off in the future shouldn't be too much work.
The tablegen tooling has been designed to be easily extended with new backends, using the classes in `RecordTypes.hpp` to abstract over the tablegen records.
### New API
Previous discussions at the LLVM/Offload meeting have brought up the need for a new API for exposing the functionality of the plugins. This change introduces a very small subset of a new API, which is primarily for testing the offload tooling and demonstrating how a new API can fit into the existing code base without being too disruptive. Exact designs for these entry points and future additions can be worked out over time.
The new API does however introduce the bare minimum functionality to implement device discovery for Unified Runtime and SYCL. This means that the `urinfo` and `sycl-ls` tools can be used on top of Offload. A (rough) implementation of a Unified Runtime adapter (aka plugin) for Offload is available [here](https://github.com/callumfare/unified-runtime/tree/offload_adapter). Our intention is to maintain this and use it to implement and test Offload API changes with SYCL.
### Demoing the new API
```sh
$ git clone -b offload_adapter https://github.com/callumfare/unified-runtime.git
$ cd unified-runtime
$ mkdir build
$ cd build
$ cmake .. -GNinja -DUR_BUILD_ADAPTER_OFFLOAD=ON \
-DUR_OFFLOAD_INSTALL_DIR=<offload build dir containing liboffload_new.so> \
-DUR_OFFLOAD_INCLUDE_DIR=<offload build dir containing 'offload' headers directory>
$ ninja urinfo
export LD_LIBRARY_PATH=<offload build dir containing offload plugin libraries>
$ UR_ADAPTERS_FORCE_LOAD=$PWD/lib/libur_adapter_offload.so ./bin/urinfo
[cuda:gpu][cuda:0] CUDA, NVIDIA GeForce GT 1030 [12030]
# Demo with tracing
$ OFFLOAD_TRACE=1 UR_ADAPTERS_FORCE_LOAD=$PWD/lib/libur_adapter_offload.so ./bin/urinfo
---> offloadPlatformGet(.NumEntries = 0, .phPlatforms = {}, .pNumPlatforms = 0x7ffd05e4d6e0 (2))-> OFFLOAD_RESULT_SUCCESS
---> offloadPlatformGet(.NumEntries = 2, .phPlatforms = {0x564bf4040220, 0x564bf4040240}, .pNumPlatforms = nullptr)-> OFFLOAD_RESULT_SUCCESS
...
```
### Open questions and future work
* The new API is implemented in a separate library (`liboffload_new.so`). It could just as easily be part of the existing `libomptarget` library - I have no strong feelings on which is better.
* Only some of the available device info is exposed, and not all the possible device queries needed for SYCL are implemented by the plugins. A sensible next step would be to refactor and extend the existing device info queries in the plugins. The existing info queries are all strings, but the new API introduces the ability to return any arbitrary type.
* It may be sensible at some point for the plugins to implement the new API directly, and the higher level code on top of it could be made generic, but this is more of a long-term possibility.
---
Patch is 76.16 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/108413.diff
22 Files Affected:
- (modified) offload/CMakeLists.txt (+3)
- (added) offload/new-api/API/APIDefs.td (+212)
- (added) offload/new-api/API/Common.td (+75)
- (added) offload/new-api/API/Device.td (+101)
- (added) offload/new-api/API/OffloadAPI.td (+15)
- (added) offload/new-api/API/Platform.td (+94)
- (added) offload/new-api/API/README.md (+150)
- (added) offload/new-api/CMakeLists.txt (+36)
- (added) offload/new-api/README.md (+8)
- (added) offload/new-api/src/helpers.hpp (+96)
- (added) offload/new-api/src/offload_impl.cpp (+187)
- (added) offload/new-api/src/offload_lib.cpp (+23)
- (modified) offload/plugins-nextgen/common/include/PluginInterface.h (+7)
- (added) offload/tools/offload-tblgen/APIGen.cpp (+196)
- (added) offload/tools/offload-tblgen/CMakeLists.txt (+24)
- (added) offload/tools/offload-tblgen/EntryPointGen.cpp (+86)
- (added) offload/tools/offload-tblgen/FuncsGen.cpp (+54)
- (added) offload/tools/offload-tblgen/GenCommon.hpp (+58)
- (added) offload/tools/offload-tblgen/Generators.hpp (+18)
- (added) offload/tools/offload-tblgen/PrintGen.cpp (+206)
- (added) offload/tools/offload-tblgen/RecordTypes.hpp (+227)
- (added) offload/tools/offload-tblgen/offload-tblgen.cpp (+95)
``````````diff
diff --git a/offload/CMakeLists.txt b/offload/CMakeLists.txt
index 9ffe8f56b76e67..ba7be255cfe582 100644
--- a/offload/CMakeLists.txt
+++ b/offload/CMakeLists.txt
@@ -349,6 +349,9 @@ add_subdirectory(tools)
# Build target agnostic offloading library.
add_subdirectory(src)
+add_subdirectory(tools/offload-tblgen)
+add_subdirectory(new-api)
+
# Add tests.
add_subdirectory(test)
diff --git a/offload/new-api/API/APIDefs.td b/offload/new-api/API/APIDefs.td
new file mode 100644
index 00000000000000..410a28c4c90cfe
--- /dev/null
+++ b/offload/new-api/API/APIDefs.td
@@ -0,0 +1,212 @@
+//===-- APIDefs.td - Base definitions for Offload tablegen -*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the class definitions used to implement the Offload API,
+// as well as helper functions used to help populate relevant records.
+// See offload/API/README.md for more detailed documentation.
+//
+//===----------------------------------------------------------------------===//
+
+// Prefix for API naming. This could be hard-coded in the future when a value
+// is agreed upon.
+defvar PREFIX = "OFFLOAD";
+defvar prefix = !tolower(PREFIX);
+
+// Parameter flags
+defvar PARAM_IN = 0x1;
+defvar PARAM_OUT = 0x2;
+defvar PARAM_OPTIONAL = 0x4;
+defvar PARAM_IN_OPTIONAL = !or(PARAM_IN, PARAM_OPTIONAL);
+defvar PARAM_OUT_OPTIONAL = !or(PARAM_OUT, PARAM_OPTIONAL);
+
+// Does the type end with '_handle_t'?
+class IsHandleType<string Type> {
+ // size("_handle_t") == 9
+ bit ret = !if(!lt(!size(Type), 9), 0,
+ !ne(!find(Type, "_handle_t", !sub(!size(Type), 9)), -1));
+}
+
+// Does the type end with '*'?
+class IsPointerType<string Type> {
+ bit ret = !ne(!find(Type, "*", !sub(!size(Type), 1)), -1);
+}
+
+// Describes the valid range of a pointer parameter that reperesents an array
+class Range<string Begin, string End> {
+ string begin = Begin;
+ string end = End;
+}
+
+// Names the parameters that indicate the type and size of the data pointed to
+// by an opaque pointer parameter
+class TypeInfo<string TypeEnum, string TypeSize> {
+ string enum = TypeEnum;
+ string size = TypeSize;
+}
+
+class Param<string Type, string Name, string Desc, bits<3> Flags = 0> {
+ string type = Type;
+ string name = Name;
+ string desc = Desc;
+ bits<3> flags = Flags;
+ Range range = Range<"", "">;
+ TypeInfo type_info = TypeInfo<"", "">;
+ bit IsHandle = IsHandleType<type>.ret;
+ bit IsPointer = IsPointerType<type>.ret;
+}
+
+// A parameter whose range is described by other parameters in the function.
+class RangedParam<string Type, string Name, string Desc, bits<3> Flags, Range ParamRange> : Param<Type, Name, Desc, Flags> {
+ let range = ParamRange;
+}
+
+// A parameter (normally of type void*) which has its pointee type and size
+// described by other parameters in the function.
+class TypeTaggedParam<string Type, string Name, string Desc, bits<3> Flags, TypeInfo ParamTypeInfo> : Param<Type, Name, Desc, Flags> {
+ let type_info = ParamTypeInfo;
+}
+
+class Return<string Value, list<string> Conditions = []> {
+ string value = Value;
+ list<string> conditions = Conditions;
+}
+
+class ShouldCheckHandle<Param P> {
+ bit ret = !and(P.IsHandle, !eq(!and(PARAM_OPTIONAL, P.flags), 0));
+}
+
+class ShouldCheckPointer<Param P> {
+ bit ret = !and(P.IsPointer, !eq(!and(PARAM_OPTIONAL, P.flags), 0));
+}
+
+// For a list of returns that contains a specific return code, find and append
+// new conditions to that return
+class AppendConditionsToReturn<list<Return> Returns, string ReturnValue,
+ list<string> Conditions> {
+ list<Return> ret =
+ !foreach(Ret, Returns,
+ !if(!eq(Ret.value, ReturnValue),
+ Return<Ret.value, Ret.conditions#Conditions>, Ret));
+}
+
+// Add null handle checks to a function's return value descriptions
+class AddHandleChecksToReturns<list<Param> Params, list<Return> Returns> {
+ list<string> handle_params =
+ !foreach(P, Params, !if(ShouldCheckHandle<P>.ret, P.name, ""));
+ list<string> handle_params_filt =
+ !filter(param, handle_params, !ne(param, ""));
+ list<string> handle_param_conds =
+ !foreach(handle, handle_params_filt, "`NULL == "#handle#"`");
+
+ // Does the list of returns already contain ERROR_INVALID_NULL_HANDLE?
+ bit returns_has_inv_handle = !foldl(
+ 0, Returns, HasErr, Ret,
+ !or(HasErr, !eq(Ret.value, PREFIX#"_RESULT_ERROR_INVALID_NULL_HANDLE")));
+
+ list<Return> returns_out = !if(returns_has_inv_handle,
+ AppendConditionsToReturn<Returns, PREFIX # "_RESULT_ERROR_INVALID_NULL_HANDLE", handle_param_conds>.ret,
+ !listconcat(Returns, [Return<PREFIX # "_RESULT_ERROR_INVALID_NULL_HANDLE", handle_param_conds>])
+ );
+}
+
+// Add null pointer checks to a function's return value descriptions
+class AddPointerChecksToReturns<list<Param> Params, list<Return> Returns> {
+ list<string> ptr_params =
+ !foreach(P, Params, !if(ShouldCheckPointer<P>.ret, P.name, ""));
+ list<string> ptr_params_filt = !filter(param, ptr_params, !ne(param, ""));
+ list<string> ptr_param_conds =
+ !foreach(ptr, ptr_params_filt, "`NULL == "#ptr#"`");
+
+ // Does the list of returns already contain ERROR_INVALID_NULL_POINTER?
+ bit returns_has_inv_ptr = !foldl(
+ 0, Returns, HasErr, Ret,
+ !or(HasErr, !eq(Ret.value, PREFIX#"_RESULT_ERROR_INVALID_NULL_POINTER")));
+ list<Return> returns_out = !if(returns_has_inv_ptr,
+ AppendConditionsToReturn<Returns, PREFIX # "_RESULT_ERROR_INVALID_NULL_POINTER", ptr_param_conds>.ret,
+ !listconcat(Returns, [Return<PREFIX # "_RESULT_ERROR_INVALID_NULL_POINTER", ptr_param_conds>])
+ );
+}
+
+defvar DefaultReturns = [Return<PREFIX#"_RESULT_SUCCESS">,
+ Return<PREFIX#"_RESULT_ERROR_UNINITIALIZED">,
+ Return<PREFIX#"_RESULT_ERROR_DEVICE_LOST">];
+
+class APIObject {
+ string name;
+ string desc;
+}
+
+class Function : APIObject {
+ list<Param> params;
+ list<Return> returns;
+ list<string> details = [];
+ list<string> analogues = [];
+
+ list<Return> returns_with_def = !listconcat(DefaultReturns, returns);
+ list<Return> all_returns = AddPointerChecksToReturns<params,
+ AddHandleChecksToReturns<params, returns_with_def>.returns_out>.returns_out;
+}
+
+class Etor<string Name, string Desc> {
+ string name = Name;
+ string desc = Desc;
+ string tagged_type;
+}
+
+class TaggedEtor<string Name, string Type, string Desc> : Etor<Name, Desc> {
+ let tagged_type = Type;
+}
+
+class Enum : APIObject {
+ // This refers to whether the enumerator descriptions specify a return
+ // type for functions where this enum may be used as an output type. If set,
+ // all Etor values must be TaggedEtor records
+ bit is_typed = 0;
+
+ list<Etor> etors = [];
+}
+
+class StructMember<string Type, string Name, string Desc> {
+ string type = Type;
+ string name = Name;
+ string desc = Desc;
+}
+
+defvar DefaultPropStructMembers =
+ [StructMember<prefix#"_structure_type_t", "stype",
+ "type of this structure">,
+ StructMember<"void*", "pNext", "pointer to extension-specific structure">];
+
+class StructHasInheritedMembers<string BaseClass> {
+ bit ret = !or(!eq(BaseClass, prefix#"_base_properties_t"),
+ !eq(BaseClass, prefix#"_base_desc_t"));
+}
+
+class Struct : APIObject {
+ string base_class = "";
+ list<StructMember> members;
+ list<StructMember> all_members =
+ !if(StructHasInheritedMembers<base_class>.ret,
+ DefaultPropStructMembers, [])#members;
+}
+
+class Typedef : APIObject { string value; }
+
+class FptrTypedef : APIObject {
+ list<Param> params;
+ list<Return> returns;
+}
+
+class Macro : APIObject {
+ string value;
+
+ string condition;
+ string alt_value;
+}
+
+class Handle : APIObject;
diff --git a/offload/new-api/API/Common.td b/offload/new-api/API/Common.td
new file mode 100644
index 00000000000000..d293e4addfef8b
--- /dev/null
+++ b/offload/new-api/API/Common.td
@@ -0,0 +1,75 @@
+def : Macro {
+ let name = "OFFLOAD_APICALL";
+ let desc = "Calling convention for all API functions";
+ let condition = "defined(_WIN32)";
+ let value = "__cdecl";
+ let alt_value = "";
+}
+
+def : Macro {
+ let name = "OFFLOAD_APIEXPORT";
+ let desc = "Microsoft-specific dllexport storage-class attribute";
+ let condition = "defined(_WIN32)";
+ let value = "__declspec(dllexport)";
+ let alt_value = "";
+}
+
+def : Macro {
+ let name = "OFFLOAD_DLLEXPORT";
+ let desc = "Microsoft-specific dllexport storage-class attribute";
+ let condition = "defined(_WIN32)";
+ let value = "__declspec(dllexport)";
+}
+
+def : Macro {
+ let name = "OFFLOAD_DLLEXPORT";
+ let desc = "GCC-specific dllexport storage-class attribute";
+ let condition = "__GNUC__ >= 4";
+ let value = "__attribute__ ((visibility (\"default\")))";
+ let alt_value = "";
+}
+
+def : Typedef {
+ let name = "offload_bool_t";
+ let value = "uint8_t";
+ let desc = "compiler-independent type";
+}
+
+def : Handle {
+ let name = "offload_platform_handle_t";
+ let desc = "Handle of a platform instance";
+}
+
+def : Handle {
+ let name = "offload_device_handle_t";
+ let desc = "Handle of platform's device object";
+}
+
+def : Handle {
+ let name = "offload_context_handle_t";
+ let desc = "Handle of context object";
+}
+
+def : Enum {
+ let name = "offload_result_t";
+ let desc = "Defines Return/Error codes";
+ let etors =[
+ Etor<"SUCCESS", "Success">,
+ Etor<"ERROR_INVALID_VALUE", "Invalid Value">,
+ Etor<"ERROR_INVALID_PLATFORM", "Invalid platform">,
+ Etor<"ERROR_DEVICE_NOT_FOUND", "Device not found">,
+ Etor<"ERROR_INVALID_DEVICE", "Invalid device">,
+ Etor<"ERROR_DEVICE_LOST", "Device hung, reset, was removed, or driver update occurred">,
+ Etor<"ERROR_UNINITIALIZED", "plugin is not initialized or specific entry-point is not implemented">,
+ Etor<"ERROR_OUT_OF_RESOURCES", "Out of resources">,
+ Etor<"ERROR_UNSUPPORTED_VERSION", "[Validation] generic error code for unsupported versions">,
+ Etor<"ERROR_UNSUPPORTED_FEATURE", "[Validation] generic error code for unsupported features">,
+ Etor<"ERROR_INVALID_ARGUMENT", "[Validation] generic error code for invalid arguments">,
+ Etor<"ERROR_INVALID_NULL_HANDLE", "[Validation] handle argument is not valid">,
+ Etor<"ERROR_INVALID_NULL_POINTER", "[Validation] pointer argument may not be nullptr">,
+ Etor<"ERROR_INVALID_SIZE", "[Validation] invalid size or dimensions (e.g., must not be zero, or is out of bounds)">,
+ Etor<"ERROR_INVALID_ENUMERATION", "[Validation] enumerator argument is not valid">,
+ Etor<"ERROR_UNSUPPORTED_ENUMERATION", "[Validation] enumerator argument is not supported by the device">,
+ Etor<"ERROR_UNKNOWN", "Unknown or internal error">
+ ];
+}
\ No newline at end of file
diff --git a/offload/new-api/API/Device.td b/offload/new-api/API/Device.td
new file mode 100644
index 00000000000000..2a330d7ef7c4cb
--- /dev/null
+++ b/offload/new-api/API/Device.td
@@ -0,0 +1,101 @@
+//===-- Device.td - Device definitions for Offload ---------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains Offload API definitions related to the Device handle
+//
+//===----------------------------------------------------------------------===//
+
+def : Enum {
+ let name = "offload_device_type_t";
+ let desc = "Supported device types";
+ let etors =[
+ Etor<"DEFAULT", "The default device type as preferred by the runtime">,
+ Etor<"ALL", "Devices of all types">,
+ Etor<"GPU", "GPU device type">,
+ Etor<"CPU", "CPU device type">,
+ ];
+}
+
+def : Enum {
+ let name = "offload_device_info_t";
+ let desc = "Supported device info";
+ let is_typed = 1;
+ let etors =[
+ TaggedEtor<"TYPE", "offload_device_type_t", "type of the device">,
+ TaggedEtor<"PLATFORM", "offload_platform_handle_t", "the platform associated with the device">,
+ TaggedEtor<"NAME", "char[]", "Device name">,
+ TaggedEtor<"VENDOR", "char[]", "Device vendor">,
+ TaggedEtor<"DRIVER_VERSION", "char[]", "Driver version">
+ ];
+}
+
+def : Function {
+ let name = "offloadDeviceGet";
+ let desc = "Retrieves devices within a platform";
+ let details = [
+ "Multiple calls to this function will return identical device handles, in the same order.",
+ "The number and order of handles returned from this function can be affected by environment variables that filter devices exposed through API.",
+ "The returned devices are taken a reference of and must be released with a subsequent call to olDeviceRelease.",
+ "The application may call this function from simultaneous threads, the implementation must be thread-safe"
+ ];
+ let params = [
+ Param<"offload_platform_handle_t", "hPlatform", "handle of the platform instance", PARAM_IN>,
+ Param<"offload_device_type_t", "DeviceType", "the type of the devices.", PARAM_IN>,
+ Param<"uint32_t", "NumEntries", "the number of devices to be added to phDevices."
+ "If phDevices is not NULL, then NumEntries should be greater than zero. Otherwise OFFLOAD_RESULT_ERROR_INVALID_SIZE"
+ "will be returned.", PARAM_IN>,
+ RangedParam<"offload_device_handle_t*", "phDevices", "array of handle of devices."
+ "If NumEntries is less than the number of devices available, then platform shall only retrieve that number of devices.", PARAM_OUT_OPTIONAL,
+ Range<"0", "NumEntries">>,
+ Param<"uint32_t*", "pNumDevices", "pointer to the number of devices."
+ "pNumDevices will be updated with the total number of devices available.", PARAM_OUT_OPTIONAL>
+ ];
+ let returns = [
+ Return<"OFFLOAD_RESULT_ERROR_INVALID_SIZE", [
+ "`NumEntries == 0 && phDevices != NULL`"
+ ]>,
+ Return<"OFFLOAD_RESULT_ERROR_INVALID_NULL_POINTER", [
+ "`NumEntries > 0 && phDevices == NULL`"
+ ]>,
+ Return<"OFFLOAD_RESULT_ERROR_INVALID_VALUE">
+ ];
+}
+
+def : Function {
+ let name = "offloadDeviceGetInfo";
+ let desc = "Retrieves various information about device";
+ let details = [
+ "The application may call this function from simultaneous threads.",
+ "The implementation of this function should be lock-free."
+ ];
+ let params = [
+ Param<"offload_device_handle_t", "hDevice", "handle of the device instance", PARAM_IN>,
+ Param<"offload_device_info_t", "propName", "type of the info to retrieve", PARAM_IN>,
+ Param<"size_t", "propSize", "the number of bytes pointed to by pPropValue.", PARAM_IN>,
+ TypeTaggedParam<"void*", "pPropValue", "array of bytes holding the info. If propSize is not equal to or greater than the real "
+ "number of bytes needed to return the info then the OFFLOAD_RESULT_ERROR_INVALID_SIZE error is returned and "
+ "pPropValue is not used.", PARAM_OUT_OPTIONAL, TypeInfo<"propName" , "propSize">>,
+ Param<"size_t*", "pPropSizeRet", "pointer to the actual size in bytes of the queried propName.", PARAM_OUT_OPTIONAL>
+ ];
+ let returns = [
+ Return<"OFFLOAD_RESULT_ERROR_UNSUPPORTED_ENUMERATION", [
+ "If `propName` is not supported by the adapter."
+ ]>,
+ Return<"OFFLOAD_RESULT_ERROR_INVALID_SIZE", [
+ "`propSize == 0 && pPropValue != NULL`",
+ "If `propSize` is less than the real number of bytes needed to return the info."
+ ]>,
+ Return<"OFFLOAD_RESULT_ERROR_INVALID_NULL_POINTER", [
+ "`propSize != 0 && pPropValue == NULL`",
+ "`pPropValue == NULL && pPropSizeRet == NULL`"
+ ]>,
+ Return<"OFFLOAD_RESULT_ERROR_INVALID_DEVICE">,
+ Return<"OFFLOAD_RESULT_ERROR_OUT_OF_RESOURCES">,
+ Return<"OFFLOAD_RESULT_ERROR_OUT_OF_HOST_MEMORY">
+ ];
+}
diff --git a/offload/new-api/API/OffloadAPI.td b/offload/new-api/API/OffloadAPI.td
new file mode 100644
index 00000000000000..8a0c3c40581223
--- /dev/null
+++ b/offload/new-api/API/OffloadAPI.td
@@ -0,0 +1,15 @@
+//===-- OffloadAPI.td - Root tablegen file for Offload -----*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// Always include this file first
+include "APIDefs.td"
+
+// Add API definition files here
+include "Common.td"
+include "Platform.td"
+include "Device.td"
diff --git a/offload/new-api/API/Platform.td b/offload/new-api/API/Platform.td
new file mode 100644
index 00000000000000..71af04bb831998
--- /dev/null
+++ b/offload/new-api/API/Platform.td
@@ -0,0 +1,94 @@
+//===-- Platform.td - Platform definitions for Offload -----*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains Offload API definitions related to the Platform handle
+//
+//===----------------------------------------------------------------------===//
+def : Function {
+ let name = "offloadPlatformGet";
+ let desc = "Retrieves all available platforms";
+ let details = [
+ "Multiple calls to this function will return identical platforms handles, in the same order.",
+ ];
+ let params = [
+ Param<"uint32_t", "NumEntries",
+ "The number of platforms to be added to phPlatforms. If phPlatforms is not NULL, then"
+ "NumEntries should be greater than zero, otherwise OFFLOAD_RESULT_ERROR_INVALID_SIZE"
+ "will be returned.", PARAM_IN>,
+ RangedParam<"offload_platform_handle_t*", "phPlatforms",
+ "Array of handle of platforms. If NumEntries is"
+ "less than the number of platforms available, then offloadPlatformGet"
+ "shall only retrieve that number of platforms.",
+ PARAM_OUT_OPTIONAL, Range<"0", "NumEntries">>,
+ Param<"uint32_t*",
+ "pNumPlatforms", "returns the total number of platforms available.",
+ PARAM_OUT_OPTIONAL>
+ ];
+ let returns = [
+ Return<"OFFLOAD_RESULT_ERROR_INVALID_SIZE", [
+ "`NumEntries == 0 && phPlatforms != NULL`"
+ ]>
+ ];
+}
+
+def : Enum {
+ let name = "offload_platform_info_t";
+ let desc = "Supported platform info";
+ let is_typed = 1;
+ let etors = [
+ TaggedEtor<"NAME", "char[]", "The string denoting name of the platform. The size of the info needs to be dynamically queried.">,
+ TaggedEtor<"VENDOR_NAME", "char[]","The string denoting name of the vendor of the platform. The size of the info needs to be dynamically queried.">,
+ TaggedEtor<"VERSION", "char[]", "The string denoting the version of the platform. The size of the info needs to be dynamically queried.">,
+ TaggedEtor<"BACKEND", "offload_platform_backend_t", "The backend of the platform. Identifies the native backend adapter implementing this platform.">
+ ];
+}
+
+def : Enum {
+ let name = "offload_platform_backend_t";
+ let desc = "Identifies the native backend of the platform";
+ let etors =[
+ Etor<"UNKNOWN", "The backend is not recognized">,
+ Etor<"CUDA", "The backend is CUDA">,
+ Etor<"AMDGPU", "The backend is AMDGPU">,
+ ];
+}
+
+def : Function {
+ let name = "offloadPlatformGetInfo";
+ let desc = "Retrieves various information about platform";
+ let details = [
+ "The application may call this function from simultaneous threads.",
+ "The implementation of this function should be lock-free."
+ ];
+ let params = [
+ Param<"offload_platform_handle_t", "hPlatform", "handle of the platform", PARAM_IN>,
+ Param<"offload_platform_info_t", "propName", "type of the info to retrieve", PARAM_IN>,
+ Param<"size_t", "propSize", "the number of bytes pointed to by pPlatformInfo.", PARAM_IN>,
+ TypeTaggedParam<"void*...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/108413
More information about the llvm-commits
mailing list