mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-16 09:16:31 +00:00
Revert "Reland - [Offload] Introduce offload-tblgen and initial new API implementation (#108413) (#117704)"
This reverts commit c979ec05642f292737d250c6682d85ed49bc7b6e. This showed failures in the post-merge CI.
This commit is contained in:
parent
fc5c89900f
commit
0cb5846a68
@ -351,9 +351,6 @@ add_subdirectory(tools)
|
||||
# Build target agnostic offloading library.
|
||||
add_subdirectory(src)
|
||||
|
||||
add_subdirectory(tools/offload-tblgen)
|
||||
add_subdirectory(liboffload)
|
||||
|
||||
# Add tests.
|
||||
add_subdirectory(test)
|
||||
|
||||
|
@ -48,17 +48,6 @@ function(find_standalone_test_dependencies)
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_program(OFFLOAD_TBLGEN_EXECUTABLE
|
||||
NAMES offload-tblgen
|
||||
PATHS ${OPENMP_LLVM_TOOLS_DIR})
|
||||
if (NOT OFFLOAD_TBLGEN_EXECUTABLE)
|
||||
message(STATUS "Cannot find 'offload-tblgen'.")
|
||||
message(STATUS "Please put 'not' in your PATH, set OFFLOAD_TBLGEN_EXECUTABLE to its full path, or point OPENMP_LLVM_TOOLS_DIR to its directory.")
|
||||
message(WARNING "The check targets will not be available!")
|
||||
set(ENABLE_CHECK_TARGETS FALSE PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_program(OPENMP_NOT_EXECUTABLE
|
||||
NAMES not
|
||||
PATHS ${OPENMP_LLVM_TOOLS_DIR})
|
||||
@ -93,7 +82,6 @@ else()
|
||||
set(OPENMP_FILECHECK_EXECUTABLE ${LLVM_RUNTIME_OUTPUT_INTDIR}/FileCheck)
|
||||
endif()
|
||||
set(OPENMP_NOT_EXECUTABLE ${LLVM_RUNTIME_OUTPUT_INTDIR}/not)
|
||||
set(OFFLOAD_TBLGEN_EXECUTABLE ${LLVM_RUNTIME_OUTPUT_INTDIR}/offload-tblgen)
|
||||
set(OFFLOAD_DEVICE_INFO_EXECUTABLE ${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-offload-device-info)
|
||||
endif()
|
||||
|
||||
|
@ -1,212 +0,0 @@
|
||||
//===-- 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 = "OL";
|
||||
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#"_ERRC_INVALID_NULL_HANDLE")));
|
||||
|
||||
list<Return> returns_out = !if(returns_has_inv_handle,
|
||||
AppendConditionsToReturn<Returns, PREFIX # "_ERRC_INVALID_NULL_HANDLE", handle_param_conds>.ret,
|
||||
!listconcat(Returns, [Return<PREFIX # "_ERRC_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#"_ERRC_INVALID_NULL_POINTER")));
|
||||
list<Return> returns_out = !if(returns_has_inv_ptr,
|
||||
AppendConditionsToReturn<Returns, PREFIX # "_ERRC_INVALID_NULL_POINTER", ptr_param_conds>.ret,
|
||||
!listconcat(Returns, [Return<PREFIX # "_ERRC_INVALID_NULL_POINTER", ptr_param_conds>])
|
||||
);
|
||||
}
|
||||
|
||||
defvar DefaultReturns = [Return<PREFIX#"_RESULT_SUCCESS">,
|
||||
Return<PREFIX#"_ERRC_UNINITIALIZED">,
|
||||
Return<PREFIX#"_ERRC_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;
|
@ -1,25 +0,0 @@
|
||||
# The OffloadGenerate target is used to regenerate the generated files in the
|
||||
# include directory. These files are checked in with the rest of the source,
|
||||
# therefore it is only needed when making changes to the API.
|
||||
|
||||
find_program(CLANG_FORMAT clang-format PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH)
|
||||
if (CLANG_FORMAT)
|
||||
set(LLVM_TARGET_DEFINITIONS ${CMAKE_CURRENT_SOURCE_DIR}/OffloadAPI.td)
|
||||
|
||||
tablegen(OFFLOAD OffloadAPI.h -gen-api)
|
||||
tablegen(OFFLOAD OffloadEntryPoints.inc -gen-entry-points)
|
||||
tablegen(OFFLOAD OffloadFuncs.inc -gen-func-names)
|
||||
tablegen(OFFLOAD OffloadImplFuncDecls.inc -gen-impl-func-decls)
|
||||
tablegen(OFFLOAD OffloadPrint.hpp -gen-print-header)
|
||||
|
||||
set(OFFLOAD_GENERATED_FILES ${TABLEGEN_OUTPUT})
|
||||
add_public_tablegen_target(OffloadGenerate)
|
||||
add_custom_command(TARGET OffloadGenerate POST_BUILD COMMAND ${CLANG_FORMAT}
|
||||
-i ${OFFLOAD_GENERATED_FILES})
|
||||
add_custom_command(TARGET OffloadGenerate POST_BUILD COMMAND ${CMAKE_COMMAND}
|
||||
-E copy_if_different ${OFFLOAD_GENERATED_FILES} "${CMAKE_CURRENT_SOURCE_DIR}/../include/generated")
|
||||
else()
|
||||
message(WARNING "clang-format was not found, so the OffloadGenerate target\
|
||||
will not be available. Offload will still build, but you will not be\
|
||||
able to make changes to the API.")
|
||||
endif()
|
@ -1,141 +0,0 @@
|
||||
def : Macro {
|
||||
let name = "OL_VERSION_MAJOR";
|
||||
let desc = "Major version of the Offload API";
|
||||
let value = "0";
|
||||
}
|
||||
|
||||
def : Macro {
|
||||
let name = "OL_VERSION_MINOR";
|
||||
let desc = "Minor version of the Offload API";
|
||||
let value = "0";
|
||||
}
|
||||
|
||||
def : Macro {
|
||||
let name = "OL_VERSION_PATCH";
|
||||
let desc = "Patch version of the Offload API";
|
||||
let value = "1";
|
||||
}
|
||||
|
||||
def : Macro {
|
||||
let name = "OL_APICALL";
|
||||
let desc = "Calling convention for all API functions";
|
||||
let condition = "defined(_WIN32)";
|
||||
let value = "__cdecl";
|
||||
let alt_value = "";
|
||||
}
|
||||
|
||||
def : Macro {
|
||||
let name = "OL_APIEXPORT";
|
||||
let desc = "Microsoft-specific dllexport storage-class attribute";
|
||||
let condition = "defined(_WIN32)";
|
||||
let value = "__declspec(dllexport)";
|
||||
let alt_value = "";
|
||||
}
|
||||
|
||||
def : Macro {
|
||||
let name = "OL_DLLEXPORT";
|
||||
let desc = "Microsoft-specific dllexport storage-class attribute";
|
||||
let condition = "defined(_WIN32)";
|
||||
let value = "__declspec(dllexport)";
|
||||
}
|
||||
|
||||
def : Macro {
|
||||
let name = "OL_DLLEXPORT";
|
||||
let desc = "GCC-specific dllexport storage-class attribute";
|
||||
let condition = "__GNUC__ >= 4";
|
||||
let value = "__attribute__ ((visibility (\"default\")))";
|
||||
let alt_value = "";
|
||||
}
|
||||
|
||||
def : Handle {
|
||||
let name = "ol_platform_handle_t";
|
||||
let desc = "Handle of a platform instance";
|
||||
}
|
||||
|
||||
def : Handle {
|
||||
let name = "ol_device_handle_t";
|
||||
let desc = "Handle of platform's device object";
|
||||
}
|
||||
|
||||
def : Handle {
|
||||
let name = "ol_context_handle_t";
|
||||
let desc = "Handle of context object";
|
||||
}
|
||||
|
||||
def : Enum {
|
||||
let name = "ol_errc_t";
|
||||
let desc = "Defines Return/Error codes";
|
||||
let etors =[
|
||||
Etor<"SUCCESS", "Success">,
|
||||
Etor<"INVALID_VALUE", "Invalid Value">,
|
||||
Etor<"INVALID_PLATFORM", "Invalid platform">,
|
||||
Etor<"DEVICE_NOT_FOUND", "Device not found">,
|
||||
Etor<"INVALID_DEVICE", "Invalid device">,
|
||||
Etor<"DEVICE_LOST", "Device hung, reset, was removed, or driver update occurred">,
|
||||
Etor<"UNINITIALIZED", "plugin is not initialized or specific entry-point is not implemented">,
|
||||
Etor<"OUT_OF_RESOURCES", "Out of resources">,
|
||||
Etor<"UNSUPPORTED_VERSION", "generic error code for unsupported versions">,
|
||||
Etor<"UNSUPPORTED_FEATURE", "generic error code for unsupported features">,
|
||||
Etor<"INVALID_ARGUMENT", "generic error code for invalid arguments">,
|
||||
Etor<"INVALID_NULL_HANDLE", "handle argument is not valid">,
|
||||
Etor<"INVALID_NULL_POINTER", "pointer argument may not be nullptr">,
|
||||
Etor<"INVALID_SIZE", "invalid size or dimensions (e.g., must not be zero, or is out of bounds)">,
|
||||
Etor<"INVALID_ENUMERATION", "enumerator argument is not valid">,
|
||||
Etor<"UNSUPPORTED_ENUMERATION", "enumerator argument is not supported by the device">,
|
||||
Etor<"UNKNOWN", "Unknown or internal error">
|
||||
];
|
||||
}
|
||||
|
||||
def : Struct {
|
||||
let name = "ol_error_struct_t";
|
||||
let desc = "Details of the error condition returned by an API call";
|
||||
let members = [
|
||||
StructMember<"ol_errc_t", "Code", "The error code">,
|
||||
StructMember<"const char*", "Details", "String containing error details">
|
||||
];
|
||||
}
|
||||
|
||||
def : Typedef {
|
||||
let name = "ol_result_t";
|
||||
let desc = "Result type returned by all entry points.";
|
||||
let value = "const ol_error_struct_t*";
|
||||
}
|
||||
|
||||
def : Macro {
|
||||
let name = "OL_SUCCESS";
|
||||
let desc = "Success condition";
|
||||
let value = "NULL";
|
||||
}
|
||||
|
||||
def : Struct {
|
||||
let name = "ol_code_location_t";
|
||||
let desc = "Code location information that can optionally be associated with an API call";
|
||||
let members = [
|
||||
StructMember<"const char*", "FunctionName", "Function name">,
|
||||
StructMember<"const char*", "SourceFile", "Source code file">,
|
||||
StructMember<"uint32_t", "LineNumber", "Source code line number">,
|
||||
StructMember<"uint32_t", "ColumnNumber", "Source code column number">
|
||||
];
|
||||
}
|
||||
|
||||
def : Function {
|
||||
let name = "olInit";
|
||||
let desc = "Perform initialization of the Offload library and plugins";
|
||||
let details = [
|
||||
"This must be the first API call made by a user of the Offload library",
|
||||
"Each call will increment an internal reference count that is decremented by `olShutDown`"
|
||||
];
|
||||
let params = [];
|
||||
let returns = [];
|
||||
}
|
||||
|
||||
def : Function {
|
||||
let name = "olShutDown";
|
||||
let desc = "Release the resources in use by Offload";
|
||||
let details = [
|
||||
"This decrements an internal reference count. When this reaches 0, all resources will be released",
|
||||
"Subsequent API calls made after this are not valid"
|
||||
];
|
||||
let params = [];
|
||||
let returns = [];
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
//===-- 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 = "ol_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 = "ol_device_info_t";
|
||||
let desc = "Supported device info";
|
||||
let is_typed = 1;
|
||||
let etors =[
|
||||
TaggedEtor<"TYPE", "ol_device_type_t", "type of the device">,
|
||||
TaggedEtor<"PLATFORM", "ol_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 = "olGetDeviceCount";
|
||||
let desc = "Retrieves the number of available devices within a platform";
|
||||
let params = [
|
||||
Param<"ol_platform_handle_t", "Platform", "handle of the platform instance", PARAM_IN>,
|
||||
Param<"uint32_t*", "NumDevices", "pointer to the number of devices.", PARAM_OUT>
|
||||
];
|
||||
let returns = [];
|
||||
}
|
||||
|
||||
def : Function {
|
||||
let name = "olGetDevice";
|
||||
let desc = "Retrieves devices within a platform";
|
||||
let details = [
|
||||
"Multiple calls to this function will return identical device handles, in the same order.",
|
||||
];
|
||||
let params = [
|
||||
Param<"ol_platform_handle_t", "Platform", "handle of the platform instance", PARAM_IN>,
|
||||
Param<"uint32_t", "NumEntries", "the number of devices to be added to phDevices, which must be greater than zero", PARAM_IN>,
|
||||
RangedParam<"ol_device_handle_t*", "Devices", "Array of device handles. "
|
||||
"If NumEntries is less than the number of devices available, then this function shall only retrieve that number of devices.", PARAM_OUT,
|
||||
Range<"0", "NumEntries">>
|
||||
];
|
||||
let returns = [
|
||||
Return<"OL_ERRC_INVALID_SIZE", [
|
||||
"`NumEntries == 0`"
|
||||
]>
|
||||
];
|
||||
}
|
||||
|
||||
def : Function {
|
||||
let name = "olGetDeviceInfo";
|
||||
let desc = "Queries the given property of the device";
|
||||
let details = [];
|
||||
let params = [
|
||||
Param<"ol_device_handle_t", "Device", "handle of the device instance", PARAM_IN>,
|
||||
Param<"ol_device_info_t", "PropName", "type of the info to retrieve", PARAM_IN>,
|
||||
Param<"size_t", "PropSize", "the number of bytes pointed to by PropValue.", PARAM_IN>,
|
||||
TypeTaggedParam<"void*", "PropValue", "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 OL_ERRC_INVALID_SIZE error is returned and "
|
||||
"PropValue is not used.", PARAM_OUT, TypeInfo<"PropName" , "PropSize">>
|
||||
];
|
||||
let returns = [
|
||||
Return<"OL_ERRC_UNSUPPORTED_ENUMERATION", [
|
||||
"If `PropName` is not supported by the device."
|
||||
]>,
|
||||
Return<"OL_ERRC_INVALID_SIZE", [
|
||||
"`PropSize == 0`",
|
||||
"If `PropSize` is less than the real number of bytes needed to return the info."
|
||||
]>,
|
||||
Return<"OL_ERRC_INVALID_DEVICE">
|
||||
];
|
||||
}
|
||||
|
||||
def : Function {
|
||||
let name = "olGetDeviceInfoSize";
|
||||
let desc = "Returns the storage size of the given device query";
|
||||
let details = [];
|
||||
let params = [
|
||||
Param<"ol_device_handle_t", "Device", "handle of the device instance", PARAM_IN>,
|
||||
Param<"ol_device_info_t", "PropName", "type of the info to retrieve", PARAM_IN>,
|
||||
Param<"size_t*", "PropSizeRet", "pointer to the number of bytes required to store the query", PARAM_OUT>
|
||||
];
|
||||
let returns = [
|
||||
Return<"OL_ERRC_UNSUPPORTED_ENUMERATION", [
|
||||
"If `PropName` is not supported by the device."
|
||||
]>,
|
||||
Return<"OL_ERRC_INVALID_DEVICE">
|
||||
];
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
//===-- 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"
|
@ -1,112 +0,0 @@
|
||||
//===-- 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 = "olGetPlatform";
|
||||
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 Platforms. NumEntries must be "
|
||||
"greater than zero.",
|
||||
PARAM_IN>,
|
||||
RangedParam<"ol_platform_handle_t*", "Platforms",
|
||||
"Array of handle of platforms. If NumEntries is less than the number of "
|
||||
"platforms available, then olGetPlatform shall only retrieve that "
|
||||
"number of platforms.",
|
||||
PARAM_OUT, Range<"0", "NumEntries">>
|
||||
];
|
||||
let returns = [
|
||||
Return<"OL_ERRC_INVALID_SIZE", [
|
||||
"`NumEntries == 0`"
|
||||
]>
|
||||
];
|
||||
}
|
||||
|
||||
def : Function {
|
||||
let name = "olGetPlatformCount";
|
||||
let desc = "Retrieves the number of available platforms";
|
||||
let params = [
|
||||
Param<"uint32_t*",
|
||||
"NumPlatforms", "returns the total number of platforms available.",
|
||||
PARAM_OUT>
|
||||
];
|
||||
let returns = [];
|
||||
}
|
||||
|
||||
def : Enum {
|
||||
let name = "ol_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", "ol_platform_backend_t", "The native backend of the platform.">
|
||||
];
|
||||
}
|
||||
|
||||
def : Enum {
|
||||
let name = "ol_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 = "olGetPlatformInfo";
|
||||
let desc = "Queries the given property of the platform";
|
||||
let details = [
|
||||
"`olGetPlatformInfoSize` can be used to query the storage size "
|
||||
"required for the given query."
|
||||
];
|
||||
let params = [
|
||||
Param<"ol_platform_handle_t", "Platform", "handle of the platform", PARAM_IN>,
|
||||
Param<"ol_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*", "PropValue", "array of bytes holding the info. "
|
||||
"If Size is not equal to or greater to the real number of bytes needed to return the info "
|
||||
"then the OL_ERRC_INVALID_SIZE error is returned and pPlatformInfo is not used.", PARAM_OUT,
|
||||
TypeInfo<"PropName" , "PropSize">>
|
||||
];
|
||||
let returns = [
|
||||
Return<"OL_ERRC_UNSUPPORTED_ENUMERATION", [
|
||||
"If `PropName` is not supported by the platform."
|
||||
]>,
|
||||
Return<"OL_ERRC_INVALID_SIZE", [
|
||||
"`PropSize == 0`",
|
||||
"If `PropSize` is less than the real number of bytes needed to return the info."
|
||||
]>,
|
||||
Return<"OL_ERRC_INVALID_PLATFORM">
|
||||
];
|
||||
}
|
||||
|
||||
def : Function {
|
||||
let name = "olGetPlatformInfoSize";
|
||||
let desc = "Returns the storage size of the given platform query";
|
||||
let details = [];
|
||||
let params = [
|
||||
Param<"ol_platform_handle_t", "Platform", "handle of the platform", PARAM_IN>,
|
||||
Param<"ol_platform_info_t", "PropName", "type of the info to query", PARAM_IN>,
|
||||
Param<"size_t*", "PropSizeRet", "pointer to the number of bytes required to store the query", PARAM_OUT>
|
||||
];
|
||||
let returns = [
|
||||
Return<"OL_ERRC_UNSUPPORTED_ENUMERATION", [
|
||||
"If `PropName` is not supported by the platform."
|
||||
]>,
|
||||
Return<"OL_ERRC_INVALID_PLATFORM">
|
||||
];
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
# 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 addtionally 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`
|
@ -1,32 +0,0 @@
|
||||
add_subdirectory(API)
|
||||
|
||||
add_llvm_library(LLVMOffload SHARED
|
||||
src/OffloadLib.cpp
|
||||
src/OffloadImpl.cpp)
|
||||
|
||||
foreach(plugin IN LISTS LIBOMPTARGET_PLUGINS_TO_BUILD)
|
||||
target_link_libraries(LLVMOffload PRIVATE omptarget.rtl.${plugin})
|
||||
endforeach()
|
||||
|
||||
if(LIBOMP_HAVE_VERSION_SCRIPT_FLAG)
|
||||
target_link_libraries(LLVMOffload PRIVATE "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/exports")
|
||||
endif()
|
||||
|
||||
target_include_directories(LLVMOffload PUBLIC
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/generated
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../plugins-nextgen/common/include)
|
||||
|
||||
target_compile_options(LLVMOffload PRIVATE ${offload_compile_flags})
|
||||
target_link_options(LLVMOffload PRIVATE ${offload_link_flags})
|
||||
|
||||
set_target_properties(LLVMOffload PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
INSTALL_RPATH "$ORIGIN"
|
||||
BUILD_RPATH "$ORIGIN:${CMAKE_CURRENT_BINARY_DIR}/..")
|
||||
install(TARGETS LLVMOffload LIBRARY COMPONENT LLVMOffload DESTINATION "${OFFLOAD_INSTALL_LIBDIR}")
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/OffloadAPI.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include/offload)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/OffloadPrint.hpp DESTINATION ${CMAKE_INSTALL_PREFIX}/include/offload)
|
@ -1,8 +0,0 @@
|
||||
# Offload New API
|
||||
|
||||
This directory contains the implementation of the experimental work-in-progress
|
||||
new API for Offload. It builds on top of the existing plugin implementations but
|
||||
provides a single level of abstraction suitable for runtimes for languages other
|
||||
than OpenMP to be built on top of.
|
||||
|
||||
See the [API definition readme](API/README.md) for implementation details.
|
@ -1,6 +0,0 @@
|
||||
VERS1.0 {
|
||||
global:
|
||||
ol*;
|
||||
local:
|
||||
*;
|
||||
};
|
@ -1,94 +0,0 @@
|
||||
//===- offload_impl.hpp- Implementation helpers for the Offload library ---===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#pragma once
|
||||
|
||||
#include <OffloadAPI.h>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/StringSet.h"
|
||||
|
||||
struct OffloadConfig {
|
||||
bool TracingEnabled = false;
|
||||
};
|
||||
|
||||
OffloadConfig &offloadConfig();
|
||||
|
||||
// Use the StringSet container to efficiently deduplicate repeated error
|
||||
// strings (e.g. if the same error is hit constantly in a long running program)
|
||||
llvm::StringSet<> &errorStrs();
|
||||
|
||||
// Use an unordered_set to avoid duplicates of error structs themselves.
|
||||
// We cannot store the structs directly as returned pointers to them must always
|
||||
// be valid, and a rehash of the set may invalidate them. This requires
|
||||
// custom hash and equal_to function objects.
|
||||
using ErrPtrT = std::unique_ptr<ol_error_struct_t>;
|
||||
struct ErrPtrEqual {
|
||||
bool operator()(const ErrPtrT &lhs, const ErrPtrT &rhs) const {
|
||||
if (!lhs && !rhs) {
|
||||
return true;
|
||||
}
|
||||
if (!lhs || !rhs) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StrsEqual = false;
|
||||
if (lhs->Details == NULL && rhs->Details == NULL) {
|
||||
StrsEqual = true;
|
||||
} else if (lhs->Details != NULL && rhs->Details != NULL) {
|
||||
StrsEqual = (std::strcmp(lhs->Details, rhs->Details) == 0);
|
||||
}
|
||||
return (lhs->Code == rhs->Code) && StrsEqual;
|
||||
}
|
||||
};
|
||||
struct ErrPtrHash {
|
||||
size_t operator()(const ErrPtrT &e) const {
|
||||
if (!e) {
|
||||
// We shouldn't store empty errors (i.e. success), but just in case
|
||||
return 0lu;
|
||||
} else {
|
||||
return std::hash<int>{}(e->Code);
|
||||
}
|
||||
}
|
||||
};
|
||||
using ErrSetT = std::unordered_set<ErrPtrT, ErrPtrHash, ErrPtrEqual>;
|
||||
ErrSetT &errors();
|
||||
|
||||
struct ol_impl_result_t {
|
||||
ol_impl_result_t(std::nullptr_t) : Result(OL_SUCCESS) {}
|
||||
ol_impl_result_t(ol_errc_t Code) {
|
||||
if (Code == OL_ERRC_SUCCESS) {
|
||||
Result = nullptr;
|
||||
} else {
|
||||
auto Err = std::unique_ptr<ol_error_struct_t>(
|
||||
new ol_error_struct_t{Code, nullptr});
|
||||
Result = errors().emplace(std::move(Err)).first->get();
|
||||
}
|
||||
}
|
||||
|
||||
ol_impl_result_t(ol_errc_t Code, llvm::StringRef Details) {
|
||||
assert(Code != OL_ERRC_SUCCESS);
|
||||
Result = nullptr;
|
||||
auto DetailsStr = errorStrs().insert(Details).first->getKeyData();
|
||||
auto Err = std::unique_ptr<ol_error_struct_t>(
|
||||
new ol_error_struct_t{Code, DetailsStr});
|
||||
Result = errors().emplace(std::move(Err)).first->get();
|
||||
}
|
||||
|
||||
operator ol_result_t() { return Result; }
|
||||
|
||||
private:
|
||||
ol_result_t Result;
|
||||
};
|
@ -1,610 +0,0 @@
|
||||
//===- Auto-generated file, part of the LLVM/Offload project --------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Auto-generated file, do not manually edit.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef OL_VERSION_MAJOR
|
||||
/// @brief Major version of the Offload API
|
||||
#define OL_VERSION_MAJOR 0
|
||||
#endif // OL_VERSION_MAJOR
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef OL_VERSION_MINOR
|
||||
/// @brief Minor version of the Offload API
|
||||
#define OL_VERSION_MINOR 0
|
||||
#endif // OL_VERSION_MINOR
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef OL_VERSION_PATCH
|
||||
/// @brief Patch version of the Offload API
|
||||
#define OL_VERSION_PATCH 1
|
||||
#endif // OL_VERSION_PATCH
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef OL_APICALL
|
||||
#if defined(_WIN32)
|
||||
/// @brief Calling convention for all API functions
|
||||
#define OL_APICALL __cdecl
|
||||
#else
|
||||
#define OL_APICALL
|
||||
#endif // defined(_WIN32)
|
||||
#endif // OL_APICALL
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef OL_APIEXPORT
|
||||
#if defined(_WIN32)
|
||||
/// @brief Microsoft-specific dllexport storage-class attribute
|
||||
#define OL_APIEXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define OL_APIEXPORT
|
||||
#endif // defined(_WIN32)
|
||||
#endif // OL_APIEXPORT
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef OL_DLLEXPORT
|
||||
#if defined(_WIN32)
|
||||
/// @brief Microsoft-specific dllexport storage-class attribute
|
||||
#define OL_DLLEXPORT __declspec(dllexport)
|
||||
#endif // defined(_WIN32)
|
||||
#endif // OL_DLLEXPORT
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef OL_DLLEXPORT
|
||||
#if __GNUC__ >= 4
|
||||
/// @brief GCC-specific dllexport storage-class attribute
|
||||
#define OL_DLLEXPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
#define OL_DLLEXPORT
|
||||
#endif // __GNUC__ >= 4
|
||||
#endif // OL_DLLEXPORT
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Handle of a platform instance
|
||||
typedef struct ol_platform_handle_t_ *ol_platform_handle_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Handle of platform's device object
|
||||
typedef struct ol_device_handle_t_ *ol_device_handle_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Handle of context object
|
||||
typedef struct ol_context_handle_t_ *ol_context_handle_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Defines Return/Error codes
|
||||
typedef enum ol_errc_t {
|
||||
/// Success
|
||||
OL_ERRC_SUCCESS = 0,
|
||||
/// Invalid Value
|
||||
OL_ERRC_INVALID_VALUE = 1,
|
||||
/// Invalid platform
|
||||
OL_ERRC_INVALID_PLATFORM = 2,
|
||||
/// Device not found
|
||||
OL_ERRC_DEVICE_NOT_FOUND = 3,
|
||||
/// Invalid device
|
||||
OL_ERRC_INVALID_DEVICE = 4,
|
||||
/// Device hung, reset, was removed, or driver update occurred
|
||||
OL_ERRC_DEVICE_LOST = 5,
|
||||
/// plugin is not initialized or specific entry-point is not implemented
|
||||
OL_ERRC_UNINITIALIZED = 6,
|
||||
/// Out of resources
|
||||
OL_ERRC_OUT_OF_RESOURCES = 7,
|
||||
/// generic error code for unsupported versions
|
||||
OL_ERRC_UNSUPPORTED_VERSION = 8,
|
||||
/// generic error code for unsupported features
|
||||
OL_ERRC_UNSUPPORTED_FEATURE = 9,
|
||||
/// generic error code for invalid arguments
|
||||
OL_ERRC_INVALID_ARGUMENT = 10,
|
||||
/// handle argument is not valid
|
||||
OL_ERRC_INVALID_NULL_HANDLE = 11,
|
||||
/// pointer argument may not be nullptr
|
||||
OL_ERRC_INVALID_NULL_POINTER = 12,
|
||||
/// invalid size or dimensions (e.g., must not be zero, or is out of bounds)
|
||||
OL_ERRC_INVALID_SIZE = 13,
|
||||
/// enumerator argument is not valid
|
||||
OL_ERRC_INVALID_ENUMERATION = 14,
|
||||
/// enumerator argument is not supported by the device
|
||||
OL_ERRC_UNSUPPORTED_ENUMERATION = 15,
|
||||
/// Unknown or internal error
|
||||
OL_ERRC_UNKNOWN = 16,
|
||||
/// @cond
|
||||
OL_ERRC_FORCE_UINT32 = 0x7fffffff
|
||||
/// @endcond
|
||||
|
||||
} ol_errc_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Details of the error condition returned by an API call
|
||||
typedef struct ol_error_struct_t {
|
||||
ol_errc_t Code; /// The error code
|
||||
const char *Details; /// String containing error details
|
||||
} ol_error_struct_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Result type returned by all entry points.
|
||||
typedef const ol_error_struct_t *ol_result_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef OL_SUCCESS
|
||||
/// @brief Success condition
|
||||
#define OL_SUCCESS NULL
|
||||
#endif // OL_SUCCESS
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Code location information that can optionally be associated with an
|
||||
/// API call
|
||||
typedef struct ol_code_location_t {
|
||||
const char *FunctionName; /// Function name
|
||||
const char *SourceFile; /// Source code file
|
||||
uint32_t LineNumber; /// Source code line number
|
||||
uint32_t ColumnNumber; /// Source code column number
|
||||
} ol_code_location_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Perform initialization of the Offload library and plugins
|
||||
///
|
||||
/// @details
|
||||
/// - This must be the first API call made by a user of the Offload library
|
||||
/// - Each call will increment an internal reference count that is
|
||||
/// decremented by `olShutDown`
|
||||
///
|
||||
/// @returns
|
||||
/// - ::OL_RESULT_SUCCESS
|
||||
/// - ::OL_ERRC_UNINITIALIZED
|
||||
/// - ::OL_ERRC_DEVICE_LOST
|
||||
/// - ::OL_ERRC_INVALID_NULL_HANDLE
|
||||
/// - ::OL_ERRC_INVALID_NULL_POINTER
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olInit();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Release the resources in use by Offload
|
||||
///
|
||||
/// @details
|
||||
/// - This decrements an internal reference count. When this reaches 0, all
|
||||
/// resources will be released
|
||||
/// - Subsequent API calls made after this are not valid
|
||||
///
|
||||
/// @returns
|
||||
/// - ::OL_RESULT_SUCCESS
|
||||
/// - ::OL_ERRC_UNINITIALIZED
|
||||
/// - ::OL_ERRC_DEVICE_LOST
|
||||
/// - ::OL_ERRC_INVALID_NULL_HANDLE
|
||||
/// - ::OL_ERRC_INVALID_NULL_POINTER
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olShutDown();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Retrieves all available platforms
|
||||
///
|
||||
/// @details
|
||||
/// - Multiple calls to this function will return identical platforms
|
||||
/// handles, in the same order.
|
||||
///
|
||||
/// @returns
|
||||
/// - ::OL_RESULT_SUCCESS
|
||||
/// - ::OL_ERRC_UNINITIALIZED
|
||||
/// - ::OL_ERRC_DEVICE_LOST
|
||||
/// - ::OL_ERRC_INVALID_SIZE
|
||||
/// + `NumEntries == 0`
|
||||
/// - ::OL_ERRC_INVALID_NULL_HANDLE
|
||||
/// - ::OL_ERRC_INVALID_NULL_POINTER
|
||||
/// + `NULL == Platforms`
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetPlatform(
|
||||
// [in] The number of platforms to be added to Platforms. NumEntries must be
|
||||
// greater than zero.
|
||||
uint32_t NumEntries,
|
||||
// [out] Array of handle of platforms. If NumEntries is less than the number
|
||||
// of platforms available, then olGetPlatform shall only retrieve that
|
||||
// number of platforms.
|
||||
ol_platform_handle_t *Platforms);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Retrieves the number of available platforms
|
||||
///
|
||||
/// @details
|
||||
///
|
||||
/// @returns
|
||||
/// - ::OL_RESULT_SUCCESS
|
||||
/// - ::OL_ERRC_UNINITIALIZED
|
||||
/// - ::OL_ERRC_DEVICE_LOST
|
||||
/// - ::OL_ERRC_INVALID_NULL_HANDLE
|
||||
/// - ::OL_ERRC_INVALID_NULL_POINTER
|
||||
/// + `NULL == NumPlatforms`
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetPlatformCount(
|
||||
// [out] returns the total number of platforms available.
|
||||
uint32_t *NumPlatforms);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Supported platform info
|
||||
typedef enum ol_platform_info_t {
|
||||
/// [char[]] The string denoting name of the platform. The size of the info
|
||||
/// needs to be dynamically queried.
|
||||
OL_PLATFORM_INFO_NAME = 0,
|
||||
/// [char[]] The string denoting name of the vendor of the platform. The size
|
||||
/// of the info needs to be dynamically queried.
|
||||
OL_PLATFORM_INFO_VENDOR_NAME = 1,
|
||||
/// [char[]] The string denoting the version of the platform. The size of the
|
||||
/// info needs to be dynamically queried.
|
||||
OL_PLATFORM_INFO_VERSION = 2,
|
||||
/// [ol_platform_backend_t] The native backend of the platform.
|
||||
OL_PLATFORM_INFO_BACKEND = 3,
|
||||
/// @cond
|
||||
OL_PLATFORM_INFO_FORCE_UINT32 = 0x7fffffff
|
||||
/// @endcond
|
||||
|
||||
} ol_platform_info_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Identifies the native backend of the platform
|
||||
typedef enum ol_platform_backend_t {
|
||||
/// The backend is not recognized
|
||||
OL_PLATFORM_BACKEND_UNKNOWN = 0,
|
||||
/// The backend is CUDA
|
||||
OL_PLATFORM_BACKEND_CUDA = 1,
|
||||
/// The backend is AMDGPU
|
||||
OL_PLATFORM_BACKEND_AMDGPU = 2,
|
||||
/// @cond
|
||||
OL_PLATFORM_BACKEND_FORCE_UINT32 = 0x7fffffff
|
||||
/// @endcond
|
||||
|
||||
} ol_platform_backend_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Queries the given property of the platform
|
||||
///
|
||||
/// @details
|
||||
/// - `olGetPlatformInfoSize` can be used to query the storage size required
|
||||
/// for the given query.
|
||||
///
|
||||
/// @returns
|
||||
/// - ::OL_RESULT_SUCCESS
|
||||
/// - ::OL_ERRC_UNINITIALIZED
|
||||
/// - ::OL_ERRC_DEVICE_LOST
|
||||
/// - ::OL_ERRC_UNSUPPORTED_ENUMERATION
|
||||
/// + If `PropName` is not supported by the platform.
|
||||
/// - ::OL_ERRC_INVALID_SIZE
|
||||
/// + `PropSize == 0`
|
||||
/// + If `PropSize` is less than the real number of bytes needed to
|
||||
/// return the info.
|
||||
/// - ::OL_ERRC_INVALID_PLATFORM
|
||||
/// - ::OL_ERRC_INVALID_NULL_HANDLE
|
||||
/// + `NULL == Platform`
|
||||
/// - ::OL_ERRC_INVALID_NULL_POINTER
|
||||
/// + `NULL == PropValue`
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetPlatformInfo(
|
||||
// [in] handle of the platform
|
||||
ol_platform_handle_t Platform,
|
||||
// [in] type of the info to retrieve
|
||||
ol_platform_info_t PropName,
|
||||
// [in] the number of bytes pointed to by pPlatformInfo.
|
||||
size_t PropSize,
|
||||
// [out] array of bytes holding the info. If Size is not equal to or greater
|
||||
// to the real number of bytes needed to return the info then the
|
||||
// OL_ERRC_INVALID_SIZE error is returned and pPlatformInfo is not used.
|
||||
void *PropValue);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Returns the storage size of the given platform query
|
||||
///
|
||||
/// @details
|
||||
///
|
||||
/// @returns
|
||||
/// - ::OL_RESULT_SUCCESS
|
||||
/// - ::OL_ERRC_UNINITIALIZED
|
||||
/// - ::OL_ERRC_DEVICE_LOST
|
||||
/// - ::OL_ERRC_UNSUPPORTED_ENUMERATION
|
||||
/// + If `PropName` is not supported by the platform.
|
||||
/// - ::OL_ERRC_INVALID_PLATFORM
|
||||
/// - ::OL_ERRC_INVALID_NULL_HANDLE
|
||||
/// + `NULL == Platform`
|
||||
/// - ::OL_ERRC_INVALID_NULL_POINTER
|
||||
/// + `NULL == PropSizeRet`
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetPlatformInfoSize(
|
||||
// [in] handle of the platform
|
||||
ol_platform_handle_t Platform,
|
||||
// [in] type of the info to query
|
||||
ol_platform_info_t PropName,
|
||||
// [out] pointer to the number of bytes required to store the query
|
||||
size_t *PropSizeRet);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Supported device types
|
||||
typedef enum ol_device_type_t {
|
||||
/// The default device type as preferred by the runtime
|
||||
OL_DEVICE_TYPE_DEFAULT = 0,
|
||||
/// Devices of all types
|
||||
OL_DEVICE_TYPE_ALL = 1,
|
||||
/// GPU device type
|
||||
OL_DEVICE_TYPE_GPU = 2,
|
||||
/// CPU device type
|
||||
OL_DEVICE_TYPE_CPU = 3,
|
||||
/// @cond
|
||||
OL_DEVICE_TYPE_FORCE_UINT32 = 0x7fffffff
|
||||
/// @endcond
|
||||
|
||||
} ol_device_type_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Supported device info
|
||||
typedef enum ol_device_info_t {
|
||||
/// [ol_device_type_t] type of the device
|
||||
OL_DEVICE_INFO_TYPE = 0,
|
||||
/// [ol_platform_handle_t] the platform associated with the device
|
||||
OL_DEVICE_INFO_PLATFORM = 1,
|
||||
/// [char[]] Device name
|
||||
OL_DEVICE_INFO_NAME = 2,
|
||||
/// [char[]] Device vendor
|
||||
OL_DEVICE_INFO_VENDOR = 3,
|
||||
/// [char[]] Driver version
|
||||
OL_DEVICE_INFO_DRIVER_VERSION = 4,
|
||||
/// @cond
|
||||
OL_DEVICE_INFO_FORCE_UINT32 = 0x7fffffff
|
||||
/// @endcond
|
||||
|
||||
} ol_device_info_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Retrieves the number of available devices within a platform
|
||||
///
|
||||
/// @details
|
||||
///
|
||||
/// @returns
|
||||
/// - ::OL_RESULT_SUCCESS
|
||||
/// - ::OL_ERRC_UNINITIALIZED
|
||||
/// - ::OL_ERRC_DEVICE_LOST
|
||||
/// - ::OL_ERRC_INVALID_NULL_HANDLE
|
||||
/// + `NULL == Platform`
|
||||
/// - ::OL_ERRC_INVALID_NULL_POINTER
|
||||
/// + `NULL == NumDevices`
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetDeviceCount(
|
||||
// [in] handle of the platform instance
|
||||
ol_platform_handle_t Platform,
|
||||
// [out] pointer to the number of devices.
|
||||
uint32_t *NumDevices);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Retrieves devices within a platform
|
||||
///
|
||||
/// @details
|
||||
/// - Multiple calls to this function will return identical device handles,
|
||||
/// in the same order.
|
||||
///
|
||||
/// @returns
|
||||
/// - ::OL_RESULT_SUCCESS
|
||||
/// - ::OL_ERRC_UNINITIALIZED
|
||||
/// - ::OL_ERRC_DEVICE_LOST
|
||||
/// - ::OL_ERRC_INVALID_SIZE
|
||||
/// + `NumEntries == 0`
|
||||
/// - ::OL_ERRC_INVALID_NULL_HANDLE
|
||||
/// + `NULL == Platform`
|
||||
/// - ::OL_ERRC_INVALID_NULL_POINTER
|
||||
/// + `NULL == Devices`
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetDevice(
|
||||
// [in] handle of the platform instance
|
||||
ol_platform_handle_t Platform,
|
||||
// [in] the number of devices to be added to phDevices, which must be
|
||||
// greater than zero
|
||||
uint32_t NumEntries,
|
||||
// [out] Array of device handles. If NumEntries is less than the number of
|
||||
// devices available, then this function shall only retrieve that number of
|
||||
// devices.
|
||||
ol_device_handle_t *Devices);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Queries the given property of the device
|
||||
///
|
||||
/// @details
|
||||
///
|
||||
/// @returns
|
||||
/// - ::OL_RESULT_SUCCESS
|
||||
/// - ::OL_ERRC_UNINITIALIZED
|
||||
/// - ::OL_ERRC_DEVICE_LOST
|
||||
/// - ::OL_ERRC_UNSUPPORTED_ENUMERATION
|
||||
/// + If `PropName` is not supported by the device.
|
||||
/// - ::OL_ERRC_INVALID_SIZE
|
||||
/// + `PropSize == 0`
|
||||
/// + If `PropSize` is less than the real number of bytes needed to
|
||||
/// return the info.
|
||||
/// - ::OL_ERRC_INVALID_DEVICE
|
||||
/// - ::OL_ERRC_INVALID_NULL_HANDLE
|
||||
/// + `NULL == Device`
|
||||
/// - ::OL_ERRC_INVALID_NULL_POINTER
|
||||
/// + `NULL == PropValue`
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetDeviceInfo(
|
||||
// [in] handle of the device instance
|
||||
ol_device_handle_t Device,
|
||||
// [in] type of the info to retrieve
|
||||
ol_device_info_t PropName,
|
||||
// [in] the number of bytes pointed to by PropValue.
|
||||
size_t PropSize,
|
||||
// [out] 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
|
||||
// OL_ERRC_INVALID_SIZE error is returned and PropValue is not used.
|
||||
void *PropValue);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Returns the storage size of the given device query
|
||||
///
|
||||
/// @details
|
||||
///
|
||||
/// @returns
|
||||
/// - ::OL_RESULT_SUCCESS
|
||||
/// - ::OL_ERRC_UNINITIALIZED
|
||||
/// - ::OL_ERRC_DEVICE_LOST
|
||||
/// - ::OL_ERRC_UNSUPPORTED_ENUMERATION
|
||||
/// + If `PropName` is not supported by the device.
|
||||
/// - ::OL_ERRC_INVALID_DEVICE
|
||||
/// - ::OL_ERRC_INVALID_NULL_HANDLE
|
||||
/// + `NULL == Device`
|
||||
/// - ::OL_ERRC_INVALID_NULL_POINTER
|
||||
/// + `NULL == PropSizeRet`
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetDeviceInfoSize(
|
||||
// [in] handle of the device instance
|
||||
ol_device_handle_t Device,
|
||||
// [in] type of the info to retrieve
|
||||
ol_device_info_t PropName,
|
||||
// [out] pointer to the number of bytes required to store the query
|
||||
size_t *PropSizeRet);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Function parameters for olGetPlatform
|
||||
/// @details Each entry is a pointer to the parameter passed to the function;
|
||||
typedef struct ol_get_platform_params_t {
|
||||
uint32_t *pNumEntries;
|
||||
ol_platform_handle_t **pPlatforms;
|
||||
} ol_get_platform_params_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Function parameters for olGetPlatformCount
|
||||
/// @details Each entry is a pointer to the parameter passed to the function;
|
||||
typedef struct ol_get_platform_count_params_t {
|
||||
uint32_t **pNumPlatforms;
|
||||
} ol_get_platform_count_params_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Function parameters for olGetPlatformInfo
|
||||
/// @details Each entry is a pointer to the parameter passed to the function;
|
||||
typedef struct ol_get_platform_info_params_t {
|
||||
ol_platform_handle_t *pPlatform;
|
||||
ol_platform_info_t *pPropName;
|
||||
size_t *pPropSize;
|
||||
void **pPropValue;
|
||||
} ol_get_platform_info_params_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Function parameters for olGetPlatformInfoSize
|
||||
/// @details Each entry is a pointer to the parameter passed to the function;
|
||||
typedef struct ol_get_platform_info_size_params_t {
|
||||
ol_platform_handle_t *pPlatform;
|
||||
ol_platform_info_t *pPropName;
|
||||
size_t **pPropSizeRet;
|
||||
} ol_get_platform_info_size_params_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Function parameters for olGetDeviceCount
|
||||
/// @details Each entry is a pointer to the parameter passed to the function;
|
||||
typedef struct ol_get_device_count_params_t {
|
||||
ol_platform_handle_t *pPlatform;
|
||||
uint32_t **pNumDevices;
|
||||
} ol_get_device_count_params_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Function parameters for olGetDevice
|
||||
/// @details Each entry is a pointer to the parameter passed to the function;
|
||||
typedef struct ol_get_device_params_t {
|
||||
ol_platform_handle_t *pPlatform;
|
||||
uint32_t *pNumEntries;
|
||||
ol_device_handle_t **pDevices;
|
||||
} ol_get_device_params_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Function parameters for olGetDeviceInfo
|
||||
/// @details Each entry is a pointer to the parameter passed to the function;
|
||||
typedef struct ol_get_device_info_params_t {
|
||||
ol_device_handle_t *pDevice;
|
||||
ol_device_info_t *pPropName;
|
||||
size_t *pPropSize;
|
||||
void **pPropValue;
|
||||
} ol_get_device_info_params_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Function parameters for olGetDeviceInfoSize
|
||||
/// @details Each entry is a pointer to the parameter passed to the function;
|
||||
typedef struct ol_get_device_info_size_params_t {
|
||||
ol_device_handle_t *pDevice;
|
||||
ol_device_info_t *pPropName;
|
||||
size_t **pPropSizeRet;
|
||||
} ol_get_device_info_size_params_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Variant of olInit that also sets source code location information
|
||||
/// @details See also ::olInit
|
||||
OL_APIEXPORT ol_result_t OL_APICALL
|
||||
olInitWithCodeLoc(ol_code_location_t *CodeLocation);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Variant of olShutDown that also sets source code location information
|
||||
/// @details See also ::olShutDown
|
||||
OL_APIEXPORT ol_result_t OL_APICALL
|
||||
olShutDownWithCodeLoc(ol_code_location_t *CodeLocation);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Variant of olGetPlatform that also sets source code location
|
||||
/// information
|
||||
/// @details See also ::olGetPlatform
|
||||
OL_APIEXPORT ol_result_t OL_APICALL
|
||||
olGetPlatformWithCodeLoc(uint32_t NumEntries, ol_platform_handle_t *Platforms,
|
||||
ol_code_location_t *CodeLocation);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Variant of olGetPlatformCount that also sets source code location
|
||||
/// information
|
||||
/// @details See also ::olGetPlatformCount
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetPlatformCountWithCodeLoc(
|
||||
uint32_t *NumPlatforms, ol_code_location_t *CodeLocation);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Variant of olGetPlatformInfo that also sets source code location
|
||||
/// information
|
||||
/// @details See also ::olGetPlatformInfo
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetPlatformInfoWithCodeLoc(
|
||||
ol_platform_handle_t Platform, ol_platform_info_t PropName, size_t PropSize,
|
||||
void *PropValue, ol_code_location_t *CodeLocation);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Variant of olGetPlatformInfoSize that also sets source code location
|
||||
/// information
|
||||
/// @details See also ::olGetPlatformInfoSize
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetPlatformInfoSizeWithCodeLoc(
|
||||
ol_platform_handle_t Platform, ol_platform_info_t PropName,
|
||||
size_t *PropSizeRet, ol_code_location_t *CodeLocation);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Variant of olGetDeviceCount that also sets source code location
|
||||
/// information
|
||||
/// @details See also ::olGetDeviceCount
|
||||
OL_APIEXPORT ol_result_t OL_APICALL
|
||||
olGetDeviceCountWithCodeLoc(ol_platform_handle_t Platform, uint32_t *NumDevices,
|
||||
ol_code_location_t *CodeLocation);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Variant of olGetDevice that also sets source code location
|
||||
/// information
|
||||
/// @details See also ::olGetDevice
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetDeviceWithCodeLoc(
|
||||
ol_platform_handle_t Platform, uint32_t NumEntries,
|
||||
ol_device_handle_t *Devices, ol_code_location_t *CodeLocation);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Variant of olGetDeviceInfo that also sets source code location
|
||||
/// information
|
||||
/// @details See also ::olGetDeviceInfo
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetDeviceInfoWithCodeLoc(
|
||||
ol_device_handle_t Device, ol_device_info_t PropName, size_t PropSize,
|
||||
void *PropValue, ol_code_location_t *CodeLocation);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Variant of olGetDeviceInfoSize that also sets source code location
|
||||
/// information
|
||||
/// @details See also ::olGetDeviceInfoSize
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetDeviceInfoSizeWithCodeLoc(
|
||||
ol_device_handle_t Device, ol_device_info_t PropName, size_t *PropSizeRet,
|
||||
ol_code_location_t *CodeLocation);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern "C"
|
||||
#endif
|
@ -1,441 +0,0 @@
|
||||
//===- Auto-generated file, part of the LLVM/Offload project --------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
ol_impl_result_t olInit_val() {
|
||||
if (true /*enableParameterValidation*/) {
|
||||
}
|
||||
|
||||
return olInit_impl();
|
||||
}
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olInit() {
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
std::cout << "---> olInit";
|
||||
}
|
||||
|
||||
ol_result_t Result = olInit_val();
|
||||
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
std::cout << "()";
|
||||
std::cout << "-> " << Result << "\n";
|
||||
if (Result && Result->Details) {
|
||||
std::cout << " *Error Details* " << Result->Details << " \n";
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
ol_result_t olInitWithCodeLoc(ol_code_location_t *CodeLocation) {
|
||||
currentCodeLocation() = CodeLocation;
|
||||
ol_result_t Result = olInit();
|
||||
|
||||
currentCodeLocation() = nullptr;
|
||||
return Result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
ol_impl_result_t olShutDown_val() {
|
||||
if (true /*enableParameterValidation*/) {
|
||||
}
|
||||
|
||||
return olShutDown_impl();
|
||||
}
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olShutDown() {
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
std::cout << "---> olShutDown";
|
||||
}
|
||||
|
||||
ol_result_t Result = olShutDown_val();
|
||||
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
std::cout << "()";
|
||||
std::cout << "-> " << Result << "\n";
|
||||
if (Result && Result->Details) {
|
||||
std::cout << " *Error Details* " << Result->Details << " \n";
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
ol_result_t olShutDownWithCodeLoc(ol_code_location_t *CodeLocation) {
|
||||
currentCodeLocation() = CodeLocation;
|
||||
ol_result_t Result = olShutDown();
|
||||
|
||||
currentCodeLocation() = nullptr;
|
||||
return Result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
ol_impl_result_t olGetPlatform_val(uint32_t NumEntries,
|
||||
ol_platform_handle_t *Platforms) {
|
||||
if (true /*enableParameterValidation*/) {
|
||||
if (NumEntries == 0) {
|
||||
return OL_ERRC_INVALID_SIZE;
|
||||
}
|
||||
|
||||
if (NULL == Platforms) {
|
||||
return OL_ERRC_INVALID_NULL_POINTER;
|
||||
}
|
||||
}
|
||||
|
||||
return olGetPlatform_impl(NumEntries, Platforms);
|
||||
}
|
||||
OL_APIEXPORT ol_result_t OL_APICALL
|
||||
olGetPlatform(uint32_t NumEntries, ol_platform_handle_t *Platforms) {
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
std::cout << "---> olGetPlatform";
|
||||
}
|
||||
|
||||
ol_result_t Result = olGetPlatform_val(NumEntries, Platforms);
|
||||
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
ol_get_platform_params_t Params = {&NumEntries, &Platforms};
|
||||
std::cout << "(" << &Params << ")";
|
||||
std::cout << "-> " << Result << "\n";
|
||||
if (Result && Result->Details) {
|
||||
std::cout << " *Error Details* " << Result->Details << " \n";
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
ol_result_t olGetPlatformWithCodeLoc(uint32_t NumEntries,
|
||||
ol_platform_handle_t *Platforms,
|
||||
ol_code_location_t *CodeLocation) {
|
||||
currentCodeLocation() = CodeLocation;
|
||||
ol_result_t Result = olGetPlatform(NumEntries, Platforms);
|
||||
|
||||
currentCodeLocation() = nullptr;
|
||||
return Result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
ol_impl_result_t olGetPlatformCount_val(uint32_t *NumPlatforms) {
|
||||
if (true /*enableParameterValidation*/) {
|
||||
if (NULL == NumPlatforms) {
|
||||
return OL_ERRC_INVALID_NULL_POINTER;
|
||||
}
|
||||
}
|
||||
|
||||
return olGetPlatformCount_impl(NumPlatforms);
|
||||
}
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetPlatformCount(uint32_t *NumPlatforms) {
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
std::cout << "---> olGetPlatformCount";
|
||||
}
|
||||
|
||||
ol_result_t Result = olGetPlatformCount_val(NumPlatforms);
|
||||
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
ol_get_platform_count_params_t Params = {&NumPlatforms};
|
||||
std::cout << "(" << &Params << ")";
|
||||
std::cout << "-> " << Result << "\n";
|
||||
if (Result && Result->Details) {
|
||||
std::cout << " *Error Details* " << Result->Details << " \n";
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
ol_result_t olGetPlatformCountWithCodeLoc(uint32_t *NumPlatforms,
|
||||
ol_code_location_t *CodeLocation) {
|
||||
currentCodeLocation() = CodeLocation;
|
||||
ol_result_t Result = olGetPlatformCount(NumPlatforms);
|
||||
|
||||
currentCodeLocation() = nullptr;
|
||||
return Result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
ol_impl_result_t olGetPlatformInfo_val(ol_platform_handle_t Platform,
|
||||
ol_platform_info_t PropName,
|
||||
size_t PropSize, void *PropValue) {
|
||||
if (true /*enableParameterValidation*/) {
|
||||
if (PropSize == 0) {
|
||||
return OL_ERRC_INVALID_SIZE;
|
||||
}
|
||||
|
||||
if (NULL == Platform) {
|
||||
return OL_ERRC_INVALID_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (NULL == PropValue) {
|
||||
return OL_ERRC_INVALID_NULL_POINTER;
|
||||
}
|
||||
}
|
||||
|
||||
return olGetPlatformInfo_impl(Platform, PropName, PropSize, PropValue);
|
||||
}
|
||||
OL_APIEXPORT ol_result_t OL_APICALL
|
||||
olGetPlatformInfo(ol_platform_handle_t Platform, ol_platform_info_t PropName,
|
||||
size_t PropSize, void *PropValue) {
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
std::cout << "---> olGetPlatformInfo";
|
||||
}
|
||||
|
||||
ol_result_t Result =
|
||||
olGetPlatformInfo_val(Platform, PropName, PropSize, PropValue);
|
||||
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
ol_get_platform_info_params_t Params = {&Platform, &PropName, &PropSize,
|
||||
&PropValue};
|
||||
std::cout << "(" << &Params << ")";
|
||||
std::cout << "-> " << Result << "\n";
|
||||
if (Result && Result->Details) {
|
||||
std::cout << " *Error Details* " << Result->Details << " \n";
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
ol_result_t olGetPlatformInfoWithCodeLoc(ol_platform_handle_t Platform,
|
||||
ol_platform_info_t PropName,
|
||||
size_t PropSize, void *PropValue,
|
||||
ol_code_location_t *CodeLocation) {
|
||||
currentCodeLocation() = CodeLocation;
|
||||
ol_result_t Result =
|
||||
olGetPlatformInfo(Platform, PropName, PropSize, PropValue);
|
||||
|
||||
currentCodeLocation() = nullptr;
|
||||
return Result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
ol_impl_result_t olGetPlatformInfoSize_val(ol_platform_handle_t Platform,
|
||||
ol_platform_info_t PropName,
|
||||
size_t *PropSizeRet) {
|
||||
if (true /*enableParameterValidation*/) {
|
||||
if (NULL == Platform) {
|
||||
return OL_ERRC_INVALID_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (NULL == PropSizeRet) {
|
||||
return OL_ERRC_INVALID_NULL_POINTER;
|
||||
}
|
||||
}
|
||||
|
||||
return olGetPlatformInfoSize_impl(Platform, PropName, PropSizeRet);
|
||||
}
|
||||
OL_APIEXPORT ol_result_t OL_APICALL
|
||||
olGetPlatformInfoSize(ol_platform_handle_t Platform,
|
||||
ol_platform_info_t PropName, size_t *PropSizeRet) {
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
std::cout << "---> olGetPlatformInfoSize";
|
||||
}
|
||||
|
||||
ol_result_t Result =
|
||||
olGetPlatformInfoSize_val(Platform, PropName, PropSizeRet);
|
||||
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
ol_get_platform_info_size_params_t Params = {&Platform, &PropName,
|
||||
&PropSizeRet};
|
||||
std::cout << "(" << &Params << ")";
|
||||
std::cout << "-> " << Result << "\n";
|
||||
if (Result && Result->Details) {
|
||||
std::cout << " *Error Details* " << Result->Details << " \n";
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
ol_result_t olGetPlatformInfoSizeWithCodeLoc(ol_platform_handle_t Platform,
|
||||
ol_platform_info_t PropName,
|
||||
size_t *PropSizeRet,
|
||||
ol_code_location_t *CodeLocation) {
|
||||
currentCodeLocation() = CodeLocation;
|
||||
ol_result_t Result = olGetPlatformInfoSize(Platform, PropName, PropSizeRet);
|
||||
|
||||
currentCodeLocation() = nullptr;
|
||||
return Result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
ol_impl_result_t olGetDeviceCount_val(ol_platform_handle_t Platform,
|
||||
uint32_t *NumDevices) {
|
||||
if (true /*enableParameterValidation*/) {
|
||||
if (NULL == Platform) {
|
||||
return OL_ERRC_INVALID_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (NULL == NumDevices) {
|
||||
return OL_ERRC_INVALID_NULL_POINTER;
|
||||
}
|
||||
}
|
||||
|
||||
return olGetDeviceCount_impl(Platform, NumDevices);
|
||||
}
|
||||
OL_APIEXPORT ol_result_t OL_APICALL
|
||||
olGetDeviceCount(ol_platform_handle_t Platform, uint32_t *NumDevices) {
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
std::cout << "---> olGetDeviceCount";
|
||||
}
|
||||
|
||||
ol_result_t Result = olGetDeviceCount_val(Platform, NumDevices);
|
||||
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
ol_get_device_count_params_t Params = {&Platform, &NumDevices};
|
||||
std::cout << "(" << &Params << ")";
|
||||
std::cout << "-> " << Result << "\n";
|
||||
if (Result && Result->Details) {
|
||||
std::cout << " *Error Details* " << Result->Details << " \n";
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
ol_result_t olGetDeviceCountWithCodeLoc(ol_platform_handle_t Platform,
|
||||
uint32_t *NumDevices,
|
||||
ol_code_location_t *CodeLocation) {
|
||||
currentCodeLocation() = CodeLocation;
|
||||
ol_result_t Result = olGetDeviceCount(Platform, NumDevices);
|
||||
|
||||
currentCodeLocation() = nullptr;
|
||||
return Result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
ol_impl_result_t olGetDevice_val(ol_platform_handle_t Platform,
|
||||
uint32_t NumEntries,
|
||||
ol_device_handle_t *Devices) {
|
||||
if (true /*enableParameterValidation*/) {
|
||||
if (NumEntries == 0) {
|
||||
return OL_ERRC_INVALID_SIZE;
|
||||
}
|
||||
|
||||
if (NULL == Platform) {
|
||||
return OL_ERRC_INVALID_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (NULL == Devices) {
|
||||
return OL_ERRC_INVALID_NULL_POINTER;
|
||||
}
|
||||
}
|
||||
|
||||
return olGetDevice_impl(Platform, NumEntries, Devices);
|
||||
}
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetDevice(ol_platform_handle_t Platform,
|
||||
uint32_t NumEntries,
|
||||
ol_device_handle_t *Devices) {
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
std::cout << "---> olGetDevice";
|
||||
}
|
||||
|
||||
ol_result_t Result = olGetDevice_val(Platform, NumEntries, Devices);
|
||||
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
ol_get_device_params_t Params = {&Platform, &NumEntries, &Devices};
|
||||
std::cout << "(" << &Params << ")";
|
||||
std::cout << "-> " << Result << "\n";
|
||||
if (Result && Result->Details) {
|
||||
std::cout << " *Error Details* " << Result->Details << " \n";
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
ol_result_t olGetDeviceWithCodeLoc(ol_platform_handle_t Platform,
|
||||
uint32_t NumEntries,
|
||||
ol_device_handle_t *Devices,
|
||||
ol_code_location_t *CodeLocation) {
|
||||
currentCodeLocation() = CodeLocation;
|
||||
ol_result_t Result = olGetDevice(Platform, NumEntries, Devices);
|
||||
|
||||
currentCodeLocation() = nullptr;
|
||||
return Result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
ol_impl_result_t olGetDeviceInfo_val(ol_device_handle_t Device,
|
||||
ol_device_info_t PropName, size_t PropSize,
|
||||
void *PropValue) {
|
||||
if (true /*enableParameterValidation*/) {
|
||||
if (PropSize == 0) {
|
||||
return OL_ERRC_INVALID_SIZE;
|
||||
}
|
||||
|
||||
if (NULL == Device) {
|
||||
return OL_ERRC_INVALID_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (NULL == PropValue) {
|
||||
return OL_ERRC_INVALID_NULL_POINTER;
|
||||
}
|
||||
}
|
||||
|
||||
return olGetDeviceInfo_impl(Device, PropName, PropSize, PropValue);
|
||||
}
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetDeviceInfo(ol_device_handle_t Device,
|
||||
ol_device_info_t PropName,
|
||||
size_t PropSize,
|
||||
void *PropValue) {
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
std::cout << "---> olGetDeviceInfo";
|
||||
}
|
||||
|
||||
ol_result_t Result =
|
||||
olGetDeviceInfo_val(Device, PropName, PropSize, PropValue);
|
||||
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
ol_get_device_info_params_t Params = {&Device, &PropName, &PropSize,
|
||||
&PropValue};
|
||||
std::cout << "(" << &Params << ")";
|
||||
std::cout << "-> " << Result << "\n";
|
||||
if (Result && Result->Details) {
|
||||
std::cout << " *Error Details* " << Result->Details << " \n";
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
ol_result_t olGetDeviceInfoWithCodeLoc(ol_device_handle_t Device,
|
||||
ol_device_info_t PropName,
|
||||
size_t PropSize, void *PropValue,
|
||||
ol_code_location_t *CodeLocation) {
|
||||
currentCodeLocation() = CodeLocation;
|
||||
ol_result_t Result = olGetDeviceInfo(Device, PropName, PropSize, PropValue);
|
||||
|
||||
currentCodeLocation() = nullptr;
|
||||
return Result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
ol_impl_result_t olGetDeviceInfoSize_val(ol_device_handle_t Device,
|
||||
ol_device_info_t PropName,
|
||||
size_t *PropSizeRet) {
|
||||
if (true /*enableParameterValidation*/) {
|
||||
if (NULL == Device) {
|
||||
return OL_ERRC_INVALID_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (NULL == PropSizeRet) {
|
||||
return OL_ERRC_INVALID_NULL_POINTER;
|
||||
}
|
||||
}
|
||||
|
||||
return olGetDeviceInfoSize_impl(Device, PropName, PropSizeRet);
|
||||
}
|
||||
OL_APIEXPORT ol_result_t OL_APICALL olGetDeviceInfoSize(
|
||||
ol_device_handle_t Device, ol_device_info_t PropName, size_t *PropSizeRet) {
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
std::cout << "---> olGetDeviceInfoSize";
|
||||
}
|
||||
|
||||
ol_result_t Result = olGetDeviceInfoSize_val(Device, PropName, PropSizeRet);
|
||||
|
||||
if (offloadConfig().TracingEnabled) {
|
||||
ol_get_device_info_size_params_t Params = {&Device, &PropName,
|
||||
&PropSizeRet};
|
||||
std::cout << "(" << &Params << ")";
|
||||
std::cout << "-> " << Result << "\n";
|
||||
if (Result && Result->Details) {
|
||||
std::cout << " *Error Details* " << Result->Details << " \n";
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
ol_result_t olGetDeviceInfoSizeWithCodeLoc(ol_device_handle_t Device,
|
||||
ol_device_info_t PropName,
|
||||
size_t *PropSizeRet,
|
||||
ol_code_location_t *CodeLocation) {
|
||||
currentCodeLocation() = CodeLocation;
|
||||
ol_result_t Result = olGetDeviceInfoSize(Device, PropName, PropSizeRet);
|
||||
|
||||
currentCodeLocation() = nullptr;
|
||||
return Result;
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
//===- Auto-generated file, part of the LLVM/Offload project --------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef OFFLOAD_FUNC
|
||||
#error Please define the macro OFFLOAD_FUNC(Function)
|
||||
#endif
|
||||
|
||||
OFFLOAD_FUNC(olInit)
|
||||
OFFLOAD_FUNC(olShutDown)
|
||||
OFFLOAD_FUNC(olGetPlatform)
|
||||
OFFLOAD_FUNC(olGetPlatformCount)
|
||||
OFFLOAD_FUNC(olGetPlatformInfo)
|
||||
OFFLOAD_FUNC(olGetPlatformInfoSize)
|
||||
OFFLOAD_FUNC(olGetDeviceCount)
|
||||
OFFLOAD_FUNC(olGetDevice)
|
||||
OFFLOAD_FUNC(olGetDeviceInfo)
|
||||
OFFLOAD_FUNC(olGetDeviceInfoSize)
|
||||
OFFLOAD_FUNC(olInitWithCodeLoc)
|
||||
OFFLOAD_FUNC(olShutDownWithCodeLoc)
|
||||
OFFLOAD_FUNC(olGetPlatformWithCodeLoc)
|
||||
OFFLOAD_FUNC(olGetPlatformCountWithCodeLoc)
|
||||
OFFLOAD_FUNC(olGetPlatformInfoWithCodeLoc)
|
||||
OFFLOAD_FUNC(olGetPlatformInfoSizeWithCodeLoc)
|
||||
OFFLOAD_FUNC(olGetDeviceCountWithCodeLoc)
|
||||
OFFLOAD_FUNC(olGetDeviceWithCodeLoc)
|
||||
OFFLOAD_FUNC(olGetDeviceInfoWithCodeLoc)
|
||||
OFFLOAD_FUNC(olGetDeviceInfoSizeWithCodeLoc)
|
||||
|
||||
#undef OFFLOAD_FUNC
|
@ -1,38 +0,0 @@
|
||||
//===- Auto-generated file, part of the LLVM/Offload project --------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
ol_impl_result_t olInit_impl();
|
||||
|
||||
ol_impl_result_t olShutDown_impl();
|
||||
|
||||
ol_impl_result_t olGetPlatform_impl(uint32_t NumEntries,
|
||||
ol_platform_handle_t *Platforms);
|
||||
|
||||
ol_impl_result_t olGetPlatformCount_impl(uint32_t *NumPlatforms);
|
||||
|
||||
ol_impl_result_t olGetPlatformInfo_impl(ol_platform_handle_t Platform,
|
||||
ol_platform_info_t PropName,
|
||||
size_t PropSize, void *PropValue);
|
||||
|
||||
ol_impl_result_t olGetPlatformInfoSize_impl(ol_platform_handle_t Platform,
|
||||
ol_platform_info_t PropName,
|
||||
size_t *PropSizeRet);
|
||||
|
||||
ol_impl_result_t olGetDeviceCount_impl(ol_platform_handle_t Platform,
|
||||
uint32_t *NumDevices);
|
||||
|
||||
ol_impl_result_t olGetDevice_impl(ol_platform_handle_t Platform,
|
||||
uint32_t NumEntries,
|
||||
ol_device_handle_t *Devices);
|
||||
|
||||
ol_impl_result_t olGetDeviceInfo_impl(ol_device_handle_t Device,
|
||||
ol_device_info_t PropName,
|
||||
size_t PropSize, void *PropValue);
|
||||
|
||||
ol_impl_result_t olGetDeviceInfoSize_impl(ol_device_handle_t Device,
|
||||
ol_device_info_t PropName,
|
||||
size_t *PropSizeRet);
|
@ -1,428 +0,0 @@
|
||||
//===- Auto-generated file, part of the LLVM/Offload project --------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Auto-generated file, do not manually edit.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <OffloadAPI.h>
|
||||
#include <ostream>
|
||||
|
||||
template <typename T>
|
||||
inline ol_result_t printPtr(std::ostream &os, const T *ptr);
|
||||
template <typename T>
|
||||
inline void printTagged(std::ostream &os, const void *ptr, T value,
|
||||
size_t size);
|
||||
template <typename T> struct is_handle : std::false_type {};
|
||||
template <> struct is_handle<ol_platform_handle_t> : std::true_type {};
|
||||
template <> struct is_handle<ol_device_handle_t> : std::true_type {};
|
||||
template <> struct is_handle<ol_context_handle_t> : std::true_type {};
|
||||
template <typename T> inline constexpr bool is_handle_v = is_handle<T>::value;
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &os, enum ol_errc_t value);
|
||||
inline std::ostream &operator<<(std::ostream &os,
|
||||
enum ol_platform_info_t value);
|
||||
inline std::ostream &operator<<(std::ostream &os,
|
||||
enum ol_platform_backend_t value);
|
||||
inline std::ostream &operator<<(std::ostream &os, enum ol_device_type_t value);
|
||||
inline std::ostream &operator<<(std::ostream &os, enum ol_device_info_t value);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Print operator for the ol_errc_t type
|
||||
/// @returns std::ostream &
|
||||
inline std::ostream &operator<<(std::ostream &os, enum ol_errc_t value) {
|
||||
switch (value) {
|
||||
case OL_ERRC_SUCCESS:
|
||||
os << "OL_ERRC_SUCCESS";
|
||||
break;
|
||||
case OL_ERRC_INVALID_VALUE:
|
||||
os << "OL_ERRC_INVALID_VALUE";
|
||||
break;
|
||||
case OL_ERRC_INVALID_PLATFORM:
|
||||
os << "OL_ERRC_INVALID_PLATFORM";
|
||||
break;
|
||||
case OL_ERRC_DEVICE_NOT_FOUND:
|
||||
os << "OL_ERRC_DEVICE_NOT_FOUND";
|
||||
break;
|
||||
case OL_ERRC_INVALID_DEVICE:
|
||||
os << "OL_ERRC_INVALID_DEVICE";
|
||||
break;
|
||||
case OL_ERRC_DEVICE_LOST:
|
||||
os << "OL_ERRC_DEVICE_LOST";
|
||||
break;
|
||||
case OL_ERRC_UNINITIALIZED:
|
||||
os << "OL_ERRC_UNINITIALIZED";
|
||||
break;
|
||||
case OL_ERRC_OUT_OF_RESOURCES:
|
||||
os << "OL_ERRC_OUT_OF_RESOURCES";
|
||||
break;
|
||||
case OL_ERRC_UNSUPPORTED_VERSION:
|
||||
os << "OL_ERRC_UNSUPPORTED_VERSION";
|
||||
break;
|
||||
case OL_ERRC_UNSUPPORTED_FEATURE:
|
||||
os << "OL_ERRC_UNSUPPORTED_FEATURE";
|
||||
break;
|
||||
case OL_ERRC_INVALID_ARGUMENT:
|
||||
os << "OL_ERRC_INVALID_ARGUMENT";
|
||||
break;
|
||||
case OL_ERRC_INVALID_NULL_HANDLE:
|
||||
os << "OL_ERRC_INVALID_NULL_HANDLE";
|
||||
break;
|
||||
case OL_ERRC_INVALID_NULL_POINTER:
|
||||
os << "OL_ERRC_INVALID_NULL_POINTER";
|
||||
break;
|
||||
case OL_ERRC_INVALID_SIZE:
|
||||
os << "OL_ERRC_INVALID_SIZE";
|
||||
break;
|
||||
case OL_ERRC_INVALID_ENUMERATION:
|
||||
os << "OL_ERRC_INVALID_ENUMERATION";
|
||||
break;
|
||||
case OL_ERRC_UNSUPPORTED_ENUMERATION:
|
||||
os << "OL_ERRC_UNSUPPORTED_ENUMERATION";
|
||||
break;
|
||||
case OL_ERRC_UNKNOWN:
|
||||
os << "OL_ERRC_UNKNOWN";
|
||||
break;
|
||||
default:
|
||||
os << "unknown enumerator";
|
||||
break;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Print operator for the ol_platform_info_t type
|
||||
/// @returns std::ostream &
|
||||
inline std::ostream &operator<<(std::ostream &os,
|
||||
enum ol_platform_info_t value) {
|
||||
switch (value) {
|
||||
case OL_PLATFORM_INFO_NAME:
|
||||
os << "OL_PLATFORM_INFO_NAME";
|
||||
break;
|
||||
case OL_PLATFORM_INFO_VENDOR_NAME:
|
||||
os << "OL_PLATFORM_INFO_VENDOR_NAME";
|
||||
break;
|
||||
case OL_PLATFORM_INFO_VERSION:
|
||||
os << "OL_PLATFORM_INFO_VERSION";
|
||||
break;
|
||||
case OL_PLATFORM_INFO_BACKEND:
|
||||
os << "OL_PLATFORM_INFO_BACKEND";
|
||||
break;
|
||||
default:
|
||||
os << "unknown enumerator";
|
||||
break;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Print type-tagged ol_platform_info_t enum value
|
||||
/// @returns std::ostream &
|
||||
template <>
|
||||
inline void printTagged(std::ostream &os, const void *ptr,
|
||||
ol_platform_info_t value, size_t size) {
|
||||
if (ptr == NULL) {
|
||||
printPtr(os, ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (value) {
|
||||
case OL_PLATFORM_INFO_NAME: {
|
||||
printPtr(os, (const char *)ptr);
|
||||
break;
|
||||
}
|
||||
case OL_PLATFORM_INFO_VENDOR_NAME: {
|
||||
printPtr(os, (const char *)ptr);
|
||||
break;
|
||||
}
|
||||
case OL_PLATFORM_INFO_VERSION: {
|
||||
printPtr(os, (const char *)ptr);
|
||||
break;
|
||||
}
|
||||
case OL_PLATFORM_INFO_BACKEND: {
|
||||
const ol_platform_backend_t *const tptr =
|
||||
(const ol_platform_backend_t *const)ptr;
|
||||
os << (const void *)tptr << " (";
|
||||
os << *tptr;
|
||||
os << ")";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
os << "unknown enumerator";
|
||||
break;
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Print operator for the ol_platform_backend_t type
|
||||
/// @returns std::ostream &
|
||||
inline std::ostream &operator<<(std::ostream &os,
|
||||
enum ol_platform_backend_t value) {
|
||||
switch (value) {
|
||||
case OL_PLATFORM_BACKEND_UNKNOWN:
|
||||
os << "OL_PLATFORM_BACKEND_UNKNOWN";
|
||||
break;
|
||||
case OL_PLATFORM_BACKEND_CUDA:
|
||||
os << "OL_PLATFORM_BACKEND_CUDA";
|
||||
break;
|
||||
case OL_PLATFORM_BACKEND_AMDGPU:
|
||||
os << "OL_PLATFORM_BACKEND_AMDGPU";
|
||||
break;
|
||||
default:
|
||||
os << "unknown enumerator";
|
||||
break;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Print operator for the ol_device_type_t type
|
||||
/// @returns std::ostream &
|
||||
inline std::ostream &operator<<(std::ostream &os, enum ol_device_type_t value) {
|
||||
switch (value) {
|
||||
case OL_DEVICE_TYPE_DEFAULT:
|
||||
os << "OL_DEVICE_TYPE_DEFAULT";
|
||||
break;
|
||||
case OL_DEVICE_TYPE_ALL:
|
||||
os << "OL_DEVICE_TYPE_ALL";
|
||||
break;
|
||||
case OL_DEVICE_TYPE_GPU:
|
||||
os << "OL_DEVICE_TYPE_GPU";
|
||||
break;
|
||||
case OL_DEVICE_TYPE_CPU:
|
||||
os << "OL_DEVICE_TYPE_CPU";
|
||||
break;
|
||||
default:
|
||||
os << "unknown enumerator";
|
||||
break;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Print operator for the ol_device_info_t type
|
||||
/// @returns std::ostream &
|
||||
inline std::ostream &operator<<(std::ostream &os, enum ol_device_info_t value) {
|
||||
switch (value) {
|
||||
case OL_DEVICE_INFO_TYPE:
|
||||
os << "OL_DEVICE_INFO_TYPE";
|
||||
break;
|
||||
case OL_DEVICE_INFO_PLATFORM:
|
||||
os << "OL_DEVICE_INFO_PLATFORM";
|
||||
break;
|
||||
case OL_DEVICE_INFO_NAME:
|
||||
os << "OL_DEVICE_INFO_NAME";
|
||||
break;
|
||||
case OL_DEVICE_INFO_VENDOR:
|
||||
os << "OL_DEVICE_INFO_VENDOR";
|
||||
break;
|
||||
case OL_DEVICE_INFO_DRIVER_VERSION:
|
||||
os << "OL_DEVICE_INFO_DRIVER_VERSION";
|
||||
break;
|
||||
default:
|
||||
os << "unknown enumerator";
|
||||
break;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Print type-tagged ol_device_info_t enum value
|
||||
/// @returns std::ostream &
|
||||
template <>
|
||||
inline void printTagged(std::ostream &os, const void *ptr,
|
||||
ol_device_info_t value, size_t size) {
|
||||
if (ptr == NULL) {
|
||||
printPtr(os, ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (value) {
|
||||
case OL_DEVICE_INFO_TYPE: {
|
||||
const ol_device_type_t *const tptr = (const ol_device_type_t *const)ptr;
|
||||
os << (const void *)tptr << " (";
|
||||
os << *tptr;
|
||||
os << ")";
|
||||
break;
|
||||
}
|
||||
case OL_DEVICE_INFO_PLATFORM: {
|
||||
const ol_platform_handle_t *const tptr =
|
||||
(const ol_platform_handle_t *const)ptr;
|
||||
os << (const void *)tptr << " (";
|
||||
os << *tptr;
|
||||
os << ")";
|
||||
break;
|
||||
}
|
||||
case OL_DEVICE_INFO_NAME: {
|
||||
printPtr(os, (const char *)ptr);
|
||||
break;
|
||||
}
|
||||
case OL_DEVICE_INFO_VENDOR: {
|
||||
printPtr(os, (const char *)ptr);
|
||||
break;
|
||||
}
|
||||
case OL_DEVICE_INFO_DRIVER_VERSION: {
|
||||
printPtr(os, (const char *)ptr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
os << "unknown enumerator";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &os,
|
||||
const ol_error_struct_t *Err) {
|
||||
if (Err == nullptr) {
|
||||
os << "OL_SUCCESS";
|
||||
} else {
|
||||
os << Err->Code;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &os,
|
||||
const struct ol_get_platform_params_t *params) {
|
||||
os << ".NumEntries = ";
|
||||
os << *params->pNumEntries;
|
||||
os << ", ";
|
||||
os << ".Platforms = ";
|
||||
os << "{";
|
||||
for (size_t i = 0; i < *params->pNumEntries; i++) {
|
||||
if (i > 0) {
|
||||
os << ", ";
|
||||
}
|
||||
printPtr(os, (*params->pPlatforms)[i]);
|
||||
}
|
||||
os << "}";
|
||||
return os;
|
||||
}
|
||||
|
||||
inline std::ostream &
|
||||
operator<<(std::ostream &os,
|
||||
const struct ol_get_platform_count_params_t *params) {
|
||||
os << ".NumPlatforms = ";
|
||||
printPtr(os, *params->pNumPlatforms);
|
||||
return os;
|
||||
}
|
||||
|
||||
inline std::ostream &
|
||||
operator<<(std::ostream &os,
|
||||
const struct ol_get_platform_info_params_t *params) {
|
||||
os << ".Platform = ";
|
||||
printPtr(os, *params->pPlatform);
|
||||
os << ", ";
|
||||
os << ".PropName = ";
|
||||
os << *params->pPropName;
|
||||
os << ", ";
|
||||
os << ".PropSize = ";
|
||||
os << *params->pPropSize;
|
||||
os << ", ";
|
||||
os << ".PropValue = ";
|
||||
printTagged(os, *params->pPropValue, *params->pPropName, *params->pPropSize);
|
||||
return os;
|
||||
}
|
||||
|
||||
inline std::ostream &
|
||||
operator<<(std::ostream &os,
|
||||
const struct ol_get_platform_info_size_params_t *params) {
|
||||
os << ".Platform = ";
|
||||
printPtr(os, *params->pPlatform);
|
||||
os << ", ";
|
||||
os << ".PropName = ";
|
||||
os << *params->pPropName;
|
||||
os << ", ";
|
||||
os << ".PropSizeRet = ";
|
||||
printPtr(os, *params->pPropSizeRet);
|
||||
return os;
|
||||
}
|
||||
|
||||
inline std::ostream &
|
||||
operator<<(std::ostream &os,
|
||||
const struct ol_get_device_count_params_t *params) {
|
||||
os << ".Platform = ";
|
||||
printPtr(os, *params->pPlatform);
|
||||
os << ", ";
|
||||
os << ".NumDevices = ";
|
||||
printPtr(os, *params->pNumDevices);
|
||||
return os;
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &os,
|
||||
const struct ol_get_device_params_t *params) {
|
||||
os << ".Platform = ";
|
||||
printPtr(os, *params->pPlatform);
|
||||
os << ", ";
|
||||
os << ".NumEntries = ";
|
||||
os << *params->pNumEntries;
|
||||
os << ", ";
|
||||
os << ".Devices = ";
|
||||
os << "{";
|
||||
for (size_t i = 0; i < *params->pNumEntries; i++) {
|
||||
if (i > 0) {
|
||||
os << ", ";
|
||||
}
|
||||
printPtr(os, (*params->pDevices)[i]);
|
||||
}
|
||||
os << "}";
|
||||
return os;
|
||||
}
|
||||
|
||||
inline std::ostream &
|
||||
operator<<(std::ostream &os, const struct ol_get_device_info_params_t *params) {
|
||||
os << ".Device = ";
|
||||
printPtr(os, *params->pDevice);
|
||||
os << ", ";
|
||||
os << ".PropName = ";
|
||||
os << *params->pPropName;
|
||||
os << ", ";
|
||||
os << ".PropSize = ";
|
||||
os << *params->pPropSize;
|
||||
os << ", ";
|
||||
os << ".PropValue = ";
|
||||
printTagged(os, *params->pPropValue, *params->pPropName, *params->pPropSize);
|
||||
return os;
|
||||
}
|
||||
|
||||
inline std::ostream &
|
||||
operator<<(std::ostream &os,
|
||||
const struct ol_get_device_info_size_params_t *params) {
|
||||
os << ".Device = ";
|
||||
printPtr(os, *params->pDevice);
|
||||
os << ", ";
|
||||
os << ".PropName = ";
|
||||
os << *params->pPropName;
|
||||
os << ", ";
|
||||
os << ".PropSizeRet = ";
|
||||
printPtr(os, *params->pPropSizeRet);
|
||||
return os;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// @brief Print pointer value
|
||||
template <typename T>
|
||||
inline ol_result_t printPtr(std::ostream &os, const T *ptr) {
|
||||
if (ptr == nullptr) {
|
||||
os << "nullptr";
|
||||
} else if constexpr (std::is_pointer_v<T>) {
|
||||
os << (const void *)(ptr) << " (";
|
||||
printPtr(os, *ptr);
|
||||
os << ")";
|
||||
} else if constexpr (std::is_void_v<T> || is_handle_v<T *>) {
|
||||
os << (const void *)ptr;
|
||||
} else if constexpr (std::is_same_v<std::remove_cv_t<T>, char>) {
|
||||
os << (const void *)(ptr) << " (";
|
||||
os << ptr;
|
||||
os << ")";
|
||||
} else {
|
||||
os << (const void *)(ptr) << " (";
|
||||
os << *ptr;
|
||||
os << ")";
|
||||
}
|
||||
|
||||
return OL_SUCCESS;
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
//===- helpers.hpp- GetInfo return helpers for the new LLVM/Offload API ---===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The getInfo*/ReturnHelper facilities provide shortcut way of writing return
|
||||
// data + size for the various getInfo APIs. Based on the equivalent
|
||||
// implementations in Unified Runtime.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "OffloadAPI.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
template <typename T, typename Assign>
|
||||
ol_errc_t getInfoImpl(size_t ParamValueSize, void *ParamValue,
|
||||
size_t *ParamValueSizeRet, T Value, size_t ValueSize,
|
||||
Assign &&AssignFunc) {
|
||||
if (!ParamValue && !ParamValueSizeRet) {
|
||||
return OL_ERRC_INVALID_NULL_POINTER;
|
||||
}
|
||||
|
||||
if (ParamValue != nullptr) {
|
||||
if (ParamValueSize < ValueSize) {
|
||||
return OL_ERRC_INVALID_SIZE;
|
||||
}
|
||||
AssignFunc(ParamValue, Value, ValueSize);
|
||||
}
|
||||
|
||||
if (ParamValueSizeRet != nullptr) {
|
||||
*ParamValueSizeRet = ValueSize;
|
||||
}
|
||||
|
||||
return OL_ERRC_SUCCESS;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ol_errc_t getInfo(size_t ParamValueSize, void *ParamValue,
|
||||
size_t *ParamValueSizeRet, T Value) {
|
||||
auto Assignment = [](void *ParamValue, T Value, size_t) {
|
||||
*static_cast<T *>(ParamValue) = Value;
|
||||
};
|
||||
|
||||
return getInfoImpl(ParamValueSize, ParamValue, ParamValueSizeRet, Value,
|
||||
sizeof(T), Assignment);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ol_errc_t getInfoArray(size_t array_length, size_t ParamValueSize,
|
||||
void *ParamValue, size_t *ParamValueSizeRet,
|
||||
const T *Value) {
|
||||
return getInfoImpl(ParamValueSize, ParamValue, ParamValueSizeRet, Value,
|
||||
array_length * sizeof(T), memcpy);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline ol_errc_t getInfo<const char *>(size_t ParamValueSize, void *ParamValue,
|
||||
size_t *ParamValueSizeRet,
|
||||
const char *Value) {
|
||||
return getInfoArray(strlen(Value) + 1, ParamValueSize, ParamValue,
|
||||
ParamValueSizeRet, Value);
|
||||
}
|
||||
|
||||
class ReturnHelper {
|
||||
public:
|
||||
ReturnHelper(size_t ParamValueSize, void *ParamValue,
|
||||
size_t *ParamValueSizeRet)
|
||||
: ParamValueSize(ParamValueSize), ParamValue(ParamValue),
|
||||
ParamValueSizeRet(ParamValueSizeRet) {}
|
||||
|
||||
// A version where in/out info size is represented by a single pointer
|
||||
// to a value which is updated on return
|
||||
ReturnHelper(size_t *ParamValueSize, void *ParamValue)
|
||||
: ParamValueSize(*ParamValueSize), ParamValue(ParamValue),
|
||||
ParamValueSizeRet(ParamValueSize) {}
|
||||
|
||||
// Scalar return Value
|
||||
template <class T> ol_errc_t operator()(const T &t) {
|
||||
return getInfo(ParamValueSize, ParamValue, ParamValueSizeRet, t);
|
||||
}
|
||||
|
||||
// Array return Value
|
||||
template <class T> ol_errc_t operator()(const T *t, size_t s) {
|
||||
return getInfoArray(s, ParamValueSize, ParamValue, ParamValueSizeRet, t);
|
||||
}
|
||||
|
||||
protected:
|
||||
size_t ParamValueSize;
|
||||
void *ParamValue;
|
||||
size_t *ParamValueSizeRet;
|
||||
};
|
@ -1,232 +0,0 @@
|
||||
//===- ol_impl.cpp - Implementation of the new LLVM/Offload API ------===//
|
||||
//
|
||||
// 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 contains the definitions of the new LLVM/Offload API entry points. See
|
||||
// new-api/API/README.md for more information.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "OffloadImpl.hpp"
|
||||
#include "Helpers.hpp"
|
||||
#include "PluginManager.h"
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
#include <OffloadAPI.h>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::omp::target::plugin;
|
||||
|
||||
// Handle type definitions. Ideally these would be 1:1 with the plugins
|
||||
struct ol_device_handle_t_ {
|
||||
int DeviceNum;
|
||||
GenericDeviceTy &Device;
|
||||
ol_platform_handle_t Platform;
|
||||
};
|
||||
|
||||
struct ol_platform_handle_t_ {
|
||||
std::unique_ptr<GenericPluginTy> Plugin;
|
||||
std::vector<ol_device_handle_t_> Devices;
|
||||
};
|
||||
|
||||
using PlatformVecT = SmallVector<ol_platform_handle_t_, 4>;
|
||||
PlatformVecT &Platforms() {
|
||||
static PlatformVecT Platforms;
|
||||
return Platforms;
|
||||
}
|
||||
|
||||
// Every plugin exports this method to create an instance of the plugin type.
|
||||
#define PLUGIN_TARGET(Name) extern "C" GenericPluginTy *createPlugin_##Name();
|
||||
#include "Shared/Targets.def"
|
||||
|
||||
void initPlugins() {
|
||||
// Attempt to create an instance of each supported plugin.
|
||||
#define PLUGIN_TARGET(Name) \
|
||||
do { \
|
||||
Platforms().emplace_back(ol_platform_handle_t_{ \
|
||||
std::unique_ptr<GenericPluginTy>(createPlugin_##Name()), {}}); \
|
||||
} while (false);
|
||||
#include "Shared/Targets.def"
|
||||
|
||||
// Preemptively initialize all devices in the plugin so we can just return
|
||||
// them from deviceGet
|
||||
for (auto &Platform : Platforms()) {
|
||||
auto Err = Platform.Plugin->init();
|
||||
[[maybe_unused]] std::string InfoMsg = toString(std::move(Err));
|
||||
for (auto DevNum = 0; DevNum < Platform.Plugin->number_of_devices();
|
||||
DevNum++) {
|
||||
if (Platform.Plugin->init_device(DevNum) == OFFLOAD_SUCCESS) {
|
||||
Platform.Devices.emplace_back(ol_device_handle_t_{
|
||||
DevNum, Platform.Plugin->getDevice(DevNum), &Platform});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offloadConfig().TracingEnabled = std::getenv("OFFLOAD_TRACE");
|
||||
}
|
||||
|
||||
// TODO: We can properly reference count here and manage the resources in a more
|
||||
// clever way
|
||||
ol_impl_result_t olInit_impl() {
|
||||
static std::once_flag InitFlag;
|
||||
std::call_once(InitFlag, initPlugins);
|
||||
|
||||
return OL_SUCCESS;
|
||||
}
|
||||
ol_impl_result_t olShutDown_impl() { return OL_SUCCESS; }
|
||||
|
||||
ol_impl_result_t olGetPlatformCount_impl(uint32_t *NumPlatforms) {
|
||||
*NumPlatforms = Platforms().size();
|
||||
return OL_SUCCESS;
|
||||
}
|
||||
|
||||
ol_impl_result_t olGetPlatform_impl(uint32_t NumEntries,
|
||||
ol_platform_handle_t *PlatformsOut) {
|
||||
if (NumEntries > Platforms().size()) {
|
||||
return {OL_ERRC_INVALID_SIZE,
|
||||
std::string{formatv("{0} platform(s) available but {1} requested.",
|
||||
Platforms().size(), NumEntries)}};
|
||||
}
|
||||
|
||||
for (uint32_t PlatformIndex = 0; PlatformIndex < NumEntries;
|
||||
PlatformIndex++) {
|
||||
PlatformsOut[PlatformIndex] = &(Platforms())[PlatformIndex];
|
||||
}
|
||||
|
||||
return OL_SUCCESS;
|
||||
}
|
||||
|
||||
ol_impl_result_t olGetPlatformInfoImplDetail(ol_platform_handle_t Platform,
|
||||
ol_platform_info_t PropName,
|
||||
size_t PropSize, void *PropValue,
|
||||
size_t *PropSizeRet) {
|
||||
ReturnHelper ReturnValue(PropSize, PropValue, PropSizeRet);
|
||||
|
||||
switch (PropName) {
|
||||
case OL_PLATFORM_INFO_NAME:
|
||||
return ReturnValue(Platform->Plugin->getName());
|
||||
case OL_PLATFORM_INFO_VENDOR_NAME:
|
||||
// TODO: Implement this
|
||||
return ReturnValue("Unknown platform vendor");
|
||||
case OL_PLATFORM_INFO_VERSION: {
|
||||
return ReturnValue(formatv("v{0}.{1}.{2}", OL_VERSION_MAJOR,
|
||||
OL_VERSION_MINOR, OL_VERSION_PATCH)
|
||||
.str()
|
||||
.c_str());
|
||||
}
|
||||
case OL_PLATFORM_INFO_BACKEND: {
|
||||
auto PluginName = Platform->Plugin->getName();
|
||||
if (PluginName == StringRef("CUDA")) {
|
||||
return ReturnValue(OL_PLATFORM_BACKEND_CUDA);
|
||||
} else if (PluginName == StringRef("AMDGPU")) {
|
||||
return ReturnValue(OL_PLATFORM_BACKEND_AMDGPU);
|
||||
} else {
|
||||
return ReturnValue(OL_PLATFORM_BACKEND_UNKNOWN);
|
||||
}
|
||||
}
|
||||
default:
|
||||
return OL_ERRC_INVALID_ENUMERATION;
|
||||
}
|
||||
|
||||
return OL_SUCCESS;
|
||||
}
|
||||
|
||||
ol_impl_result_t olGetPlatformInfo_impl(ol_platform_handle_t Platform,
|
||||
ol_platform_info_t PropName,
|
||||
size_t PropSize, void *PropValue) {
|
||||
return olGetPlatformInfoImplDetail(Platform, PropName, PropSize, PropValue,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
ol_impl_result_t olGetPlatformInfoSize_impl(ol_platform_handle_t Platform,
|
||||
ol_platform_info_t PropName,
|
||||
size_t *PropSizeRet) {
|
||||
return olGetPlatformInfoImplDetail(Platform, PropName, 0, nullptr,
|
||||
PropSizeRet);
|
||||
}
|
||||
|
||||
ol_impl_result_t olGetDeviceCount_impl(ol_platform_handle_t Platform,
|
||||
uint32_t *pNumDevices) {
|
||||
*pNumDevices = static_cast<uint32_t>(Platform->Devices.size());
|
||||
|
||||
return OL_SUCCESS;
|
||||
}
|
||||
|
||||
ol_impl_result_t olGetDevice_impl(ol_platform_handle_t Platform,
|
||||
uint32_t NumEntries,
|
||||
ol_device_handle_t *Devices) {
|
||||
if (NumEntries > Platform->Devices.size()) {
|
||||
return OL_ERRC_INVALID_SIZE;
|
||||
}
|
||||
|
||||
for (uint32_t DeviceIndex = 0; DeviceIndex < NumEntries; DeviceIndex++) {
|
||||
Devices[DeviceIndex] = &(Platform->Devices[DeviceIndex]);
|
||||
}
|
||||
|
||||
return OL_SUCCESS;
|
||||
}
|
||||
|
||||
ol_impl_result_t olGetDeviceInfoImplDetail(ol_device_handle_t Device,
|
||||
ol_device_info_t PropName,
|
||||
size_t PropSize, void *PropValue,
|
||||
size_t *PropSizeRet) {
|
||||
|
||||
ReturnHelper ReturnValue(PropSize, PropValue, PropSizeRet);
|
||||
|
||||
InfoQueueTy DevInfo;
|
||||
if (auto Err = Device->Device.obtainInfoImpl(DevInfo))
|
||||
return OL_ERRC_OUT_OF_RESOURCES;
|
||||
|
||||
// Find the info if it exists under any of the given names
|
||||
auto GetInfo = [&DevInfo](std::vector<std::string> Names) {
|
||||
for (auto Name : Names) {
|
||||
auto InfoKeyMatches = [&](const InfoQueueTy::InfoQueueEntryTy &Info) {
|
||||
return Info.Key == Name;
|
||||
};
|
||||
auto Item = std::find_if(DevInfo.getQueue().begin(),
|
||||
DevInfo.getQueue().end(), InfoKeyMatches);
|
||||
|
||||
if (Item != std::end(DevInfo.getQueue())) {
|
||||
return Item->Value;
|
||||
}
|
||||
}
|
||||
|
||||
return std::string("");
|
||||
};
|
||||
|
||||
switch (PropName) {
|
||||
case OL_DEVICE_INFO_PLATFORM:
|
||||
return ReturnValue(Device->Platform);
|
||||
case OL_DEVICE_INFO_TYPE:
|
||||
return ReturnValue(OL_DEVICE_TYPE_GPU);
|
||||
case OL_DEVICE_INFO_NAME:
|
||||
return ReturnValue(GetInfo({"Device Name"}).c_str());
|
||||
case OL_DEVICE_INFO_VENDOR:
|
||||
return ReturnValue(GetInfo({"Vendor Name"}).c_str());
|
||||
case OL_DEVICE_INFO_DRIVER_VERSION:
|
||||
return ReturnValue(
|
||||
GetInfo({"CUDA Driver Version", "HSA Runtime Version"}).c_str());
|
||||
default:
|
||||
return OL_ERRC_INVALID_ENUMERATION;
|
||||
}
|
||||
|
||||
return OL_SUCCESS;
|
||||
}
|
||||
|
||||
ol_impl_result_t olGetDeviceInfo_impl(ol_device_handle_t Device,
|
||||
ol_device_info_t PropName,
|
||||
size_t PropSize, void *PropValue) {
|
||||
return olGetDeviceInfoImplDetail(Device, PropName, PropSize, PropValue,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
ol_impl_result_t olGetDeviceInfoSize_impl(ol_device_handle_t Device,
|
||||
ol_device_info_t PropName,
|
||||
size_t *PropSizeRet) {
|
||||
return olGetDeviceInfoImplDetail(Device, PropName, 0, nullptr, PropSizeRet);
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
//===- offload_lib.cpp - Entry points for the new LLVM/Offload API --------===//
|
||||
//
|
||||
// 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 pulls in the tablegen'd API entry point functions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "OffloadImpl.hpp"
|
||||
#include <OffloadAPI.h>
|
||||
#include <OffloadPrint.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
llvm::StringSet<> &errorStrs() {
|
||||
static llvm::StringSet<> ErrorStrs;
|
||||
return ErrorStrs;
|
||||
}
|
||||
|
||||
ErrSetT &errors() {
|
||||
static ErrSetT Errors{};
|
||||
return Errors;
|
||||
}
|
||||
|
||||
ol_code_location_t *¤tCodeLocation() {
|
||||
thread_local ol_code_location_t *CodeLoc = nullptr;
|
||||
return CodeLoc;
|
||||
}
|
||||
|
||||
OffloadConfig &offloadConfig() {
|
||||
static OffloadConfig Config{};
|
||||
return Config;
|
||||
}
|
||||
|
||||
// Pull in the declarations for the implementation funtions. The actual entry
|
||||
// points in this file wrap these.
|
||||
#include "OffloadImplFuncDecls.inc"
|
||||
|
||||
// Pull in the tablegen'd entry point definitions.
|
||||
#include "OffloadEntryPoints.inc"
|
@ -124,7 +124,6 @@ enum InfoLevelKind { InfoLevel1 = 1, InfoLevel2, InfoLevel3 };
|
||||
/// we use the level to determine the indentation of the key-value property at
|
||||
/// printing time. See the enum InfoLevelKind for the list of accepted levels.
|
||||
class InfoQueueTy {
|
||||
public:
|
||||
struct InfoQueueEntryTy {
|
||||
std::string Key;
|
||||
std::string Value;
|
||||
@ -132,7 +131,6 @@ public:
|
||||
uint64_t Level;
|
||||
};
|
||||
|
||||
private:
|
||||
std::deque<InfoQueueEntryTy> Queue;
|
||||
|
||||
public:
|
||||
@ -155,8 +153,6 @@ public:
|
||||
Queue.push_back({Key, Value, Units, L});
|
||||
}
|
||||
|
||||
const std::deque<InfoQueueEntryTy> &getQueue() const { return Queue; }
|
||||
|
||||
/// Print all info entries added to the queue.
|
||||
void print() const {
|
||||
// We print four spances for each level.
|
||||
|
@ -66,7 +66,7 @@ def evaluate_bool_env(env):
|
||||
config.name = 'libomptarget :: ' + config.libomptarget_current_target
|
||||
|
||||
# suffixes: A list of file extensions to treat as test files.
|
||||
config.suffixes = ['.c', '.cpp', '.cc', '.f90', '.cu', '.td']
|
||||
config.suffixes = ['.c', '.cpp', '.cc', '.f90', '.cu']
|
||||
|
||||
# excludes: A list of directories to exclude from the testuites.
|
||||
config.excludes = ['Inputs']
|
||||
@ -418,4 +418,3 @@ config.substitutions.append(("%flags", config.test_flags))
|
||||
config.substitutions.append(("%not", config.libomptarget_not))
|
||||
config.substitutions.append(("%offload-device-info",
|
||||
config.offload_device_info))
|
||||
config.substitutions.append(("%offload-tblgen", config.offload_tblgen))
|
||||
|
@ -28,6 +28,5 @@ config.libomptarget_debug = @LIBOMPTARGET_DEBUG@
|
||||
config.has_libomptarget_ompt = @LIBOMPTARGET_OMPT_SUPPORT@
|
||||
config.libomptarget_has_libc = @LIBOMPTARGET_GPU_LIBC_SUPPORT@
|
||||
config.libomptarget_test_pgo = @LIBOMPTARGET_TEST_GPU_PGO@
|
||||
config.offload_tblgen = "@OFFLOAD_TBLGEN_EXECUTABLE@"
|
||||
# Let the main config do the real work.
|
||||
lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg")
|
||||
|
@ -1,40 +0,0 @@
|
||||
// RUN: %offload-tblgen -gen-api -I %S/../../../new-api/API %s | %fcheck-generic --check-prefix=CHECK-API
|
||||
// RUN: %offload-tblgen -gen-entry-points -I %S/../../../new-api/API %s | %fcheck-generic --check-prefix=CHECK-VALIDATION
|
||||
|
||||
// Check implicit returns are included in documentation and the validation
|
||||
// wrappers where applicable
|
||||
|
||||
include "APIDefs.td"
|
||||
|
||||
def : Handle {
|
||||
let name = "offload_foo_handle_t";
|
||||
let desc = "Example handle type";
|
||||
}
|
||||
|
||||
def : Function {
|
||||
let name = "FunctionA";
|
||||
let desc = "Function A description";
|
||||
let details = [ "Function A detailed information" ];
|
||||
let params = [
|
||||
Param<"uint32_t", "ParamValue", "A plain value parameter">,
|
||||
Param<"offload_foo_handle_t", "ParamHandle", "A handle parameter">,
|
||||
Param<"uint32_t*", "ParamPointer", "A pointer parameter">,
|
||||
Param<"uint32_t*", "ParamPointerOpt", "An optional pointer parameter", PARAM_OUT_OPTIONAL>
|
||||
];
|
||||
let returns = [];
|
||||
}
|
||||
|
||||
// CHECK-API: /// @returns
|
||||
// CHECK-API: OFFLOAD_RESULT_SUCCESS
|
||||
// CHECK-API: OFFLOAD_ERRC_INVALID_NULL_HANDLE
|
||||
// CHECK-API-NEXT: `NULL == ParamHandle`
|
||||
// CHECK-API: OFFLOAD_ERRC_INVALID_NULL_POINTER
|
||||
// CHECK-API-NEXT: `NULL == ParamPointer`
|
||||
// CHECK-API-NOT: `NULL == ParamPointerOpt`
|
||||
|
||||
// CHECK-VALIDATION: FunctionA_val
|
||||
// CHECK-VALIDATION: if (NULL == ParamHandle)
|
||||
// CHECK-VALIDATION-NEXT: return OFFLOAD_ERRC_INVALID_NULL_HANDLE;
|
||||
// CHECK-VALIDATION: if (NULL == ParamPointer)
|
||||
// CHECK-VALIDATION-NEXT: return OFFLOAD_ERRC_INVALID_NULL_POINTER;
|
||||
// CHECK-VALIDATION-NOT: if (NULL == ParamPointerOpt)
|
@ -1,37 +0,0 @@
|
||||
// RUN: %offload-tblgen -gen-entry-points -I %S/../../../new-api/API %s | %fcheck-generic
|
||||
|
||||
// Check entry point wrapper functions are generated correctly
|
||||
|
||||
include "APIDefs.td"
|
||||
|
||||
def : Function {
|
||||
let name = "FunctionA";
|
||||
let desc = "Function A description";
|
||||
let details = [ "Function A detailed information" ];
|
||||
let params = [
|
||||
Param<"uint32_t", "ParamA", "Parameter A description">,
|
||||
Param<"uint32_t*", "ParamB", "Parameter B description">,
|
||||
];
|
||||
let returns = [
|
||||
Return<"OFFLOAD_ERRC_INVALID_VALUE", ["When a value is invalid"]>
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
// The validation function should call the implementation function
|
||||
// CHECK: FunctionA_val
|
||||
// CHECK: return FunctionA_impl(ParamA, ParamB);
|
||||
|
||||
// CHECK: offload_result_t{{.*}} FunctionA(
|
||||
|
||||
// The entry point should print tracing output if enabled
|
||||
// CHECK: if (offloadConfig().TracingEnabled) {
|
||||
// CHECK-NEXT: "---> FunctionA";
|
||||
|
||||
// CHECK: Result = FunctionA_val(ParamA, ParamB);
|
||||
|
||||
// Tracing should construct a param struct for printing
|
||||
// CHECK: if (offloadConfig().TracingEnabled) {
|
||||
// CHECK: function_a_params_t Params = {&ParamA, &ParamB};
|
||||
|
||||
// CHECK: return Result;
|
@ -1,39 +0,0 @@
|
||||
// RUN: %offload-tblgen -gen-api -I %S/../../../new-api/API %s | %fcheck-generic --check-prefix=CHECK-API
|
||||
// RUN: %offload-tblgen -gen-exports -I %S/../../../new-api/API %s | %fcheck-generic --check-prefix=CHECK-EXPORTS
|
||||
// RUN: %offload-tblgen -gen-func-names -I %S/../../../new-api/API %s | %fcheck-generic --check-prefix=CHECK-FUNC-MACRO
|
||||
|
||||
// Check basic support for API functions
|
||||
|
||||
include "APIDefs.td"
|
||||
|
||||
def : Function {
|
||||
let name = "FunctionA";
|
||||
let desc = "Function A description";
|
||||
let details = [ "Function A detailed information" ];
|
||||
let params = [
|
||||
Param<"uint32_t", "ParamA", "Parameter A description">,
|
||||
Param<"uint32_t*", "ParamB", "Parameter B description">,
|
||||
];
|
||||
let returns = [
|
||||
Return<"OFFLOAD_ERRC_INVALID_VALUE", ["When a value is invalid"]>
|
||||
];
|
||||
}
|
||||
|
||||
// CHECK-API: /// @brief Function A description
|
||||
// CHECK-API: /// @details
|
||||
// CHECK-API-NEXT: Function A detailed information
|
||||
// CHECK-API: /// @returns
|
||||
// CHECK-API: OFFLOAD_ERRC_INVALID_VALUE
|
||||
// CHECK-API-NEXT: When a value is invalid
|
||||
|
||||
// CHECK-API: offload_result_t
|
||||
// CHECK-API-SAME: FunctionA
|
||||
|
||||
// CHECK-API: // Parameter A description
|
||||
// CHECK-API-NEXT: uint32_t ParamA
|
||||
// CHECK-API: // Parameter B description
|
||||
// CHECK-API-NEXT: uint32_t* ParamB
|
||||
|
||||
// CHECK-EXPORTS: FunctionA
|
||||
|
||||
// CHECK-FUNC-MACRO: OFFLOAD_FUNC(FunctionA)
|
@ -1,26 +0,0 @@
|
||||
// RUN: %offload-tblgen -gen-api -I %S/../../../new-api/API %s | %fcheck-generic --check-prefix=CHECK-API
|
||||
// RUN: %offload-tblgen -gen-exports -I %S/../../../new-api/API %s | %fcheck-generic --check-prefix=CHECK-EXPORTS
|
||||
// RUN: %offload-tblgen -gen-func-names -I %S/../../../new-api/API %s | %fcheck-generic --check-prefix=CHECK-FUNC-MACRO
|
||||
|
||||
// Check that the function variant with code location information is generated
|
||||
// and is otherwise the same as the regular function
|
||||
|
||||
include "APIDefs.td"
|
||||
|
||||
def : Function {
|
||||
let name = "FunctionA";
|
||||
let desc = "Function A description";
|
||||
let details = [ "Function A detailed information" ];
|
||||
let params = [
|
||||
Param<"uint32_t", "ParamA", "Parameter A description">,
|
||||
Param<"uint32_t*", "ParamB", "Parameter B description">,
|
||||
];
|
||||
let returns = [
|
||||
Return<"OFFLOAD_ERRC_INVALID_VALUE", ["When a value is invalid"]>
|
||||
];
|
||||
}
|
||||
|
||||
// CHECK-API-DAG: offload_result_t{{.*}} FunctionA
|
||||
// CHECK-API-DAG: offload_result_t{{.*}} FunctionAWithCodeLoc
|
||||
// CHECK-EXPORTS: FunctionAWithCodeLoc
|
||||
// CHECK-FUNC-MACRO: OFFLOAD_FUNC(FunctionAWithCodeLoc)
|
@ -1,36 +0,0 @@
|
||||
// RUN: %offload-tblgen -gen-print-header -I %S/../../../new-api/API %s | %fcheck-generic
|
||||
|
||||
// Check that ranged function parameters are implemented correctly. These
|
||||
// are pointers to an array of an arbitrary size. Their size is described as a
|
||||
// range between two values. This is typically between 0 and a parameter such
|
||||
// as NumItems. The range information helps the printing code print the entire
|
||||
// range of the output rather than just the pointer or the first element.
|
||||
|
||||
include "APIDefs.td"
|
||||
|
||||
def : Handle {
|
||||
let name = "some_handle_t";
|
||||
let desc = "An example handle type";
|
||||
}
|
||||
|
||||
def : Function {
|
||||
let name = "FunctionA";
|
||||
let desc = "Function A description";
|
||||
let details = [ "Function A detailed information" ];
|
||||
let params = [
|
||||
Param<"size_t", "OutCount", "the number of things to write out", PARAM_IN>,
|
||||
RangedParam<"some_handle_t*", "OutPtr", "pointer to the output things.", PARAM_OUT,
|
||||
Range<"0", "OutCount">>
|
||||
];
|
||||
let returns = [];
|
||||
}
|
||||
|
||||
// CHECK: inline std::ostream &operator<<(std::ostream &os, const struct function_a_params_t *params) {
|
||||
// CHECK: os << ".OutPtr = ";
|
||||
// CHECK: for (size_t i = 0; i < *params->pOutCount; i++) {
|
||||
// CHECK: if (i > 0) {
|
||||
// CHECK: os << ", ";
|
||||
// CHECK: }
|
||||
// CHECK: printPtr(os, (*params->pOutPtr)[i]);
|
||||
// CHECK: }
|
||||
// CHECK: os << "}";
|
@ -1,34 +0,0 @@
|
||||
// RUN: %offload-tblgen -gen-print-header -I %S/../../../new-api/API %s | %fcheck-generic
|
||||
|
||||
// Check that print helpers are created for enums
|
||||
|
||||
include "APIDefs.td"
|
||||
|
||||
def : Enum {
|
||||
let name = "my_enum_t";
|
||||
let desc = "An example enum";
|
||||
let etors =[
|
||||
Etor<"VALUE_ONE", "The first enum value">,
|
||||
Etor<"VALUE_TWO", "The second enum value">,
|
||||
Etor<"VALUE_THREE", "The third enum value">,
|
||||
Etor<"VALUE_FOUR", "The fourth enum value">,
|
||||
];
|
||||
}
|
||||
|
||||
// CHECK: inline std::ostream &operator<<(std::ostream &os, enum my_enum_t value)
|
||||
// CHECK: switch (value) {
|
||||
// CHECK: case MY_ENUM_VALUE_ONE:
|
||||
// CHECK: os << "MY_ENUM_VALUE_ONE";
|
||||
// CHECK: break;
|
||||
// CHECK: case MY_ENUM_VALUE_TWO:
|
||||
// CHECK: os << "MY_ENUM_VALUE_TWO";
|
||||
// CHECK: break;
|
||||
// CHECK: case MY_ENUM_VALUE_THREE:
|
||||
// CHECK: os << "MY_ENUM_VALUE_THREE";
|
||||
// CHECK: break;
|
||||
// CHECK: case MY_ENUM_VALUE_FOUR:
|
||||
// CHECK: os << "MY_ENUM_VALUE_FOUR";
|
||||
// CHECK: break;
|
||||
// CHECK: default:
|
||||
// CHECK: os << "unknown enumerator";
|
||||
// CHECK: break;
|
@ -1,38 +0,0 @@
|
||||
// RUN: %offload-tblgen -gen-print-header -I %S/../../../new-api/API %s | %fcheck-generic --check-prefix=CHECK-PRINT
|
||||
// RUN: %offload-tblgen -gen-api -I %S/../../../new-api/API %s | %fcheck-generic --check-prefix=CHECK-API
|
||||
|
||||
// Check that print helpers are created for functions
|
||||
|
||||
include "APIDefs.td"
|
||||
|
||||
def : Handle {
|
||||
let name = "offload_foo_handle_t";
|
||||
let desc = "Example handle type";
|
||||
}
|
||||
|
||||
def : Function {
|
||||
let name = "FunctionA";
|
||||
let desc = "Function A description";
|
||||
let details = [ "Function A detailed information" ];
|
||||
let params = [
|
||||
Param<"uint32_t", "ParamValue", "A plain value parameter">,
|
||||
Param<"offload_foo_handle_t", "ParamHandle", "A handle parameter">,
|
||||
Param<"uint32_t*", "ParamPointer", "A pointer parameter">,
|
||||
];
|
||||
let returns = [];
|
||||
}
|
||||
|
||||
// CHECK-API: typedef struct function_a_params_t {
|
||||
// CHECK-API-NEXT: uint32_t* pParamValue;
|
||||
// CHECK-API-NEXT: offload_foo_handle_t* pParamHandle;
|
||||
// CHECK-API-NEXT: uint32_t** pParamPointer;
|
||||
|
||||
// CHECK-PRINT: inline std::ostream &operator<<(std::ostream &os, const struct function_a_params_t *params)
|
||||
// CHECK-PRINT: os << ".ParamValue = ";
|
||||
// CHECK-PRINT: os << *params->pParamValue;
|
||||
// CHECK-PRINT: os << ", ";
|
||||
// CHECK-PRINT: os << ".ParamHandle = ";
|
||||
// CHECK-PRINT: printPtr(os, *params->pParamHandle);
|
||||
// CHECK-PRINT: os << ", ";
|
||||
// CHECK-PRINT: os << ".ParamPointer = ";
|
||||
// CHECK-PRINT: printPtr(os, *params->pParamPointer);
|
@ -1,76 +0,0 @@
|
||||
// RUN: %offload-tblgen -gen-api -I %S/../../../new-api/API %s | %fcheck-generic --check-prefix=CHECK-API
|
||||
// RUN: %offload-tblgen -gen-print-header -I %S/../../../new-api/API %s | %fcheck-generic --check-prefix=CHECK-PRINT
|
||||
|
||||
// Check that type-tagged enumerators are implemented correctly. They enable
|
||||
// functions to return data of an arbitrary type and size via a void*, using
|
||||
// the value of an enum parameter to indicate which type is being returned.
|
||||
// This allows, for example, for a single olGetDeviceInfo function, rather
|
||||
// than requiring a separate entry point for every possible query.
|
||||
|
||||
include "APIDefs.td"
|
||||
|
||||
def : Handle {
|
||||
let name = "some_handle_t";
|
||||
let desc = "An example handle type";
|
||||
}
|
||||
|
||||
def : Enum {
|
||||
let name = "my_type_tagged_enum_t";
|
||||
let desc = "Example type tagged enum";
|
||||
let is_typed = 1;
|
||||
let etors = [
|
||||
TaggedEtor<"VALUE_ONE", "uint32_t", "Value one.">,
|
||||
TaggedEtor<"VALUE_TWO", "char[]", "Value two.">,
|
||||
TaggedEtor<"VALUE_THREE", "some_handle_t", "Value three.">
|
||||
];
|
||||
}
|
||||
|
||||
// Check the tagged types appear in the comments
|
||||
// CHECK-API: typedef enum my_type_tagged_enum_t {
|
||||
// CHECK-API-NEXT: [uint32_t] Value one.
|
||||
// CHECK-API-NEXT: MY_TYPE_TAGGED_ENUM_VALUE_ONE = 0,
|
||||
// CHECK-API-NEXT: [char[]] Value two.
|
||||
// CHECK-API-NEXT: MY_TYPE_TAGGED_ENUM_VALUE_TWO = 1,
|
||||
// CHECK-API-NEXT: [some_handle_t] Value three.
|
||||
// CHECK-API-NEXT: MY_TYPE_TAGGED_ENUM_VALUE_THREE = 2,
|
||||
|
||||
def : Function {
|
||||
let name = "FunctionA";
|
||||
let desc = "Function A description";
|
||||
let details = [ "Function A detailed information" ];
|
||||
let params = [
|
||||
Param<"my_type_tagged_enum_t", "PropName", "type of the info to retrieve", PARAM_IN>,
|
||||
Param<"size_t", "PropSize", "the number of bytes pointed to by PropValue.", PARAM_IN>,
|
||||
TypeTaggedParam<"void*", "PropValue", "array of bytes holding the info. "
|
||||
"If PropSize is not equal to or greater to the real number of bytes needed to return the info "
|
||||
"then the OFFLOAD_ERRC_INVALID_SIZE error is returned and PropValue is not used.", PARAM_OUT,
|
||||
TypeInfo<"PropName" , "PropSize">>
|
||||
];
|
||||
let returns = [];
|
||||
}
|
||||
|
||||
// Check that a tagged enum print function definition is generated
|
||||
// CHECK-PRINT: void printTagged(std::ostream &os, const void *ptr, my_type_tagged_enum_t value, size_t size) {
|
||||
// CHECK-PRINT: case MY_TYPE_TAGGED_ENUM_VALUE_ONE: {
|
||||
// CHECK-PRINT: const uint32_t * const tptr = (const uint32_t * const)ptr;
|
||||
// CHECK-PRINT: os << (const void *)tptr << " (";
|
||||
// CHECK-PRINT: os << *tptr;
|
||||
// CHECK-PRINT: os << ")";
|
||||
// CHECK-PRINT: break;
|
||||
// CHECK-PRINT: }
|
||||
// CHECK-PRINT: case MY_TYPE_TAGGED_ENUM_VALUE_TWO: {
|
||||
// CHECK-PRINT: printPtr(os, (const char*) ptr);
|
||||
// CHECK-PRINT: break;
|
||||
// CHECK-PRINT: }
|
||||
// CHECK-PRINT: case MY_TYPE_TAGGED_ENUM_VALUE_THREE: {
|
||||
// CHECK-PRINT: const some_handle_t * const tptr = (const some_handle_t * const)ptr;
|
||||
// CHECK-PRINT: os << (const void *)tptr << " (";
|
||||
// CHECK-PRINT: os << *tptr;
|
||||
// CHECK-PRINT: os << ")";
|
||||
// CHECK-PRINT: break;
|
||||
// CHECK-PRINT: }
|
||||
|
||||
// Check that the tagged type information is used when printing function parameters
|
||||
// CHECK-PRINT: std::ostream &operator<<(std::ostream &os, const struct function_a_params_t *params) {
|
||||
// CHECK-PRINT: os << ".PropValue = "
|
||||
// CHECK-PRINT-NEXT: printTagged(os, *params->pPropValue, *params->pPropName, *params->pPropSize);
|
@ -1,229 +0,0 @@
|
||||
//===- offload-tblgen/APIGen.cpp - Tablegen backend for Offload header ----===//
|
||||
//
|
||||
// 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 is a Tablegen backend that produces the contents of the Offload API
|
||||
// header. The generated comments are Doxygen compatible.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
#include "llvm/TableGen/Record.h"
|
||||
#include "llvm/TableGen/TableGenBackend.h"
|
||||
|
||||
#include "GenCommon.hpp"
|
||||
#include "RecordTypes.hpp"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace offload::tblgen;
|
||||
|
||||
// Produce a possibly multi-line comment from the input string
|
||||
static std::string MakeComment(StringRef in) {
|
||||
std::string out = "";
|
||||
size_t LineStart = 0;
|
||||
size_t LineBreak = 0;
|
||||
while (LineBreak < in.size()) {
|
||||
LineBreak = in.find_first_of("\n", LineStart);
|
||||
if (LineBreak - LineStart <= 1) {
|
||||
break;
|
||||
}
|
||||
out += std::string("/// ") +
|
||||
in.substr(LineStart, LineBreak - LineStart).str() + "\n";
|
||||
LineStart = LineBreak + 1;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static void ProcessHandle(const HandleRec &H, raw_ostream &OS) {
|
||||
OS << CommentsHeader;
|
||||
OS << formatv("/// @brief {0}\n", H.getDesc());
|
||||
OS << formatv("typedef struct {0}_ *{0};\n", H.getName());
|
||||
}
|
||||
|
||||
static void ProcessTypedef(const TypedefRec &T, raw_ostream &OS) {
|
||||
OS << CommentsHeader;
|
||||
OS << formatv("/// @brief {0}\n", T.getDesc());
|
||||
OS << formatv("typedef {0} {1};\n", T.getValue(), T.getName());
|
||||
}
|
||||
|
||||
static void ProcessMacro(const MacroRec &M, raw_ostream &OS) {
|
||||
OS << CommentsHeader;
|
||||
OS << formatv("#ifndef {0}\n", M.getName());
|
||||
if (auto Condition = M.getCondition()) {
|
||||
OS << formatv("#if {0}\n", *Condition);
|
||||
}
|
||||
OS << "/// @brief " << M.getDesc() << "\n";
|
||||
OS << formatv("#define {0} {1}\n", M.getNameWithArgs(), M.getValue());
|
||||
if (auto AltValue = M.getAltValue()) {
|
||||
OS << "#else\n";
|
||||
OS << formatv("#define {0} {1}\n", M.getNameWithArgs(), *AltValue);
|
||||
}
|
||||
if (auto Condition = M.getCondition()) {
|
||||
OS << formatv("#endif // {0}\n", *Condition);
|
||||
}
|
||||
OS << formatv("#endif // {0}\n", M.getName());
|
||||
}
|
||||
|
||||
static void ProcessFunction(const FunctionRec &F, raw_ostream &OS) {
|
||||
OS << CommentsHeader;
|
||||
OS << formatv("/// @brief {0}\n", F.getDesc());
|
||||
OS << CommentsBreak;
|
||||
|
||||
OS << "/// @details\n";
|
||||
for (auto &Detail : F.getDetails()) {
|
||||
OS << formatv("/// - {0}\n", Detail);
|
||||
}
|
||||
OS << CommentsBreak;
|
||||
|
||||
// Emit analogue remarks
|
||||
auto Analogues = F.getAnalogues();
|
||||
if (!Analogues.empty()) {
|
||||
OS << "/// @remarks\n/// _Analogues_\n";
|
||||
for (auto &Analogue : Analogues) {
|
||||
OS << formatv("/// - **{0}**\n", Analogue);
|
||||
}
|
||||
OS << CommentsBreak;
|
||||
}
|
||||
|
||||
OS << "/// @returns\n";
|
||||
auto Returns = F.getReturns();
|
||||
for (auto &Ret : Returns) {
|
||||
OS << formatv("/// - ::{0}\n", Ret.getValue());
|
||||
auto RetConditions = Ret.getConditions();
|
||||
for (auto &RetCondition : RetConditions) {
|
||||
OS << formatv("/// + {0}\n", RetCondition);
|
||||
}
|
||||
}
|
||||
|
||||
OS << formatv("{0}_APIEXPORT {1}_result_t {0}_APICALL ", PrefixUpper,
|
||||
PrefixLower);
|
||||
OS << F.getName();
|
||||
OS << "(\n";
|
||||
auto Params = F.getParams();
|
||||
for (auto &Param : Params) {
|
||||
OS << MakeParamComment(Param) << "\n";
|
||||
OS << " " << Param.getType() << " " << Param.getName();
|
||||
if (Param != Params.back()) {
|
||||
OS << ",\n";
|
||||
} else {
|
||||
OS << "\n";
|
||||
}
|
||||
}
|
||||
OS << ");\n\n";
|
||||
}
|
||||
|
||||
static void ProcessEnum(const EnumRec &Enum, raw_ostream &OS) {
|
||||
OS << CommentsHeader;
|
||||
OS << formatv("/// @brief {0}\n", Enum.getDesc());
|
||||
OS << formatv("typedef enum {0} {{\n", Enum.getName());
|
||||
|
||||
uint32_t EtorVal = 0;
|
||||
for (const auto &EnumVal : Enum.getValues()) {
|
||||
if (Enum.isTyped()) {
|
||||
OS << MakeComment(
|
||||
formatv("[{0}] {1}", EnumVal.getTaggedType(), EnumVal.getDesc())
|
||||
.str());
|
||||
} else {
|
||||
OS << MakeComment(EnumVal.getDesc());
|
||||
}
|
||||
OS << formatv(TAB_1 "{0}_{1} = {2},\n", Enum.getEnumValNamePrefix(),
|
||||
EnumVal.getName(), EtorVal++);
|
||||
}
|
||||
|
||||
// Add force uint32 val
|
||||
OS << formatv(TAB_1 "/// @cond\n" TAB_1
|
||||
"{0}_FORCE_UINT32 = 0x7fffffff\n" TAB_1
|
||||
"/// @endcond\n\n",
|
||||
Enum.getEnumValNamePrefix());
|
||||
|
||||
OS << formatv("} {0};\n", Enum.getName());
|
||||
}
|
||||
|
||||
static void ProcessStruct(const StructRec &Struct, raw_ostream &OS) {
|
||||
OS << CommentsHeader;
|
||||
OS << formatv("/// @brief {0}\n", Struct.getDesc());
|
||||
OS << formatv("typedef struct {0} {{\n", Struct.getName());
|
||||
|
||||
for (const auto &Member : Struct.getMembers()) {
|
||||
OS << formatv(TAB_1 "{0} {1}; {2}", Member.getType(), Member.getName(),
|
||||
MakeComment(Member.getDesc()));
|
||||
}
|
||||
|
||||
OS << formatv("} {0};\n\n", Struct.getName());
|
||||
}
|
||||
|
||||
static void ProcessFuncParamStruct(const FunctionRec &Func, raw_ostream &OS) {
|
||||
if (Func.getParams().size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto FuncParamStructBegin = R"(
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Function parameters for {0}
|
||||
/// @details Each entry is a pointer to the parameter passed to the function;
|
||||
typedef struct {1} {{
|
||||
)";
|
||||
|
||||
OS << formatv(FuncParamStructBegin, Func.getName(),
|
||||
Func.getParamStructName());
|
||||
for (const auto &Param : Func.getParams()) {
|
||||
OS << TAB_1 << Param.getType() << "* p" << Param.getName() << ";\n";
|
||||
}
|
||||
OS << formatv("} {0};\n", Func.getParamStructName());
|
||||
}
|
||||
|
||||
static void ProcessFuncWithCodeLocVariant(const FunctionRec &Func,
|
||||
raw_ostream &OS) {
|
||||
|
||||
auto FuncWithCodeLocBegin = R"(
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Variant of {0} that also sets source code location information
|
||||
/// @details See also ::{0}
|
||||
OL_APIEXPORT ol_result_t OL_APICALL {0}WithCodeLoc(
|
||||
)";
|
||||
OS << formatv(FuncWithCodeLocBegin, Func.getName());
|
||||
auto Params = Func.getParams();
|
||||
for (auto &Param : Params) {
|
||||
OS << " " << Param.getType() << " " << Param.getName();
|
||||
OS << ",\n";
|
||||
}
|
||||
OS << "ol_code_location_t *CodeLocation);\n\n";
|
||||
}
|
||||
|
||||
void EmitOffloadAPI(const RecordKeeper &Records, raw_ostream &OS) {
|
||||
OS << GenericHeader;
|
||||
OS << FileHeader;
|
||||
// Generate main API definitions
|
||||
for (auto *R : Records.getAllDerivedDefinitions("APIObject")) {
|
||||
if (R->isSubClassOf("Macro")) {
|
||||
ProcessMacro(MacroRec{R}, OS);
|
||||
} else if (R->isSubClassOf("Typedef")) {
|
||||
ProcessTypedef(TypedefRec{R}, OS);
|
||||
} else if (R->isSubClassOf("Handle")) {
|
||||
ProcessHandle(HandleRec{R}, OS);
|
||||
} else if (R->isSubClassOf("Function")) {
|
||||
ProcessFunction(FunctionRec{R}, OS);
|
||||
} else if (R->isSubClassOf("Enum")) {
|
||||
ProcessEnum(EnumRec{R}, OS);
|
||||
} else if (R->isSubClassOf("Struct")) {
|
||||
ProcessStruct(StructRec{R}, OS);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate auxiliary definitions (func param structs etc)
|
||||
for (auto *R : Records.getAllDerivedDefinitions("Function")) {
|
||||
ProcessFuncParamStruct(FunctionRec{R}, OS);
|
||||
}
|
||||
|
||||
for (auto *R : Records.getAllDerivedDefinitions("Function")) {
|
||||
ProcessFuncWithCodeLocVariant(FunctionRec{R}, OS);
|
||||
}
|
||||
|
||||
OS << FileFooter;
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
##===----------------------------------------------------------------------===##
|
||||
#
|
||||
# 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
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
include(TableGen)
|
||||
|
||||
add_tablegen(offload-tblgen OFFLOAD
|
||||
EXPORT OFFLOAD
|
||||
APIGen.cpp
|
||||
EntryPointGen.cpp
|
||||
FuncsGen.cpp
|
||||
GenCommon.hpp
|
||||
Generators.hpp
|
||||
offload-tblgen.cpp
|
||||
PrintGen.cpp
|
||||
RecordTypes.hpp
|
||||
)
|
||||
|
||||
set(OFFLOAD_TABLEGEN_EXE "${OFFLOAD_TABLEGEN_EXE}" CACHE INTERNAL "")
|
||||
set(OFFLOAD_TABLEGEN_TARGET "${OFFLOAD_TABLEGEN_TARGET}" CACHE INTERNAL "")
|
||||
|
@ -1,138 +0,0 @@
|
||||
//===- offload-tblgen/EntryPointGen.cpp - Tablegen backend for Offload ----===//
|
||||
//
|
||||
// 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 is a Tablegen backend that produces the actual entry points for the
|
||||
// Offload API. It serves as a place to integrate functionality like tracing
|
||||
// and validation before dispatching to the actual implementations.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
#include "llvm/TableGen/Record.h"
|
||||
|
||||
#include "GenCommon.hpp"
|
||||
#include "RecordTypes.hpp"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace offload::tblgen;
|
||||
|
||||
static void EmitValidationFunc(const FunctionRec &F, raw_ostream &OS) {
|
||||
OS << CommentsHeader;
|
||||
// Emit preamble
|
||||
OS << formatv("{0}_impl_result_t {1}_val(\n ", PrefixLower, F.getName());
|
||||
// Emit arguments
|
||||
std::string ParamNameList = "";
|
||||
for (auto &Param : F.getParams()) {
|
||||
OS << Param.getType() << " " << Param.getName();
|
||||
if (Param != F.getParams().back()) {
|
||||
OS << ", ";
|
||||
}
|
||||
ParamNameList += Param.getName().str() + ", ";
|
||||
}
|
||||
OS << ") {\n";
|
||||
|
||||
OS << TAB_1 "if (true /*enableParameterValidation*/) {\n";
|
||||
// Emit validation checks
|
||||
for (const auto &Return : F.getReturns()) {
|
||||
for (auto &Condition : Return.getConditions()) {
|
||||
if (Condition.starts_with("`") && Condition.ends_with("`")) {
|
||||
auto ConditionString = Condition.substr(1, Condition.size() - 2);
|
||||
OS << formatv(TAB_2 "if ({0}) {{\n", ConditionString);
|
||||
OS << formatv(TAB_3 "return {0};\n", Return.getValue());
|
||||
OS << TAB_2 "}\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
OS << TAB_1 "}\n\n";
|
||||
|
||||
// Perform actual function call to the implementation
|
||||
ParamNameList = ParamNameList.substr(0, ParamNameList.size() - 2);
|
||||
OS << formatv(TAB_1 "return {0}_impl({1});\n\n", F.getName(), ParamNameList);
|
||||
OS << "}\n";
|
||||
}
|
||||
|
||||
static void EmitEntryPointFunc(const FunctionRec &F, raw_ostream &OS) {
|
||||
// Emit preamble
|
||||
OS << formatv("{1}_APIEXPORT {0}_result_t {1}_APICALL {2}(\n ", PrefixLower,
|
||||
PrefixUpper, F.getName());
|
||||
// Emit arguments
|
||||
std::string ParamNameList = "";
|
||||
for (auto &Param : F.getParams()) {
|
||||
OS << Param.getType() << " " << Param.getName();
|
||||
if (Param != F.getParams().back()) {
|
||||
OS << ", ";
|
||||
}
|
||||
ParamNameList += Param.getName().str() + ", ";
|
||||
}
|
||||
OS << ") {\n";
|
||||
|
||||
// Emit pre-call prints
|
||||
OS << TAB_1 "if (offloadConfig().TracingEnabled) {\n";
|
||||
OS << formatv(TAB_2 "std::cout << \"---> {0}\";\n", F.getName());
|
||||
OS << TAB_1 "}\n\n";
|
||||
|
||||
// Perform actual function call to the validation wrapper
|
||||
ParamNameList = ParamNameList.substr(0, ParamNameList.size() - 2);
|
||||
OS << formatv(TAB_1 "{0}_result_t Result = {1}_val({2});\n\n", PrefixLower,
|
||||
F.getName(), ParamNameList);
|
||||
|
||||
// Emit post-call prints
|
||||
OS << TAB_1 "if (offloadConfig().TracingEnabled) {\n";
|
||||
if (F.getParams().size() > 0) {
|
||||
OS << formatv(TAB_2 "{0} Params = {{", F.getParamStructName());
|
||||
for (const auto &Param : F.getParams()) {
|
||||
OS << "&" << Param.getName();
|
||||
if (Param != F.getParams().back()) {
|
||||
OS << ", ";
|
||||
}
|
||||
}
|
||||
OS << formatv("};\n");
|
||||
OS << TAB_2 "std::cout << \"(\" << &Params << \")\";\n";
|
||||
} else {
|
||||
OS << TAB_2 "std::cout << \"()\";\n";
|
||||
}
|
||||
OS << TAB_2 "std::cout << \"-> \" << Result << \"\\n\";\n";
|
||||
OS << TAB_2 "if (Result && Result->Details) {\n";
|
||||
OS << TAB_3 "std::cout << \" *Error Details* \" << Result->Details "
|
||||
"<< \" \\n\";\n";
|
||||
OS << TAB_2 "}\n";
|
||||
OS << TAB_1 "}\n";
|
||||
|
||||
OS << TAB_1 "return Result;\n";
|
||||
OS << "}\n";
|
||||
}
|
||||
|
||||
static void EmitCodeLocWrapper(const FunctionRec &F, raw_ostream &OS) {
|
||||
// Emit preamble
|
||||
OS << formatv("{0}_result_t {1}WithCodeLoc(\n ", PrefixLower, F.getName());
|
||||
// Emit arguments
|
||||
std::string ParamNameList = "";
|
||||
for (auto &Param : F.getParams()) {
|
||||
OS << Param.getType() << " " << Param.getName() << ", ";
|
||||
ParamNameList += Param.getName().str();
|
||||
if (Param != F.getParams().back()) {
|
||||
ParamNameList += ", ";
|
||||
}
|
||||
}
|
||||
OS << "ol_code_location_t *CodeLocation";
|
||||
OS << ") {\n";
|
||||
OS << TAB_1 "currentCodeLocation() = CodeLocation;\n";
|
||||
OS << formatv(TAB_1 "{0}_result_t Result = {1}({2});\n\n", PrefixLower,
|
||||
F.getName(), ParamNameList);
|
||||
OS << TAB_1 "currentCodeLocation() = nullptr;\n";
|
||||
OS << TAB_1 "return Result;\n";
|
||||
OS << "}\n";
|
||||
}
|
||||
|
||||
void EmitOffloadEntryPoints(const RecordKeeper &Records, raw_ostream &OS) {
|
||||
OS << GenericHeader;
|
||||
for (auto *R : Records.getAllDerivedDefinitions("Function")) {
|
||||
EmitValidationFunc(FunctionRec{R}, OS);
|
||||
EmitEntryPointFunc(FunctionRec{R}, OS);
|
||||
EmitCodeLocWrapper(FunctionRec{R}, OS);
|
||||
}
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
//===- offload-tblgen/APIGen.cpp - Tablegen backend for Offload functions -===//
|
||||
//
|
||||
// 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 is a Tablegen backend that handles generation of various small files
|
||||
// pertaining to the API functions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
#include "llvm/TableGen/Record.h"
|
||||
|
||||
#include "GenCommon.hpp"
|
||||
#include "RecordTypes.hpp"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace offload::tblgen;
|
||||
|
||||
// Emit a list of just the API function names
|
||||
void EmitOffloadFuncNames(const RecordKeeper &Records, raw_ostream &OS) {
|
||||
OS << GenericHeader;
|
||||
OS << R"(
|
||||
#ifndef OFFLOAD_FUNC
|
||||
#error Please define the macro OFFLOAD_FUNC(Function)
|
||||
#endif
|
||||
|
||||
)";
|
||||
for (auto *R : Records.getAllDerivedDefinitions("Function")) {
|
||||
FunctionRec FR{R};
|
||||
OS << formatv("OFFLOAD_FUNC({0})", FR.getName()) << "\n";
|
||||
}
|
||||
for (auto *R : Records.getAllDerivedDefinitions("Function")) {
|
||||
FunctionRec FR{R};
|
||||
OS << formatv("OFFLOAD_FUNC({0}WithCodeLoc)", FR.getName()) << "\n";
|
||||
}
|
||||
|
||||
OS << "\n#undef OFFLOAD_FUNC\n";
|
||||
}
|
||||
|
||||
void EmitOffloadExports(const RecordKeeper &Records, raw_ostream &OS) {
|
||||
OS << "VERS1.0 {\n";
|
||||
OS << TAB_1 "global:\n";
|
||||
|
||||
for (auto *R : Records.getAllDerivedDefinitions("Function")) {
|
||||
OS << formatv(TAB_2 "{0};\n", FunctionRec(R).getName());
|
||||
}
|
||||
for (auto *R : Records.getAllDerivedDefinitions("Function")) {
|
||||
OS << formatv(TAB_2 "{0}WithCodeLoc;\n", FunctionRec(R).getName());
|
||||
}
|
||||
OS << TAB_1 "local:\n";
|
||||
OS << TAB_2 "*;\n";
|
||||
OS << "};\n";
|
||||
}
|
||||
|
||||
// Emit declarations for every implementation function
|
||||
void EmitOffloadImplFuncDecls(const RecordKeeper &Records, raw_ostream &OS) {
|
||||
OS << GenericHeader;
|
||||
for (auto *R : Records.getAllDerivedDefinitions("Function")) {
|
||||
FunctionRec F{R};
|
||||
OS << formatv("{0}_impl_result_t {1}_impl(", PrefixLower, F.getName());
|
||||
auto Params = F.getParams();
|
||||
for (auto &Param : Params) {
|
||||
OS << Param.getType() << " " << Param.getName();
|
||||
if (Param != Params.back()) {
|
||||
OS << ", ";
|
||||
}
|
||||
}
|
||||
OS << ");\n\n";
|
||||
}
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
//===- offload-tblgen/GenCommon.cpp - Common defs for Offload generators --===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RecordTypes.hpp"
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
|
||||
// Having inline bits of tabbed code is hard to read, provide some definitions
|
||||
// so we can keep things tidier
|
||||
#define TAB_1 " "
|
||||
#define TAB_2 " "
|
||||
#define TAB_3 " "
|
||||
#define TAB_4 " "
|
||||
#define TAB_5 " "
|
||||
|
||||
constexpr auto GenericHeader =
|
||||
R"(//===- Auto-generated file, part of the LLVM/Offload project --------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
)";
|
||||
|
||||
constexpr auto FileHeader = R"(
|
||||
// Auto-generated file, do not manually edit.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
)";
|
||||
|
||||
constexpr auto FileFooter = R"(
|
||||
#if defined(__cplusplus)
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
)";
|
||||
|
||||
constexpr auto CommentsHeader = R"(
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
)";
|
||||
|
||||
constexpr auto CommentsBreak = "///\n";
|
||||
|
||||
constexpr auto PrefixLower = "ol";
|
||||
constexpr auto PrefixUpper = "OL";
|
||||
|
||||
inline std::string
|
||||
MakeParamComment(const llvm::offload::tblgen::ParamRec &Param) {
|
||||
return llvm::formatv("// {0}{1}{2} {3}", (Param.isIn() ? "[in]" : ""),
|
||||
(Param.isOut() ? "[out]" : ""),
|
||||
(Param.isOpt() ? "[optional]" : ""), Param.getDesc());
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
//===- offload-tblgen/Generators.hpp - Offload generator declarations -----===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "llvm/TableGen/Record.h"
|
||||
|
||||
void EmitOffloadAPI(const llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
|
||||
void EmitOffloadFuncNames(const llvm::RecordKeeper &Records,
|
||||
llvm::raw_ostream &OS);
|
||||
void EmitOffloadImplFuncDecls(const llvm::RecordKeeper &Records,
|
||||
llvm::raw_ostream &OS);
|
||||
void EmitOffloadEntryPoints(const llvm::RecordKeeper &Records,
|
||||
llvm::raw_ostream &OS);
|
||||
void EmitOffloadPrintHeader(const llvm::RecordKeeper &Records,
|
||||
llvm::raw_ostream &OS);
|
||||
void EmitOffloadExports(const llvm::RecordKeeper &Records,
|
||||
llvm::raw_ostream &OS);
|
@ -1,226 +0,0 @@
|
||||
//===- offload-tblgen/APIGen.cpp - Tablegen backend for Offload printing --===//
|
||||
//
|
||||
// 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 is a Tablegen backend that produces print functions for the Offload API
|
||||
// entry point functions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
#include "llvm/TableGen/Record.h"
|
||||
|
||||
#include "GenCommon.hpp"
|
||||
#include "RecordTypes.hpp"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace offload::tblgen;
|
||||
|
||||
constexpr auto PrintEnumHeader =
|
||||
R"(///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Print operator for the {0} type
|
||||
/// @returns std::ostream &
|
||||
)";
|
||||
|
||||
constexpr auto PrintTaggedEnumHeader =
|
||||
R"(///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Print type-tagged {0} enum value
|
||||
/// @returns std::ostream &
|
||||
)";
|
||||
|
||||
static void ProcessEnum(const EnumRec &Enum, raw_ostream &OS) {
|
||||
OS << formatv(PrintEnumHeader, Enum.getName());
|
||||
OS << formatv(
|
||||
"inline std::ostream &operator<<(std::ostream &os, enum {0} value) "
|
||||
"{{\n" TAB_1 "switch (value) {{\n",
|
||||
Enum.getName());
|
||||
|
||||
for (const auto &Val : Enum.getValues()) {
|
||||
auto Name = Enum.getEnumValNamePrefix() + "_" + Val.getName();
|
||||
OS << formatv(TAB_1 "case {0}:\n", Name);
|
||||
OS << formatv(TAB_2 "os << \"{0}\";\n", Name);
|
||||
OS << formatv(TAB_2 "break;\n");
|
||||
}
|
||||
|
||||
OS << TAB_1 "default:\n" TAB_2 "os << \"unknown enumerator\";\n" TAB_2
|
||||
"break;\n" TAB_1 "}\n" TAB_1 "return os;\n}\n\n";
|
||||
|
||||
if (!Enum.isTyped()) {
|
||||
return;
|
||||
}
|
||||
|
||||
OS << formatv(PrintTaggedEnumHeader, Enum.getName());
|
||||
|
||||
OS << formatv(R"""(template <>
|
||||
inline void printTagged(std::ostream &os, const void *ptr, {0} value, size_t size) {{
|
||||
if (ptr == NULL) {{
|
||||
printPtr(os, ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (value) {{
|
||||
)""",
|
||||
Enum.getName());
|
||||
|
||||
for (const auto &Val : Enum.getValues()) {
|
||||
auto Name = Enum.getEnumValNamePrefix() + "_" + Val.getName();
|
||||
auto Type = Val.getTaggedType();
|
||||
OS << formatv(TAB_1 "case {0}: {{\n", Name);
|
||||
// Special case for strings
|
||||
if (Type == "char[]") {
|
||||
OS << formatv(TAB_2 "printPtr(os, (const char*) ptr);\n");
|
||||
} else {
|
||||
OS << formatv(TAB_2 "const {0} * const tptr = (const {0} * const)ptr;\n",
|
||||
Type);
|
||||
// TODO: Handle other cases here
|
||||
OS << TAB_2 "os << (const void *)tptr << \" (\";\n";
|
||||
if (Type.ends_with("*")) {
|
||||
OS << TAB_2 "os << printPtr(os, tptr);\n";
|
||||
} else {
|
||||
OS << TAB_2 "os << *tptr;\n";
|
||||
}
|
||||
OS << TAB_2 "os << \")\";\n";
|
||||
}
|
||||
OS << formatv(TAB_2 "break;\n" TAB_1 "}\n");
|
||||
}
|
||||
|
||||
OS << TAB_1 "default:\n" TAB_2 "os << \"unknown enumerator\";\n" TAB_2
|
||||
"break;\n" TAB_1 "}\n";
|
||||
|
||||
OS << "}\n";
|
||||
}
|
||||
|
||||
static void EmitResultPrint(raw_ostream &OS) {
|
||||
OS << R""(
|
||||
inline std::ostream &operator<<(std::ostream &os,
|
||||
const ol_error_struct_t *Err) {
|
||||
if (Err == nullptr) {
|
||||
os << "OL_SUCCESS";
|
||||
} else {
|
||||
os << Err->Code;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
)"";
|
||||
}
|
||||
|
||||
static void EmitFunctionParamStructPrint(const FunctionRec &Func,
|
||||
raw_ostream &OS) {
|
||||
if (Func.getParams().size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
OS << formatv(R"(
|
||||
inline std::ostream &operator<<(std::ostream &os, const struct {0} *params) {{
|
||||
)",
|
||||
Func.getParamStructName());
|
||||
|
||||
for (const auto &Param : Func.getParams()) {
|
||||
OS << formatv(TAB_1 "os << \".{0} = \";\n", Param.getName());
|
||||
if (auto Range = Param.getRange()) {
|
||||
OS << formatv(TAB_1 "os << \"{{\";\n");
|
||||
OS << formatv(TAB_1 "for (size_t i = {0}; i < *params->p{1}; i++) {{\n",
|
||||
Range->first, Range->second);
|
||||
OS << TAB_2 "if (i > 0) {\n";
|
||||
OS << TAB_3 " os << \", \";\n";
|
||||
OS << TAB_2 "}\n";
|
||||
OS << formatv(TAB_2 "printPtr(os, (*params->p{0})[i]);\n",
|
||||
Param.getName());
|
||||
OS << formatv(TAB_1 "}\n");
|
||||
OS << formatv(TAB_1 "os << \"}\";\n");
|
||||
} else if (auto TypeInfo = Param.getTypeInfo()) {
|
||||
OS << formatv(
|
||||
TAB_1
|
||||
"printTagged(os, *params->p{0}, *params->p{1}, *params->p{2});\n",
|
||||
Param.getName(), TypeInfo->first, TypeInfo->second);
|
||||
} else if (Param.isPointerType() || Param.isHandleType()) {
|
||||
OS << formatv(TAB_1 "printPtr(os, *params->p{0});\n", Param.getName());
|
||||
} else {
|
||||
OS << formatv(TAB_1 "os << *params->p{0};\n", Param.getName());
|
||||
}
|
||||
if (Param != Func.getParams().back()) {
|
||||
OS << TAB_1 "os << \", \";\n";
|
||||
}
|
||||
}
|
||||
|
||||
OS << TAB_1 "return os;\n}\n";
|
||||
}
|
||||
|
||||
void EmitOffloadPrintHeader(const RecordKeeper &Records, raw_ostream &OS) {
|
||||
OS << GenericHeader;
|
||||
OS << R"""(
|
||||
// Auto-generated file, do not manually edit.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <OffloadAPI.h>
|
||||
#include <ostream>
|
||||
|
||||
|
||||
template <typename T> inline ol_result_t printPtr(std::ostream &os, const T *ptr);
|
||||
template <typename T> inline void printTagged(std::ostream &os, const void *ptr, T value, size_t size);
|
||||
)""";
|
||||
|
||||
// ==========
|
||||
OS << "template <typename T> struct is_handle : std::false_type {};\n";
|
||||
for (auto *R : Records.getAllDerivedDefinitions("Handle")) {
|
||||
HandleRec H{R};
|
||||
OS << formatv("template <> struct is_handle<{0}> : std::true_type {{};\n",
|
||||
H.getName());
|
||||
}
|
||||
OS << "template <typename T> inline constexpr bool is_handle_v = "
|
||||
"is_handle<T>::value;\n";
|
||||
// =========
|
||||
|
||||
// Forward declare the operator<< overloads so their implementations can
|
||||
// use each other.
|
||||
OS << "\n";
|
||||
for (auto *R : Records.getAllDerivedDefinitions("Enum")) {
|
||||
OS << formatv(
|
||||
"inline std::ostream &operator<<(std::ostream &os, enum {0} value);\n",
|
||||
EnumRec{R}.getName());
|
||||
}
|
||||
OS << "\n";
|
||||
|
||||
// Create definitions
|
||||
for (auto *R : Records.getAllDerivedDefinitions("Enum")) {
|
||||
EnumRec E{R};
|
||||
ProcessEnum(E, OS);
|
||||
}
|
||||
EmitResultPrint(OS);
|
||||
|
||||
// Emit print functions for the function param structs
|
||||
for (auto *R : Records.getAllDerivedDefinitions("Function")) {
|
||||
EmitFunctionParamStructPrint(FunctionRec{R}, OS);
|
||||
}
|
||||
|
||||
OS << R"""(
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// @brief Print pointer value
|
||||
template <typename T> inline ol_result_t printPtr(std::ostream &os, const T *ptr) {
|
||||
if (ptr == nullptr) {
|
||||
os << "nullptr";
|
||||
} else if constexpr (std::is_pointer_v<T>) {
|
||||
os << (const void *)(ptr) << " (";
|
||||
printPtr(os, *ptr);
|
||||
os << ")";
|
||||
} else if constexpr (std::is_void_v<T> || is_handle_v<T *>) {
|
||||
os << (const void *)ptr;
|
||||
} else if constexpr (std::is_same_v<std::remove_cv_t< T >, char>) {
|
||||
os << (const void *)(ptr) << " (";
|
||||
os << ptr;
|
||||
os << ")";
|
||||
} else {
|
||||
os << (const void *)(ptr) << " (";
|
||||
os << *ptr;
|
||||
os << ")";
|
||||
}
|
||||
|
||||
return OL_SUCCESS;
|
||||
}
|
||||
)""";
|
||||
}
|
@ -1,227 +0,0 @@
|
||||
//===- offload-tblgen/RecordTypes.cpp - Offload record type wrappers -----===-//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "llvm/TableGen/Record.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace offload {
|
||||
namespace tblgen {
|
||||
|
||||
class HandleRec {
|
||||
public:
|
||||
explicit HandleRec(const Record *rec) : rec(rec) {}
|
||||
StringRef getName() const { return rec->getValueAsString("name"); }
|
||||
StringRef getDesc() const { return rec->getValueAsString("desc"); }
|
||||
|
||||
private:
|
||||
const Record *rec;
|
||||
};
|
||||
|
||||
class MacroRec {
|
||||
public:
|
||||
explicit MacroRec(const Record *rec) : rec(rec) {
|
||||
auto Name = rec->getValueAsString("name");
|
||||
auto OpenBrace = Name.find_first_of("(");
|
||||
nameWithoutArgs = Name.substr(0, OpenBrace);
|
||||
}
|
||||
StringRef getName() const { return nameWithoutArgs; }
|
||||
StringRef getNameWithArgs() const { return rec->getValueAsString("name"); }
|
||||
StringRef getDesc() const { return rec->getValueAsString("desc"); }
|
||||
|
||||
std::optional<StringRef> getCondition() const {
|
||||
return rec->getValueAsOptionalString("condition");
|
||||
}
|
||||
StringRef getValue() const { return rec->getValueAsString("value"); }
|
||||
std::optional<StringRef> getAltValue() const {
|
||||
return rec->getValueAsOptionalString("alt_value");
|
||||
}
|
||||
|
||||
private:
|
||||
const Record *rec;
|
||||
std::string nameWithoutArgs;
|
||||
};
|
||||
|
||||
class TypedefRec {
|
||||
public:
|
||||
explicit TypedefRec(const Record *rec) : rec(rec) {}
|
||||
StringRef getName() const { return rec->getValueAsString("name"); }
|
||||
StringRef getDesc() const { return rec->getValueAsString("desc"); }
|
||||
StringRef getValue() const { return rec->getValueAsString("value"); }
|
||||
|
||||
private:
|
||||
const Record *rec;
|
||||
};
|
||||
|
||||
class EnumValueRec {
|
||||
public:
|
||||
explicit EnumValueRec(const Record *rec) : rec(rec) {}
|
||||
std::string getName() const { return rec->getValueAsString("name").upper(); }
|
||||
StringRef getDesc() const { return rec->getValueAsString("desc"); }
|
||||
StringRef getTaggedType() const {
|
||||
return rec->getValueAsString("tagged_type");
|
||||
}
|
||||
|
||||
private:
|
||||
const Record *rec;
|
||||
};
|
||||
|
||||
class EnumRec {
|
||||
public:
|
||||
explicit EnumRec(const Record *rec) : rec(rec) {
|
||||
for (const auto *Val : rec->getValueAsListOfDefs("etors")) {
|
||||
vals.emplace_back(EnumValueRec{Val});
|
||||
}
|
||||
}
|
||||
StringRef getName() const { return rec->getValueAsString("name"); }
|
||||
StringRef getDesc() const { return rec->getValueAsString("desc"); }
|
||||
const std::vector<EnumValueRec> &getValues() const { return vals; }
|
||||
|
||||
std::string getEnumValNamePrefix() const {
|
||||
return StringRef(getName().str().substr(0, getName().str().length() - 2))
|
||||
.upper();
|
||||
}
|
||||
|
||||
bool isTyped() const { return rec->getValueAsBit("is_typed"); }
|
||||
|
||||
private:
|
||||
const Record *rec;
|
||||
std::vector<EnumValueRec> vals;
|
||||
};
|
||||
|
||||
class StructMemberRec {
|
||||
public:
|
||||
explicit StructMemberRec(const Record *rec) : rec(rec) {}
|
||||
StringRef getType() const { return rec->getValueAsString("type"); }
|
||||
StringRef getName() const { return rec->getValueAsString("name"); }
|
||||
StringRef getDesc() const { return rec->getValueAsString("desc"); }
|
||||
|
||||
private:
|
||||
const Record *rec;
|
||||
};
|
||||
|
||||
class StructRec {
|
||||
public:
|
||||
explicit StructRec(const Record *rec) : rec(rec) {
|
||||
for (auto *Member : rec->getValueAsListOfDefs("all_members")) {
|
||||
members.emplace_back(StructMemberRec(Member));
|
||||
}
|
||||
}
|
||||
StringRef getName() const { return rec->getValueAsString("name"); }
|
||||
StringRef getDesc() const { return rec->getValueAsString("desc"); }
|
||||
std::optional<StringRef> getBaseClass() const {
|
||||
return rec->getValueAsOptionalString("base_class");
|
||||
}
|
||||
const std::vector<StructMemberRec> &getMembers() const { return members; }
|
||||
|
||||
private:
|
||||
const Record *rec;
|
||||
std::vector<StructMemberRec> members;
|
||||
};
|
||||
|
||||
class ParamRec {
|
||||
public:
|
||||
explicit ParamRec(const Record *rec) : rec(rec) {
|
||||
flags = rec->getValueAsBitsInit("flags");
|
||||
auto *Range = rec->getValueAsDef("range");
|
||||
auto RangeBegin = Range->getValueAsString("begin");
|
||||
auto RangeEnd = Range->getValueAsString("end");
|
||||
if (RangeBegin != "" && RangeEnd != "") {
|
||||
range = {RangeBegin, RangeEnd};
|
||||
} else {
|
||||
range = std::nullopt;
|
||||
}
|
||||
|
||||
auto *TypeInfo = rec->getValueAsDef("type_info");
|
||||
auto TypeInfoEnum = TypeInfo->getValueAsString("enum");
|
||||
auto TypeInfoSize = TypeInfo->getValueAsString("size");
|
||||
if (TypeInfoEnum != "" && TypeInfoSize != "") {
|
||||
typeinfo = {TypeInfoEnum, TypeInfoSize};
|
||||
} else {
|
||||
typeinfo = std::nullopt;
|
||||
}
|
||||
}
|
||||
StringRef getName() const { return rec->getValueAsString("name"); }
|
||||
StringRef getType() const { return rec->getValueAsString("type"); }
|
||||
bool isPointerType() const { return getType().ends_with('*'); }
|
||||
bool isHandleType() const { return getType().ends_with("_handle_t"); }
|
||||
StringRef getDesc() const { return rec->getValueAsString("desc"); }
|
||||
bool isIn() const { return dyn_cast<BitInit>(flags->getBit(0))->getValue(); }
|
||||
bool isOut() const { return dyn_cast<BitInit>(flags->getBit(1))->getValue(); }
|
||||
bool isOpt() const { return dyn_cast<BitInit>(flags->getBit(2))->getValue(); }
|
||||
|
||||
const Record *getRec() const { return rec; }
|
||||
std::optional<std::pair<StringRef, StringRef>> getRange() const {
|
||||
return range;
|
||||
}
|
||||
|
||||
std::optional<std::pair<StringRef, StringRef>> getTypeInfo() const {
|
||||
return typeinfo;
|
||||
}
|
||||
|
||||
// Needed to check whether we're at the back of a vector of params
|
||||
bool operator!=(const ParamRec &p) const { return rec != p.getRec(); }
|
||||
|
||||
private:
|
||||
const Record *rec;
|
||||
const BitsInit *flags;
|
||||
std::optional<std::pair<StringRef, StringRef>> range;
|
||||
std::optional<std::pair<StringRef, StringRef>> typeinfo;
|
||||
};
|
||||
|
||||
class ReturnRec {
|
||||
public:
|
||||
ReturnRec(const Record *rec) : rec(rec) {}
|
||||
StringRef getValue() const { return rec->getValueAsString("value"); }
|
||||
std::vector<StringRef> getConditions() const {
|
||||
return rec->getValueAsListOfStrings("conditions");
|
||||
}
|
||||
|
||||
private:
|
||||
const Record *rec;
|
||||
};
|
||||
|
||||
class FunctionRec {
|
||||
public:
|
||||
FunctionRec(const Record *rec) : rec(rec) {
|
||||
for (auto &Ret : rec->getValueAsListOfDefs("all_returns"))
|
||||
rets.emplace_back(Ret);
|
||||
for (auto &Param : rec->getValueAsListOfDefs("params"))
|
||||
params.emplace_back(Param);
|
||||
}
|
||||
|
||||
std::string getParamStructName() const {
|
||||
return llvm::formatv("{0}_params_t",
|
||||
llvm::convertToSnakeFromCamelCase(getName()));
|
||||
}
|
||||
|
||||
StringRef getName() const { return rec->getValueAsString("name"); }
|
||||
StringRef getClass() const { return rec->getValueAsString("api_class"); }
|
||||
const std::vector<ReturnRec> &getReturns() const { return rets; }
|
||||
const std::vector<ParamRec> &getParams() const { return params; }
|
||||
StringRef getDesc() const { return rec->getValueAsString("desc"); }
|
||||
std::vector<StringRef> getDetails() const {
|
||||
return rec->getValueAsListOfStrings("details");
|
||||
}
|
||||
std::vector<StringRef> getAnalogues() const {
|
||||
return rec->getValueAsListOfStrings("analogues");
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<ReturnRec> rets;
|
||||
std::vector<ParamRec> params;
|
||||
|
||||
const Record *rec;
|
||||
};
|
||||
|
||||
} // namespace tblgen
|
||||
} // namespace offload
|
||||
} // namespace llvm
|
@ -1,101 +0,0 @@
|
||||
//===- offload-tblgen/offload-tblgen.cpp ----------------------------------===//
|
||||
//
|
||||
// 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 is a Tablegen tool that produces source files for the Offload project.
|
||||
// See offload/API/README.md for more information.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/InitLLVM.h"
|
||||
#include "llvm/TableGen/Main.h"
|
||||
#include "llvm/TableGen/Record.h"
|
||||
|
||||
#include "Generators.hpp"
|
||||
|
||||
namespace llvm {
|
||||
namespace offload {
|
||||
namespace tblgen {
|
||||
|
||||
enum ActionType {
|
||||
PrintRecords,
|
||||
DumpJSON,
|
||||
GenAPI,
|
||||
GenFuncNames,
|
||||
GenImplFuncDecls,
|
||||
GenEntryPoints,
|
||||
GenPrintHeader,
|
||||
GenExports
|
||||
};
|
||||
|
||||
namespace {
|
||||
cl::opt<ActionType> Action(
|
||||
cl::desc("Action to perform:"),
|
||||
cl::values(
|
||||
clEnumValN(PrintRecords, "print-records",
|
||||
"Print all records to stdout (default)"),
|
||||
clEnumValN(DumpJSON, "dump-json",
|
||||
"Dump all records as machine-readable JSON"),
|
||||
clEnumValN(GenAPI, "gen-api", "Generate Offload API header contents"),
|
||||
clEnumValN(GenFuncNames, "gen-func-names",
|
||||
"Generate a list of all Offload API function names"),
|
||||
clEnumValN(
|
||||
GenImplFuncDecls, "gen-impl-func-decls",
|
||||
"Generate declarations for Offload API implementation functions"),
|
||||
clEnumValN(GenEntryPoints, "gen-entry-points",
|
||||
"Generate Offload API wrapper function definitions"),
|
||||
clEnumValN(GenPrintHeader, "gen-print-header",
|
||||
"Generate Offload API print header"),
|
||||
clEnumValN(GenExports, "gen-exports",
|
||||
"Generate export file for the Offload library")));
|
||||
}
|
||||
|
||||
static bool OffloadTableGenMain(raw_ostream &OS, const RecordKeeper &Records) {
|
||||
switch (Action) {
|
||||
case PrintRecords:
|
||||
OS << Records;
|
||||
break;
|
||||
case DumpJSON:
|
||||
EmitJSON(Records, OS);
|
||||
break;
|
||||
case GenAPI:
|
||||
EmitOffloadAPI(Records, OS);
|
||||
break;
|
||||
case GenFuncNames:
|
||||
EmitOffloadFuncNames(Records, OS);
|
||||
break;
|
||||
case GenImplFuncDecls:
|
||||
EmitOffloadImplFuncDecls(Records, OS);
|
||||
break;
|
||||
case GenEntryPoints:
|
||||
EmitOffloadEntryPoints(Records, OS);
|
||||
break;
|
||||
case GenPrintHeader:
|
||||
EmitOffloadPrintHeader(Records, OS);
|
||||
break;
|
||||
case GenExports:
|
||||
EmitOffloadExports(Records, OS);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int OffloadTblgenMain(int argc, char **argv) {
|
||||
InitLLVM y(argc, argv);
|
||||
cl::ParseCommandLineOptions(argc, argv);
|
||||
return TableGenMain(argv[0], &OffloadTableGenMain);
|
||||
}
|
||||
} // namespace tblgen
|
||||
} // namespace offload
|
||||
} // namespace llvm
|
||||
|
||||
using namespace llvm;
|
||||
using namespace offload::tblgen;
|
||||
|
||||
int main(int argc, char **argv) { return OffloadTblgenMain(argc, argv); }
|
@ -5,5 +5,4 @@ function(add_libompt_unittest test_dirname)
|
||||
add_unittest(LibomptUnitTests ${test_dirname} ${ARGN})
|
||||
endfunction()
|
||||
|
||||
# add_subdirectory(Plugins)
|
||||
add_subdirectory(OffloadAPI)
|
||||
add_subdirectory(Plugins)
|
||||
|
@ -1,16 +0,0 @@
|
||||
set(PLUGINS_TEST_COMMON LLVMOffload)
|
||||
set(PLUGINS_TEST_INCLUDE ${LIBOMPTARGET_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/common)
|
||||
|
||||
add_libompt_unittest("offload.unittests"
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/common/Environment.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platform/olGetPlatform.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platform/olGetPlatformCount.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platform/olGetPlatformInfo.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platform/olGetPlatformInfoSize.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/device/olGetDevice.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/device/olGetDeviceCount.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/device/olGetDeviceInfo.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/device/olGetDeviceInfoSize.cpp)
|
||||
add_dependencies("offload.unittests" ${PLUGINS_TEST_COMMON})
|
||||
target_link_libraries("offload.unittests" PRIVATE ${PLUGINS_TEST_COMMON})
|
||||
target_include_directories("offload.unittests" PRIVATE ${PLUGINS_TEST_INCLUDE})
|
@ -1,96 +0,0 @@
|
||||
//===------- Offload API tests - gtest environment ------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Environment.hpp"
|
||||
#include "Fixtures.hpp"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include <OffloadAPI.h>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
// Wrapper so we don't have to constantly init and shutdown Offload in every
|
||||
// test, while having sensible lifetime for the platform environment
|
||||
struct OffloadInitWrapper {
|
||||
OffloadInitWrapper() { olInit(); }
|
||||
~OffloadInitWrapper() { olShutDown(); }
|
||||
};
|
||||
static OffloadInitWrapper Wrapper{};
|
||||
|
||||
static cl::opt<std::string>
|
||||
SelectedPlatform("platform", cl::desc("Only test the specified platform"),
|
||||
cl::value_desc("platform"));
|
||||
|
||||
std::ostream &operator<<(std::ostream &Out,
|
||||
const ol_platform_handle_t &Platform) {
|
||||
size_t Size;
|
||||
olGetPlatformInfoSize(Platform, OL_PLATFORM_INFO_NAME, &Size);
|
||||
std::vector<char> Name(Size);
|
||||
olGetPlatformInfo(Platform, OL_PLATFORM_INFO_NAME, Size, Name.data());
|
||||
Out << Name.data();
|
||||
return Out;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &Out,
|
||||
const std::vector<ol_platform_handle_t> &Platforms) {
|
||||
for (auto Platform : Platforms) {
|
||||
Out << "\n * \"" << Platform << "\"";
|
||||
}
|
||||
return Out;
|
||||
}
|
||||
|
||||
const std::vector<ol_platform_handle_t> &TestEnvironment::getPlatforms() {
|
||||
static std::vector<ol_platform_handle_t> Platforms{};
|
||||
|
||||
if (Platforms.empty()) {
|
||||
uint32_t PlatformCount = 0;
|
||||
olGetPlatformCount(&PlatformCount);
|
||||
if (PlatformCount > 0) {
|
||||
Platforms.resize(PlatformCount);
|
||||
olGetPlatform(PlatformCount, Platforms.data());
|
||||
}
|
||||
}
|
||||
|
||||
return Platforms;
|
||||
}
|
||||
|
||||
// Get a single platform, which may be selected by the user.
|
||||
ol_platform_handle_t TestEnvironment::getPlatform() {
|
||||
static ol_platform_handle_t Platform = nullptr;
|
||||
const auto &Platforms = getPlatforms();
|
||||
|
||||
if (!Platform) {
|
||||
if (SelectedPlatform != "") {
|
||||
for (const auto CandidatePlatform : Platforms) {
|
||||
std::stringstream PlatformName;
|
||||
PlatformName << CandidatePlatform;
|
||||
if (SelectedPlatform == PlatformName.str()) {
|
||||
Platform = CandidatePlatform;
|
||||
return Platform;
|
||||
}
|
||||
}
|
||||
std::cout << "No platform found with the name \"" << SelectedPlatform
|
||||
<< "\". Choose from:" << Platforms << "\n";
|
||||
std::exit(1);
|
||||
} else {
|
||||
// Pick a single platform. We prefer one that has available devices, but
|
||||
// just pick the first initially in case none have any devices.
|
||||
Platform = Platforms[0];
|
||||
for (auto CandidatePlatform : Platforms) {
|
||||
uint32_t NumDevices = 0;
|
||||
if (olGetDeviceCount(CandidatePlatform, &NumDevices) == OL_SUCCESS) {
|
||||
if (NumDevices > 0) {
|
||||
Platform = CandidatePlatform;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Platform;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//===------- Offload API tests - gtest environment ------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <OffloadAPI.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace TestEnvironment {
|
||||
const std::vector<ol_platform_handle_t> &getPlatforms();
|
||||
ol_platform_handle_t getPlatform();
|
||||
} // namespace TestEnvironment
|
@ -1,64 +0,0 @@
|
||||
//===------- Offload API tests - gtest fixtures --==-----------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <OffloadAPI.h>
|
||||
#include <OffloadPrint.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "Environment.hpp"
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef ASSERT_SUCCESS
|
||||
#define ASSERT_SUCCESS(ACTUAL) ASSERT_EQ(OL_SUCCESS, ACTUAL)
|
||||
#endif
|
||||
|
||||
// TODO: rework this so the EXPECTED/ACTUAL results are readable
|
||||
#ifndef ASSERT_ERROR
|
||||
#define ASSERT_ERROR(EXPECTED, ACTUAL) \
|
||||
do { \
|
||||
ol_result_t Res = ACTUAL; \
|
||||
ASSERT_TRUE(Res && (Res->Code == EXPECTED)); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define RETURN_ON_FATAL_FAILURE(...) \
|
||||
__VA_ARGS__; \
|
||||
if (this->HasFatalFailure() || this->IsSkipped()) { \
|
||||
return; \
|
||||
} \
|
||||
(void)0
|
||||
|
||||
struct offloadTest : ::testing::Test {
|
||||
// No special behavior now, but just in case we need to override it in future
|
||||
};
|
||||
|
||||
struct offloadPlatformTest : offloadTest {
|
||||
void SetUp() override {
|
||||
RETURN_ON_FATAL_FAILURE(offloadTest::SetUp());
|
||||
|
||||
Platform = TestEnvironment::getPlatform();
|
||||
ASSERT_NE(Platform, nullptr);
|
||||
}
|
||||
|
||||
ol_platform_handle_t Platform;
|
||||
};
|
||||
|
||||
struct offloadDeviceTest : offloadPlatformTest {
|
||||
void SetUp() override {
|
||||
RETURN_ON_FATAL_FAILURE(offloadPlatformTest::SetUp());
|
||||
|
||||
uint32_t NumDevices;
|
||||
ASSERT_SUCCESS(olGetDeviceCount(Platform, &NumDevices));
|
||||
if (NumDevices == 0)
|
||||
GTEST_SKIP() << "No available devices on this platform.";
|
||||
ASSERT_SUCCESS(olGetDevice(Platform, 1, &Device));
|
||||
}
|
||||
|
||||
ol_device_handle_t Device;
|
||||
};
|
@ -1,21 +0,0 @@
|
||||
//===------- Offload API tests - Helpers for device info query testing ----===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
// TODO: We could autogenerate these
|
||||
inline std::vector<ol_device_info_t> DeviceQueries = {
|
||||
OL_DEVICE_INFO_TYPE, OL_DEVICE_INFO_PLATFORM, OL_DEVICE_INFO_NAME,
|
||||
OL_DEVICE_INFO_VENDOR, OL_DEVICE_INFO_DRIVER_VERSION};
|
||||
|
||||
inline std::unordered_map<ol_device_info_t, size_t> DeviceInfoSizeMap = {
|
||||
{OL_DEVICE_INFO_TYPE, sizeof(ol_device_type_t)},
|
||||
{OL_DEVICE_INFO_PLATFORM, sizeof(ol_platform_handle_t)},
|
||||
};
|
@ -1,39 +0,0 @@
|
||||
//===------- Offload API tests - olGetDevice -------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../common/Fixtures.hpp"
|
||||
#include <OffloadAPI.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using olGetDeviceTest = offloadPlatformTest;
|
||||
|
||||
TEST_F(olGetDeviceTest, Success) {
|
||||
uint32_t Count = 0;
|
||||
ASSERT_SUCCESS(olGetDeviceCount(Platform, &Count));
|
||||
if (Count == 0)
|
||||
GTEST_SKIP() << "No available devices on this platform.";
|
||||
|
||||
std::vector<ol_device_handle_t> Devices(Count);
|
||||
ASSERT_SUCCESS(olGetDevice(Platform, Count, Devices.data()));
|
||||
for (auto Device : Devices) {
|
||||
ASSERT_NE(nullptr, Device);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(olGetDeviceTest, SuccessSubsetOfDevices) {
|
||||
uint32_t Count;
|
||||
ASSERT_SUCCESS(olGetDeviceCount(Platform, &Count));
|
||||
if (Count < 2)
|
||||
GTEST_SKIP() << "Only one device is available on this platform.";
|
||||
|
||||
std::vector<ol_device_handle_t> Devices(Count - 1);
|
||||
ASSERT_SUCCESS(olGetDevice(Platform, Count - 1, Devices.data()));
|
||||
for (auto Device : Devices) {
|
||||
ASSERT_NE(nullptr, Device);
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
//===------- Offload API tests - olGetDeviceCount --------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../common/Fixtures.hpp"
|
||||
#include <OffloadAPI.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using olGetDeviceCountTest = offloadPlatformTest;
|
||||
|
||||
TEST_F(olGetDeviceCountTest, Success) {
|
||||
uint32_t Count = 0;
|
||||
ASSERT_SUCCESS(olGetDeviceCount(Platform, &Count));
|
||||
}
|
||||
|
||||
TEST_F(olGetDeviceCountTest, InvalidNullPlatform) {
|
||||
uint32_t Count = 0;
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE, olGetDeviceCount(nullptr, &Count));
|
||||
}
|
||||
|
||||
TEST_F(olGetDeviceCountTest, InvalidNullPointer) {
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
|
||||
olGetDeviceCount(Platform, nullptr));
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
//===------- Offload API tests - olGetDeviceInfo ---------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../common/Fixtures.hpp"
|
||||
#include "olDeviceInfo.hpp"
|
||||
#include <OffloadAPI.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
struct olGetDeviceInfoTest : offloadDeviceTest,
|
||||
::testing::WithParamInterface<ol_device_info_t> {
|
||||
|
||||
void SetUp() override { RETURN_ON_FATAL_FAILURE(offloadDeviceTest::SetUp()); }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
, olGetDeviceInfoTest, ::testing::ValuesIn(DeviceQueries),
|
||||
[](const ::testing::TestParamInfo<ol_device_info_t> &info) {
|
||||
std::stringstream ss;
|
||||
ss << info.param;
|
||||
return ss.str();
|
||||
});
|
||||
|
||||
TEST_P(olGetDeviceInfoTest, Success) {
|
||||
ol_device_info_t InfoType = GetParam();
|
||||
size_t Size = 0;
|
||||
|
||||
ASSERT_SUCCESS(olGetDeviceInfoSize(Device, InfoType, &Size));
|
||||
|
||||
std::vector<char> InfoData(Size);
|
||||
ASSERT_SUCCESS(olGetDeviceInfo(Device, InfoType, Size, InfoData.data()));
|
||||
|
||||
if (InfoType == OL_DEVICE_INFO_PLATFORM) {
|
||||
auto *ReturnedPlatform =
|
||||
reinterpret_cast<ol_platform_handle_t *>(InfoData.data());
|
||||
ASSERT_EQ(Platform, *ReturnedPlatform);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(olGetDeviceInfoTest, InvalidNullHandleDevice) {
|
||||
ol_device_type_t DeviceType;
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE,
|
||||
olGetDeviceInfo(nullptr, OL_DEVICE_INFO_TYPE,
|
||||
sizeof(ol_device_type_t), &DeviceType));
|
||||
}
|
||||
|
||||
TEST_F(olGetDeviceInfoTest, InvalidEnumerationInfoType) {
|
||||
ol_device_type_t DeviceType;
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_ENUMERATION,
|
||||
olGetDeviceInfo(Device, OL_DEVICE_INFO_FORCE_UINT32,
|
||||
sizeof(ol_device_type_t), &DeviceType));
|
||||
}
|
||||
|
||||
TEST_F(olGetDeviceInfoTest, InvalidSizePropSize) {
|
||||
ol_device_type_t DeviceType;
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_SIZE,
|
||||
olGetDeviceInfo(Device, OL_DEVICE_INFO_TYPE, 0, &DeviceType));
|
||||
}
|
||||
|
||||
TEST_F(olGetDeviceInfoTest, InvalidSizePropSizeSmall) {
|
||||
ol_device_type_t DeviceType;
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_SIZE,
|
||||
olGetDeviceInfo(Device, OL_DEVICE_INFO_TYPE,
|
||||
sizeof(DeviceType) - 1, &DeviceType));
|
||||
}
|
||||
|
||||
TEST_F(olGetDeviceInfoTest, InvalidNullPointerPropValue) {
|
||||
ol_device_type_t DeviceType;
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
|
||||
olGetDeviceInfo(Device, OL_DEVICE_INFO_TYPE, sizeof(DeviceType),
|
||||
nullptr));
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
//===------- Offload API tests - olGetDeviceInfoSize -----------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <OffloadAPI.h>
|
||||
|
||||
#include "../common/Fixtures.hpp"
|
||||
#include "olDeviceInfo.hpp"
|
||||
|
||||
struct olGetDeviceInfoSizeTest
|
||||
: offloadDeviceTest,
|
||||
::testing::WithParamInterface<ol_device_info_t> {
|
||||
|
||||
void SetUp() override { RETURN_ON_FATAL_FAILURE(offloadDeviceTest::SetUp()); }
|
||||
};
|
||||
|
||||
// TODO: We could autogenerate the list of enum values
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
, olGetDeviceInfoSizeTest, ::testing::ValuesIn(DeviceQueries),
|
||||
[](const ::testing::TestParamInfo<ol_device_info_t> &info) {
|
||||
std::stringstream ss;
|
||||
ss << info.param;
|
||||
return ss.str();
|
||||
});
|
||||
|
||||
TEST_P(olGetDeviceInfoSizeTest, Success) {
|
||||
ol_device_info_t InfoType = GetParam();
|
||||
size_t Size = 0;
|
||||
|
||||
ASSERT_SUCCESS(olGetDeviceInfoSize(Device, InfoType, &Size));
|
||||
auto ExpectedSize = DeviceInfoSizeMap.find(InfoType);
|
||||
if (ExpectedSize != DeviceInfoSizeMap.end()) {
|
||||
ASSERT_EQ(Size, ExpectedSize->second);
|
||||
} else {
|
||||
ASSERT_NE(Size, 0lu);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(olGetDeviceInfoSizeTest, InvalidNullHandle) {
|
||||
size_t Size = 0;
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE,
|
||||
olGetDeviceInfoSize(nullptr, OL_DEVICE_INFO_TYPE, &Size));
|
||||
}
|
||||
|
||||
TEST_F(olGetDeviceInfoSizeTest, InvalidDeviceInfoEnumeration) {
|
||||
size_t Size = 0;
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_ENUMERATION,
|
||||
olGetDeviceInfoSize(Device, OL_DEVICE_INFO_FORCE_UINT32, &Size));
|
||||
}
|
||||
|
||||
TEST_F(olGetDeviceInfoSizeTest, InvalidNullPointer) {
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
|
||||
olGetDeviceInfoSize(Device, OL_DEVICE_INFO_TYPE, nullptr));
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
//===------- Offload API tests - olGetPlatform -----------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../common/Fixtures.hpp"
|
||||
#include <OffloadAPI.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using olGetPlatformTest = offloadTest;
|
||||
|
||||
TEST_F(olGetPlatformTest, Success) {
|
||||
uint32_t PlatformCount;
|
||||
ASSERT_SUCCESS(olGetPlatformCount(&PlatformCount));
|
||||
std::vector<ol_platform_handle_t> Platforms(PlatformCount);
|
||||
ASSERT_SUCCESS(olGetPlatform(PlatformCount, Platforms.data()));
|
||||
}
|
||||
|
||||
TEST_F(olGetPlatformTest, InvalidNumEntries) {
|
||||
uint32_t PlatformCount;
|
||||
ASSERT_SUCCESS(olGetPlatformCount(&PlatformCount));
|
||||
std::vector<ol_platform_handle_t> Platforms(PlatformCount);
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_SIZE,
|
||||
olGetPlatform(PlatformCount + 1, Platforms.data()));
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
//===------- Offload API tests - olGetPlatformCount ------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../common/Fixtures.hpp"
|
||||
#include <OffloadAPI.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using olGetPlatformCountTest = offloadTest;
|
||||
|
||||
TEST_F(olGetPlatformCountTest, Success) {
|
||||
uint32_t PlatformCount;
|
||||
ASSERT_SUCCESS(olGetPlatformCount(&PlatformCount));
|
||||
}
|
||||
|
||||
TEST_F(olGetPlatformCountTest, InvalidNullPointer) {
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER, olGetPlatformCount(nullptr));
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
//===------- Offload API tests - olGetPlatformInfo -------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <OffloadAPI.h>
|
||||
|
||||
#include "../common/Fixtures.hpp"
|
||||
#include "olPlatformInfo.hpp"
|
||||
|
||||
struct olGetPlatformInfoTest
|
||||
: offloadPlatformTest,
|
||||
::testing::WithParamInterface<ol_platform_info_t> {};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
olGetPlatformInfo, olGetPlatformInfoTest,
|
||||
::testing::ValuesIn(PlatformQueries),
|
||||
[](const ::testing::TestParamInfo<ol_platform_info_t> &info) {
|
||||
std::stringstream ss;
|
||||
ss << info.param;
|
||||
return ss.str();
|
||||
});
|
||||
|
||||
TEST_P(olGetPlatformInfoTest, Success) {
|
||||
size_t Size = 0;
|
||||
ol_platform_info_t InfoType = GetParam();
|
||||
|
||||
ASSERT_SUCCESS(olGetPlatformInfoSize(Platform, InfoType, &Size));
|
||||
std::vector<char> InfoData(Size);
|
||||
ASSERT_SUCCESS(olGetPlatformInfo(Platform, InfoType, Size, InfoData.data()));
|
||||
|
||||
// Info types with a dynamic size are all char[] so we can verify the returned
|
||||
// string is the expected size.
|
||||
auto ExpectedSize = PlatformInfoSizeMap.find(InfoType);
|
||||
if (ExpectedSize == PlatformInfoSizeMap.end()) {
|
||||
ASSERT_EQ(Size, strlen(InfoData.data()) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(olGetPlatformInfoTest, InvalidNullHandle) {
|
||||
ol_platform_backend_t Backend;
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE,
|
||||
olGetPlatformInfo(nullptr, OL_PLATFORM_INFO_BACKEND,
|
||||
sizeof(Backend), &Backend));
|
||||
}
|
||||
|
||||
TEST_F(olGetPlatformInfoTest, InvalidPlatformInfoEnumeration) {
|
||||
ol_platform_backend_t Backend;
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_ENUMERATION,
|
||||
olGetPlatformInfo(Platform, OL_PLATFORM_INFO_FORCE_UINT32,
|
||||
sizeof(Backend), &Backend));
|
||||
}
|
||||
|
||||
TEST_F(olGetPlatformInfoTest, InvalidSizeZero) {
|
||||
ol_platform_backend_t Backend;
|
||||
ASSERT_ERROR(
|
||||
OL_ERRC_INVALID_SIZE,
|
||||
olGetPlatformInfo(Platform, OL_PLATFORM_INFO_BACKEND, 0, &Backend));
|
||||
}
|
||||
|
||||
TEST_F(olGetPlatformInfoTest, InvalidSizeSmall) {
|
||||
ol_platform_backend_t Backend;
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_SIZE,
|
||||
olGetPlatformInfo(Platform, OL_PLATFORM_INFO_BACKEND,
|
||||
sizeof(Backend) - 1, &Backend));
|
||||
}
|
||||
|
||||
TEST_F(olGetPlatformInfoTest, InvalidNullPointerPropValue) {
|
||||
ol_platform_backend_t Backend;
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
|
||||
olGetPlatformInfo(Platform, OL_PLATFORM_INFO_BACKEND,
|
||||
sizeof(Backend), nullptr));
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
//===------- Offload API tests - olGetPlatformInfoSize ---------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <OffloadAPI.h>
|
||||
|
||||
#include "../common/Fixtures.hpp"
|
||||
#include "olPlatformInfo.hpp"
|
||||
|
||||
struct olGetPlatformInfoSizeTest
|
||||
: offloadPlatformTest,
|
||||
::testing::WithParamInterface<ol_platform_info_t> {};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
olGetPlatformInfoSize, olGetPlatformInfoSizeTest,
|
||||
::testing::ValuesIn(PlatformQueries),
|
||||
[](const ::testing::TestParamInfo<ol_platform_info_t> &info) {
|
||||
std::stringstream ss;
|
||||
ss << info.param;
|
||||
return ss.str();
|
||||
});
|
||||
|
||||
TEST_P(olGetPlatformInfoSizeTest, Success) {
|
||||
size_t Size = 0;
|
||||
ol_platform_info_t InfoType = GetParam();
|
||||
|
||||
ASSERT_SUCCESS(olGetPlatformInfoSize(Platform, InfoType, &Size));
|
||||
auto ExpectedSize = PlatformInfoSizeMap.find(InfoType);
|
||||
if (ExpectedSize != PlatformInfoSizeMap.end()) {
|
||||
ASSERT_EQ(Size, ExpectedSize->second);
|
||||
} else {
|
||||
ASSERT_NE(Size, 0lu);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(olGetPlatformInfoSizeTest, InvalidNullHandle) {
|
||||
size_t Size = 0;
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE,
|
||||
olGetPlatformInfoSize(nullptr, OL_PLATFORM_INFO_BACKEND, &Size));
|
||||
}
|
||||
|
||||
TEST_F(olGetPlatformInfoSizeTest, InvalidPlatformInfoEnumeration) {
|
||||
size_t Size = 0;
|
||||
ASSERT_ERROR(
|
||||
OL_ERRC_INVALID_ENUMERATION,
|
||||
olGetPlatformInfoSize(Platform, OL_PLATFORM_INFO_FORCE_UINT32, &Size));
|
||||
}
|
||||
|
||||
TEST_F(olGetPlatformInfoSizeTest, InvalidNullPointer) {
|
||||
ASSERT_ERROR(
|
||||
OL_ERRC_INVALID_NULL_POINTER,
|
||||
olGetPlatformInfoSize(Platform, OL_PLATFORM_INFO_BACKEND, nullptr));
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
//===------- Offload API tests - Helpers for platform info query testing --===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
// TODO: We could autogenerate these
|
||||
|
||||
inline std::vector<ol_platform_info_t> PlatformQueries = {
|
||||
OL_PLATFORM_INFO_NAME, OL_PLATFORM_INFO_VENDOR_NAME,
|
||||
OL_PLATFORM_INFO_VERSION, OL_PLATFORM_INFO_BACKEND};
|
||||
|
||||
inline std::unordered_map<ol_platform_info_t, size_t> PlatformInfoSizeMap = {
|
||||
{OL_PLATFORM_INFO_BACKEND, sizeof(ol_platform_backend_t)},
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user