[llvm] [offload] add translation of plugin-specific error codes to Offload API ECs (PR #207208)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 13 02:26:48 PDT 2026
Jan =?utf-8?q?Trusiłło?= <113amper at gmail.com>,
Jan =?utf-8?q?Trusiłło?= <113amper at gmail.com>,
Jan =?utf-8?q?Trusiłło?= <113amper at gmail.com>,
Jan =?utf-8?q?Trusiłło?= <113amper at gmail.com>,
Jan =?utf-8?q?Trusiłło?= <113amper at gmail.com>,
Jan =?utf-8?q?Trusiłło?= <jan.trusillo at intel.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/207208 at github.com>
https://github.com/311Volt updated https://github.com/llvm/llvm-project/pull/207208
>From c432c7a922873b9023f5e03425b8aeba2cba0ac7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Trusi=C5=82=C5=82o?= <113amper at gmail.com>
Date: Wed, 17 Jun 2026 13:22:06 +0000
Subject: [PATCH 1/7] [offload] add tests for olCreateProgram validation
---
.../OffloadAPI/program/olCreateProgram.cpp | 27 +++----------------
1 file changed, 4 insertions(+), 23 deletions(-)
diff --git a/offload/unittests/OffloadAPI/program/olCreateProgram.cpp b/offload/unittests/OffloadAPI/program/olCreateProgram.cpp
index 9177f91359784..02e82fe530ea3 100644
--- a/offload/unittests/OffloadAPI/program/olCreateProgram.cpp
+++ b/offload/unittests/OffloadAPI/program/olCreateProgram.cpp
@@ -14,6 +14,7 @@ using olCreateProgramTest = OffloadDeviceTest;
OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olCreateProgramTest);
TEST_P(olCreateProgramTest, Success) {
+
std::unique_ptr<llvm::MemoryBuffer> DeviceBin;
ASSERT_TRUE(TestEnvironment::loadDeviceBinary("foo", Device, DeviceBin));
ASSERT_GE(DeviceBin->getBufferSize(), 0lu);
@@ -27,6 +28,7 @@ TEST_P(olCreateProgramTest, Success) {
}
TEST_P(olCreateProgramTest, NullDeviceHandle) {
+
std::unique_ptr<llvm::MemoryBuffer> DeviceBin;
ASSERT_TRUE(TestEnvironment::loadDeviceBinary("foo", Device, DeviceBin));
ASSERT_GE(DeviceBin->getBufferSize(), 0lu);
@@ -38,6 +40,7 @@ TEST_P(olCreateProgramTest, NullDeviceHandle) {
}
TEST_P(olCreateProgramTest, NullProgData) {
+
std::unique_ptr<llvm::MemoryBuffer> DeviceBin;
ASSERT_TRUE(TestEnvironment::loadDeviceBinary("foo", Device, DeviceBin));
ASSERT_GE(DeviceBin->getBufferSize(), 0lu);
@@ -49,6 +52,7 @@ TEST_P(olCreateProgramTest, NullProgData) {
}
TEST_P(olCreateProgramTest, NullOutputProgram) {
+
std::unique_ptr<llvm::MemoryBuffer> DeviceBin;
ASSERT_TRUE(TestEnvironment::loadDeviceBinary("foo", Device, DeviceBin));
ASSERT_GE(DeviceBin->getBufferSize(), 0lu);
@@ -57,26 +61,3 @@ TEST_P(olCreateProgramTest, NullOutputProgram) {
olCreateProgram(Device, DeviceBin->getBufferStart(),
DeviceBin->getBufferSize(), nullptr));
}
-
-TEST_P(olCreateProgramTest, ZeroSizeBinary) {
- std::unique_ptr<llvm::MemoryBuffer> DeviceBin;
- ASSERT_TRUE(TestEnvironment::loadDeviceBinary("foo", Device, DeviceBin));
- ASSERT_GT(DeviceBin->getBufferSize(), 0lu);
-
- ol_program_handle_t Program = nullptr;
-
- // backend rejection of a binary is not guaranteed to map to a specific
- // ol_errc_t, so we ASSERT_ANY_ERROR for now
- ASSERT_ANY_ERROR(
- olCreateProgram(Device, DeviceBin->getBufferStart(), 0, &Program));
- ASSERT_EQ(Program, nullptr);
-}
-
-TEST_P(olCreateProgramTest, InvalidBinary) {
- const char InvalidBinary[] = "not an offload binary";
-
- ol_program_handle_t Program = nullptr;
- ASSERT_ANY_ERROR(olCreateProgram(Device, InvalidBinary,
- sizeof(InvalidBinary) - 1, &Program));
- ASSERT_EQ(Program, nullptr);
-}
>From 3861be5a60eb41ee0b16515d633ae1b76b678529 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Trusi=C5=82=C5=82o?= <113amper at gmail.com>
Date: Mon, 22 Jun 2026 14:01:39 +0000
Subject: [PATCH 2/7] [offload] add translation of plugin-specific error codes
to offload api ECs
---
offload/liboffload/src/OffloadImpl.cpp | 9 +
.../plugins-nextgen/amdgpu/dynamic_hsa/hsa.h | 109 ++-
offload/plugins-nextgen/amdgpu/src/rtl.cpp | 18 +-
.../plugins-nextgen/cuda/dynamic_cuda/cuda.h | 669 +++++++++++++++++-
offload/plugins-nextgen/cuda/src/rtl.cpp | 38 +-
.../level_zero/include/L0Trace.h | 66 +-
.../OffloadAPI/common/Environment.cpp | 20 +-
.../OffloadAPI/common/Environment.hpp | 4 +-
.../OffloadAPI/program/olCreateProgram.cpp | 56 ++
9 files changed, 963 insertions(+), 26 deletions(-)
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 1aec20a225196..d2b714ae657bf 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -1043,6 +1043,15 @@ Error olMemPrefetch_impl(ol_queue_handle_t Queue, size_t Count,
Error olCreateProgram_impl(ol_device_handle_t Device, const void *ProgData,
size_t ProgDataSize, ol_program_handle_t *Program) {
+
+ // an empty image is not a valid binary
+ // plugins behave differently given empty binaries - e.g. CUDA will map to INVALID_BINARY,
+ // while L0 will map to INVALID_SIZE which is also associated with invalid kernel launch dims etc.
+ // so we guard here for consistent behavior
+ if (ProgDataSize == 0)
+ return createOffloadError(ErrorCode::INVALID_BINARY,
+ "provided binary image is empty");
+
StringRef Buffer(reinterpret_cast<const char *>(ProgData), ProgDataSize);
Expected<plugin::DeviceImageTy *> Res =
Device->Device->loadBinary(Device->Device->Plugin, Buffer);
diff --git a/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h b/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h
index 258c7234251d5..5f7591cc23914 100644
--- a/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h
+++ b/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h
@@ -25,14 +25,119 @@
extern "C" {
#endif
+/**
+ * @brief Status codes.
+ */
typedef enum {
+ /**
+ * The function has been executed successfully.
+ */
HSA_STATUS_SUCCESS = 0x0,
+ /**
+ * A traversal over a list of elements has been interrupted by the
+ * application before completing.
+ */
HSA_STATUS_INFO_BREAK = 0x1,
+ /**
+ * A generic error has occurred.
+ */
HSA_STATUS_ERROR = 0x1000,
+ /**
+ * One of the actual arguments does not meet a precondition stated in the
+ * documentation of the corresponding formal argument.
+ */
+ HSA_STATUS_ERROR_INVALID_ARGUMENT = 0x1001,
+ /**
+ * The requested queue creation is not valid.
+ */
+ HSA_STATUS_ERROR_INVALID_QUEUE_CREATION = 0x1002,
+ /**
+ * The requested allocation is not valid.
+ */
+ HSA_STATUS_ERROR_INVALID_ALLOCATION = 0x1003,
+ /**
+ * The agent is invalid.
+ */
+ HSA_STATUS_ERROR_INVALID_AGENT = 0x1004,
+ /**
+ * The memory region is invalid.
+ */
+ HSA_STATUS_ERROR_INVALID_REGION = 0x1005,
+ /**
+ * The signal is invalid.
+ */
+ HSA_STATUS_ERROR_INVALID_SIGNAL = 0x1006,
+ /**
+ * The queue is invalid.
+ */
+ HSA_STATUS_ERROR_INVALID_QUEUE = 0x1007,
+ /**
+ * The HSA runtime failed to allocate the necessary resources. This error
+ * may also occur when the HSA runtime needs to spawn threads or create
+ * internal OS-specific events.
+ */
+ HSA_STATUS_ERROR_OUT_OF_RESOURCES = 0x1008,
+ /**
+ * The AQL packet is malformed.
+ */
+ HSA_STATUS_ERROR_INVALID_PACKET_FORMAT = 0x1009,
+ /**
+ * An error has been detected while releasing a resource.
+ */
+ HSA_STATUS_ERROR_RESOURCE_FREE = 0x100A,
+ /**
+ * An API other than ::hsa_init has been invoked while the reference count
+ * of the HSA runtime is 0.
+ */
+ HSA_STATUS_ERROR_NOT_INITIALIZED = 0x100B,
+ /**
+ * The maximum reference count for the object has been reached.
+ */
+ HSA_STATUS_ERROR_REFCOUNT_OVERFLOW = 0x100C,
+ /**
+ * The arguments passed to a functions are not compatible.
+ */
+ HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS = 0x100D,
+ /**
+ * The index is invalid.
+ */
+ HSA_STATUS_ERROR_INVALID_INDEX = 0x100E,
+ /**
+ * The instruction set architecture is invalid.
+ */
+ HSA_STATUS_ERROR_INVALID_ISA = 0x100F,
+ /**
+ * The instruction set architecture name is invalid.
+ */
+ HSA_STATUS_ERROR_INVALID_ISA_NAME = 0x1017,
+ /**
+ * The code object is invalid.
+ */
HSA_STATUS_ERROR_INVALID_CODE_OBJECT = 0x1010,
+ /**
+ * The executable is invalid.
+ */
+ HSA_STATUS_ERROR_INVALID_EXECUTABLE = 0x1011,
+ /**
+ * The executable is frozen.
+ */
+ HSA_STATUS_ERROR_FROZEN_EXECUTABLE = 0x1012,
+ /**
+ * There is no symbol with the given name.
+ */
HSA_STATUS_ERROR_INVALID_SYMBOL_NAME = 0x1013,
- HSA_STATUS_ERROR_NOT_INITIALIZED = 0x100B,
- HSA_STATUS_ERROR_EXCEPTION = 0x1016,
+ /**
+ * The variable is already defined.
+ */
+ HSA_STATUS_ERROR_VARIABLE_ALREADY_DEFINED = 0x1014,
+ /**
+ * The variable is undefined.
+ */
+ HSA_STATUS_ERROR_VARIABLE_UNDEFINED = 0x1015,
+ /**
+ * An HSAIL operation resulted on a hardware exception.
+ */
+ HSA_STATUS_ERROR_EXCEPTION = 0x1016
} hsa_status_t;
hsa_status_t hsa_status_string(hsa_status_t status, const char **status_string);
diff --git a/offload/plugins-nextgen/amdgpu/src/rtl.cpp b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
index f1caee0c4c1e2..f270417b0f2b2 100644
--- a/offload/plugins-nextgen/amdgpu/src/rtl.cpp
+++ b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
@@ -4379,15 +4379,31 @@ static Error Plugin::check(int32_t Code, const char *ErrFmt, ArgsTy... Args) {
if (Ret != HSA_STATUS_SUCCESS)
REPORT() << "Unrecognized " GETNAME(TARGET_NAME) " error code " << Code;
- // TODO: Add more entries to this switch
ErrorCode OffloadErrCode;
switch (ResultCode) {
case HSA_STATUS_ERROR_INVALID_SYMBOL_NAME:
+ case HSA_STATUS_ERROR_INVALID_ISA_NAME:
OffloadErrCode = ErrorCode::NOT_FOUND;
break;
case HSA_STATUS_ERROR_INVALID_CODE_OBJECT:
+ case HSA_STATUS_ERROR_INVALID_ISA:
+ case HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS:
OffloadErrCode = ErrorCode::INVALID_BINARY;
break;
+ case HSA_STATUS_ERROR_OUT_OF_RESOURCES:
+ OffloadErrCode = ErrorCode::OUT_OF_RESOURCES;
+ break;
+ case HSA_STATUS_ERROR_NOT_INITIALIZED:
+ OffloadErrCode = ErrorCode::UNINITIALIZED;
+ break;
+ case HSA_STATUS_ERROR_INVALID_ARGUMENT:
+ case HSA_STATUS_ERROR_INVALID_ALLOCATION:
+ case HSA_STATUS_ERROR_INVALID_AGENT:
+ case HSA_STATUS_ERROR_INVALID_REGION:
+ case HSA_STATUS_ERROR_INVALID_QUEUE:
+ case HSA_STATUS_ERROR_INVALID_INDEX:
+ OffloadErrCode = ErrorCode::INVALID_ARGUMENT;
+ break;
default:
OffloadErrCode = ErrorCode::UNKNOWN;
}
diff --git a/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h b/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h
index 12c42b82431e2..2624a636592bf 100644
--- a/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h
+++ b/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h
@@ -105,14 +105,669 @@ typedef struct CUmemAllocationProp_st {
} CUmemAllocationProp_v1;
typedef CUmemAllocationProp_v1 CUmemAllocationProp;
+/**
+ * Error codes (as of CUDA 12.1)
+ */
typedef enum cudaError_enum {
- CUDA_SUCCESS = 0,
- CUDA_ERROR_INVALID_VALUE = 1,
- CUDA_ERROR_NO_DEVICE = 100,
- CUDA_ERROR_INVALID_HANDLE = 400,
- CUDA_ERROR_NOT_FOUND = 500,
- CUDA_ERROR_NOT_READY = 600,
- CUDA_ERROR_TOO_MANY_PEERS = 711,
+ /**
+ * The API call returned with no errors. In the case of query calls, this
+ * also means that the operation being queried is complete (see
+ * ::cuEventQuery() and ::cuStreamQuery()).
+ */
+ CUDA_SUCCESS = 0,
+
+ /**
+ * This indicates that one or more of the parameters passed to the API call
+ * is not within an acceptable range of values.
+ */
+ CUDA_ERROR_INVALID_VALUE = 1,
+
+ /**
+ * The API call failed because it was unable to allocate enough memory or
+ * other resources to perform the requested operation.
+ */
+ CUDA_ERROR_OUT_OF_MEMORY = 2,
+
+ /**
+ * This indicates that the CUDA driver has not been initialized with
+ * ::cuInit() or that initialization has failed.
+ */
+ CUDA_ERROR_NOT_INITIALIZED = 3,
+
+ /**
+ * This indicates that the CUDA driver is in the process of shutting down.
+ */
+ CUDA_ERROR_DEINITIALIZED = 4,
+
+ /**
+ * This indicates profiler is not initialized for this run. This can
+ * happen when the application is running with external profiling tools
+ * like visual profiler.
+ */
+ CUDA_ERROR_PROFILER_DISABLED = 5,
+
+ /**
+ * \deprecated
+ * This error return is deprecated as of CUDA 5.0. It is no longer an error
+ * to attempt to enable/disable the profiling via ::cuProfilerStart or
+ * ::cuProfilerStop without initialization.
+ */
+ CUDA_ERROR_PROFILER_NOT_INITIALIZED = 6,
+
+ /**
+ * \deprecated
+ * This error return is deprecated as of CUDA 5.0. It is no longer an error
+ * to call cuProfilerStart() when profiling is already enabled.
+ */
+ CUDA_ERROR_PROFILER_ALREADY_STARTED = 7,
+
+ /**
+ * \deprecated
+ * This error return is deprecated as of CUDA 5.0. It is no longer an error
+ * to call cuProfilerStop() when profiling is already disabled.
+ */
+ CUDA_ERROR_PROFILER_ALREADY_STOPPED = 8,
+
+ /**
+ * This indicates that the CUDA driver that the application has loaded is a
+ * stub library. Applications that run with the stub rather than a real
+ * driver loaded will result in CUDA API returning this error.
+ */
+ CUDA_ERROR_STUB_LIBRARY = 34,
+
+ /**
+ * This indicates that requested CUDA device is unavailable at the current
+ * time. Devices are often unavailable due to use of
+ * ::CU_COMPUTEMODE_EXCLUSIVE_PROCESS or ::CU_COMPUTEMODE_PROHIBITED.
+ */
+ CUDA_ERROR_DEVICE_UNAVAILABLE = 46,
+
+ /**
+ * This indicates that no CUDA-capable devices were detected by the installed
+ * CUDA driver.
+ */
+ CUDA_ERROR_NO_DEVICE = 100,
+
+ /**
+ * This indicates that the device ordinal supplied by the user does not
+ * correspond to a valid CUDA device or that the action requested is
+ * invalid for the specified device.
+ */
+ CUDA_ERROR_INVALID_DEVICE = 101,
+
+ /**
+ * This error indicates that the Grid license is not applied.
+ */
+ CUDA_ERROR_DEVICE_NOT_LICENSED = 102,
+
+ /**
+ * This indicates that the device kernel image is invalid. This can also
+ * indicate an invalid CUDA module.
+ */
+ CUDA_ERROR_INVALID_IMAGE = 200,
+
+ /**
+ * This most frequently indicates that there is no context bound to the
+ * current thread. This can also be returned if the context passed to an
+ * API call is not a valid handle (such as a context that has had
+ * ::cuCtxDestroy() invoked on it). This can also be returned if a user
+ * mixes different API versions (i.e. 3010 context with 3020 API calls).
+ * See ::cuCtxGetApiVersion() for more details.
+ * This can also be returned if the green context passed to an API call
+ * was not converted to a ::CUcontext using ::cuCtxFromGreenCtx API.
+ */
+ CUDA_ERROR_INVALID_CONTEXT = 201,
+
+ /**
+ * This indicated that the context being supplied as a parameter to the
+ * API call was already the active context.
+ * \deprecated
+ * This error return is deprecated as of CUDA 3.2. It is no longer an
+ * error to attempt to push the active context via ::cuCtxPushCurrent().
+ */
+ CUDA_ERROR_CONTEXT_ALREADY_CURRENT = 202,
+
+ /**
+ * This indicates that a map or register operation has failed.
+ */
+ CUDA_ERROR_MAP_FAILED = 205,
+
+ /**
+ * This indicates that an unmap or unregister operation has failed.
+ */
+ CUDA_ERROR_UNMAP_FAILED = 206,
+
+ /**
+ * This indicates that the specified array is currently mapped and thus
+ * cannot be destroyed.
+ */
+ CUDA_ERROR_ARRAY_IS_MAPPED = 207,
+
+ /**
+ * This indicates that the resource is already mapped.
+ */
+ CUDA_ERROR_ALREADY_MAPPED = 208,
+
+ /**
+ * This indicates that there is no kernel image available that is suitable
+ * for the device. This can occur when a user specifies code generation
+ * options for a particular CUDA source file that do not include the
+ * corresponding device configuration.
+ */
+ CUDA_ERROR_NO_BINARY_FOR_GPU = 209,
+
+ /**
+ * This indicates that a resource has already been acquired.
+ */
+ CUDA_ERROR_ALREADY_ACQUIRED = 210,
+
+ /**
+ * This indicates that a resource is not mapped.
+ */
+ CUDA_ERROR_NOT_MAPPED = 211,
+
+ /**
+ * This indicates that a mapped resource is not available for access as an
+ * array.
+ */
+ CUDA_ERROR_NOT_MAPPED_AS_ARRAY = 212,
+
+ /**
+ * This indicates that a mapped resource is not available for access as a
+ * pointer.
+ */
+ CUDA_ERROR_NOT_MAPPED_AS_POINTER = 213,
+
+ /**
+ * This indicates that an uncorrectable ECC error was detected during
+ * execution.
+ */
+ CUDA_ERROR_ECC_UNCORRECTABLE = 214,
+
+ /**
+ * This indicates that the ::CUlimit passed to the API call is not
+ * supported by the active device.
+ */
+ CUDA_ERROR_UNSUPPORTED_LIMIT = 215,
+
+ /**
+ * This indicates that the ::CUcontext passed to the API call can
+ * only be bound to a single CPU thread at a time but is already
+ * bound to a CPU thread.
+ */
+ CUDA_ERROR_CONTEXT_ALREADY_IN_USE = 216,
+
+ /**
+ * This indicates that peer access is not supported across the given
+ * devices.
+ */
+ CUDA_ERROR_PEER_ACCESS_UNSUPPORTED = 217,
+
+ /**
+ * This indicates that a PTX JIT compilation failed.
+ */
+ CUDA_ERROR_INVALID_PTX = 218,
+
+ /**
+ * This indicates an error with OpenGL or DirectX context.
+ */
+ CUDA_ERROR_INVALID_GRAPHICS_CONTEXT = 219,
+
+ /**
+ * This indicates that an uncorrectable NVLink error was detected during the
+ * execution.
+ */
+ CUDA_ERROR_NVLINK_UNCORRECTABLE = 220,
+
+ /**
+ * This indicates that the PTX JIT compiler library was not found.
+ */
+ CUDA_ERROR_JIT_COMPILER_NOT_FOUND = 221,
+
+ /**
+ * This indicates that the provided PTX was compiled with an unsupported toolchain.
+ */
+
+ CUDA_ERROR_UNSUPPORTED_PTX_VERSION = 222,
+
+ /**
+ * This indicates that the PTX JIT compilation was disabled.
+ */
+ CUDA_ERROR_JIT_COMPILATION_DISABLED = 223,
+
+ /**
+ * This indicates that the ::CUexecAffinityType passed to the API call is not
+ * supported by the active device.
+ */
+ CUDA_ERROR_UNSUPPORTED_EXEC_AFFINITY = 224,
+
+ /**
+ * This indicates that the code to be compiled by the PTX JIT contains
+ * unsupported call to cudaDeviceSynchronize.
+ */
+ CUDA_ERROR_UNSUPPORTED_DEVSIDE_SYNC = 225,
+
+ /**
+ * This indicates that an exception occurred on the device that is now
+ * contained by the GPU's error containment capability. Common causes are -
+ * a. Certain types of invalid accesses of peer GPU memory over nvlink
+ * b. Certain classes of hardware errors
+ * This leaves the process in an inconsistent state and any further CUDA
+ * work will return the same error. To continue using CUDA, the process must
+ * be terminated and relaunched.
+ */
+ CUDA_ERROR_CONTAINED = 226,
+
+ /**
+ * This indicates that the device kernel source is invalid. This includes
+ * compilation/linker errors encountered in device code or user error.
+ */
+ CUDA_ERROR_INVALID_SOURCE = 300,
+
+ /**
+ * This indicates that the file specified was not found.
+ */
+ CUDA_ERROR_FILE_NOT_FOUND = 301,
+
+ /**
+ * This indicates that a link to a shared object failed to resolve.
+ */
+ CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND = 302,
+
+ /**
+ * This indicates that initialization of a shared object failed.
+ */
+ CUDA_ERROR_SHARED_OBJECT_INIT_FAILED = 303,
+
+ /**
+ * This indicates that an OS call failed.
+ */
+ CUDA_ERROR_OPERATING_SYSTEM = 304,
+
+ /**
+ * This indicates that a resource handle passed to the API call was not
+ * valid. Resource handles are opaque types like ::CUstream and ::CUevent.
+ */
+ CUDA_ERROR_INVALID_HANDLE = 400,
+
+ /**
+ * This indicates that a resource required by the API call is not in a
+ * valid state to perform the requested operation.
+ */
+ CUDA_ERROR_ILLEGAL_STATE = 401,
+
+ /**
+ * This indicates an attempt was made to introspect an object in a way that
+ * would discard semantically important information. This is either due to
+ * the object using funtionality newer than the API version used to
+ * introspect it or omission of optional return arguments.
+ */
+ CUDA_ERROR_LOSSY_QUERY = 402,
+
+ /**
+ * This indicates that a named symbol was not found. Examples of symbols
+ * are global/constant variable names, driver function names, texture names,
+ * and surface names.
+ */
+ CUDA_ERROR_NOT_FOUND = 500,
+
+ /**
+ * This indicates that asynchronous operations issued previously have not
+ * completed yet. This result is not actually an error, but must be indicated
+ * differently than ::CUDA_SUCCESS (which indicates completion). Calls that
+ * may return this value include ::cuEventQuery() and ::cuStreamQuery().
+ */
+ CUDA_ERROR_NOT_READY = 600,
+
+ /**
+ * While executing a kernel, the device encountered a
+ * load or store instruction on an invalid memory address.
+ * This leaves the process in an inconsistent state and any further CUDA work
+ * will return the same error. To continue using CUDA, the process must be terminated
+ * and relaunched.
+ */
+ CUDA_ERROR_ILLEGAL_ADDRESS = 700,
+
+ /**
+ * This indicates that a launch did not occur because it did not have
+ * appropriate resources. This error usually indicates that the user has
+ * attempted to pass too many arguments to the device kernel, or the
+ * kernel launch specifies too many threads for the kernel's register
+ * count. Passing arguments of the wrong size (i.e. a 64-bit pointer
+ * when a 32-bit int is expected) is equivalent to passing too many
+ * arguments and can also result in this error.
+ */
+ CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES = 701,
+
+ /**
+ * This indicates that the device kernel took too long to execute. This can
+ * only occur if timeouts are enabled - see the device attribute
+ * ::CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT for more information.
+ * This leaves the process in an inconsistent state and any further CUDA work
+ * will return the same error. To continue using CUDA, the process must be terminated
+ * and relaunched.
+ */
+ CUDA_ERROR_LAUNCH_TIMEOUT = 702,
+
+ /**
+ * This error indicates a kernel launch that uses an incompatible texturing
+ * mode.
+ */
+ CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING = 703,
+
+ /**
+ * This error indicates that a call to ::cuCtxEnablePeerAccess() is
+ * trying to re-enable peer access to a context which has already
+ * had peer access to it enabled.
+ */
+ CUDA_ERROR_PEER_ACCESS_ALREADY_ENABLED = 704,
+
+ /**
+ * This error indicates that ::cuCtxDisablePeerAccess() is
+ * trying to disable peer access which has not been enabled yet
+ * via ::cuCtxEnablePeerAccess().
+ */
+ CUDA_ERROR_PEER_ACCESS_NOT_ENABLED = 705,
+
+ /**
+ * This error indicates that the primary context for the specified device
+ * has already been initialized.
+ */
+ CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE = 708,
+
+ /**
+ * This error indicates that the context current to the calling thread
+ * has been destroyed using ::cuCtxDestroy, or is a primary context which
+ * has not yet been initialized.
+ */
+ CUDA_ERROR_CONTEXT_IS_DESTROYED = 709,
+
+ /**
+ * A device-side assert triggered during kernel execution. The context
+ * cannot be used anymore, and must be destroyed. All existing device
+ * memory allocations from this context are invalid and must be
+ * reconstructed if the program is to continue using CUDA.
+ */
+ CUDA_ERROR_ASSERT = 710,
+
+ /**
+ * This error indicates that the hardware resources required to enable
+ * peer access have been exhausted for one or more of the devices
+ * passed to ::cuCtxEnablePeerAccess().
+ */
+ CUDA_ERROR_TOO_MANY_PEERS = 711,
+
+ /**
+ * This error indicates that the memory range passed to ::cuMemHostRegister()
+ * has already been registered.
+ */
+ CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED = 712,
+
+ /**
+ * This error indicates that the pointer passed to ::cuMemHostUnregister()
+ * does not correspond to any currently registered memory region.
+ */
+ CUDA_ERROR_HOST_MEMORY_NOT_REGISTERED = 713,
+
+ /**
+ * While executing a kernel, the device encountered a stack error.
+ * This can be due to stack corruption or exceeding the stack size limit.
+ * This leaves the process in an inconsistent state and any further CUDA work
+ * will return the same error. To continue using CUDA, the process must be terminated
+ * and relaunched.
+ */
+ CUDA_ERROR_HARDWARE_STACK_ERROR = 714,
+
+ /**
+ * While executing a kernel, the device encountered an illegal instruction.
+ * This leaves the process in an inconsistent state and any further CUDA work
+ * will return the same error. To continue using CUDA, the process must be terminated
+ * and relaunched.
+ */
+ CUDA_ERROR_ILLEGAL_INSTRUCTION = 715,
+
+ /**
+ * While executing a kernel, the device encountered a load or store instruction
+ * on a memory address which is not aligned.
+ * This leaves the process in an inconsistent state and any further CUDA work
+ * will return the same error. To continue using CUDA, the process must be terminated
+ * and relaunched.
+ */
+ CUDA_ERROR_MISALIGNED_ADDRESS = 716,
+
+ /**
+ * While executing a kernel, the device encountered an instruction
+ * which can only operate on memory locations in certain address spaces
+ * (global, shared, or local), but was supplied a memory address not
+ * belonging to an allowed address space.
+ * This leaves the process in an inconsistent state and any further CUDA work
+ * will return the same error. To continue using CUDA, the process must be terminated
+ * and relaunched.
+ */
+ CUDA_ERROR_INVALID_ADDRESS_SPACE = 717,
+
+ /**
+ * While executing a kernel, the device program counter wrapped its address space.
+ * This leaves the process in an inconsistent state and any further CUDA work
+ * will return the same error. To continue using CUDA, the process must be terminated
+ * and relaunched.
+ */
+ CUDA_ERROR_INVALID_PC = 718,
+
+ /**
+ * An exception occurred on the device while executing a kernel. Common
+ * causes include dereferencing an invalid device pointer and accessing
+ * out of bounds shared memory. Less common cases can be system specific - more
+ * information about these cases can be found in the system specific user guide.
+ * This leaves the process in an inconsistent state and any further CUDA work
+ * will return the same error. To continue using CUDA, the process must be terminated
+ * and relaunched.
+ */
+ CUDA_ERROR_LAUNCH_FAILED = 719,
+
+ /**
+ * This error indicates that the number of blocks launched per grid for a kernel that was
+ * launched via either ::cuLaunchCooperativeKernel or ::cuLaunchCooperativeKernelMultiDevice
+ * exceeds the maximum number of blocks as allowed by ::cuOccupancyMaxActiveBlocksPerMultiprocessor
+ * or ::cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags times the number of multiprocessors
+ * as specified by the device attribute ::CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT.
+ */
+ CUDA_ERROR_COOPERATIVE_LAUNCH_TOO_LARGE = 720,
+
+ /**
+ * An exception occurred on the device while exiting a kernel using tensor memory: the
+ * tensor memory was not completely deallocated. This leaves the process in an inconsistent
+ * state and any further CUDA work will return the same error. To continue using CUDA, the
+ * process must be terminated and relaunched.
+ */
+ CUDA_ERROR_TENSOR_MEMORY_LEAK = 721,
+
+ /**
+ * This error indicates that the attempted operation is not permitted.
+ */
+ CUDA_ERROR_NOT_PERMITTED = 800,
+
+ /**
+ * This error indicates that the attempted operation is not supported
+ * on the current system or device.
+ */
+ CUDA_ERROR_NOT_SUPPORTED = 801,
+
+ /**
+ * This error indicates that the system is not yet ready to start any CUDA
+ * work. To continue using CUDA, verify the system configuration is in a
+ * valid state and all required driver daemons are actively running.
+ * More information about this error can be found in the system specific
+ * user guide.
+ */
+ CUDA_ERROR_SYSTEM_NOT_READY = 802,
+
+ /**
+ * This error indicates that there is a mismatch between the versions of
+ * the display driver and the CUDA driver. Refer to the compatibility documentation
+ * for supported versions.
+ */
+ CUDA_ERROR_SYSTEM_DRIVER_MISMATCH = 803,
+
+ /**
+ * This error indicates that the system was upgraded to run with forward compatibility
+ * but the visible hardware detected by CUDA does not support this configuration.
+ * Refer to the compatibility documentation for the supported hardware matrix or ensure
+ * that only supported hardware is visible during initialization via the CUDA_VISIBLE_DEVICES
+ * environment variable.
+ */
+ CUDA_ERROR_COMPAT_NOT_SUPPORTED_ON_DEVICE = 804,
+
+ /**
+ * This error indicates that the MPS client failed to connect to the MPS control daemon or the MPS server.
+ */
+ CUDA_ERROR_MPS_CONNECTION_FAILED = 805,
+
+ /**
+ * This error indicates that the remote procedural call between the MPS server and the MPS client failed.
+ */
+ CUDA_ERROR_MPS_RPC_FAILURE = 806,
+
+ /**
+ * This error indicates that the MPS server is not ready to accept new MPS client requests.
+ * This error can be returned when the MPS server is in the process of recovering from a fatal failure.
+ */
+ CUDA_ERROR_MPS_SERVER_NOT_READY = 807,
+
+ /**
+ * This error indicates that the hardware resources required to create MPS client have been exhausted.
+ */
+ CUDA_ERROR_MPS_MAX_CLIENTS_REACHED = 808,
+
+ /**
+ * This error indicates the the hardware resources required to support device connections have been exhausted.
+ */
+ CUDA_ERROR_MPS_MAX_CONNECTIONS_REACHED = 809,
+
+ /**
+ * This error indicates that the MPS client has been terminated by the server. To continue using CUDA, the process must be terminated and relaunched.
+ */
+ CUDA_ERROR_MPS_CLIENT_TERMINATED = 810,
+
+ /**
+ * This error indicates that the module is using CUDA Dynamic Parallelism, but the current configuration, like MPS, does not support it.
+ */
+ CUDA_ERROR_CDP_NOT_SUPPORTED = 811,
+
+ /**
+ * This error indicates that a module contains an unsupported interaction between different versions of CUDA Dynamic Parallelism.
+ */
+ CUDA_ERROR_CDP_VERSION_MISMATCH = 812,
+
+ /**
+ * This error indicates that the operation is not permitted when
+ * the stream is capturing.
+ */
+ CUDA_ERROR_STREAM_CAPTURE_UNSUPPORTED = 900,
+
+ /**
+ * This error indicates that the current capture sequence on the stream
+ * has been invalidated due to a previous error.
+ */
+ CUDA_ERROR_STREAM_CAPTURE_INVALIDATED = 901,
+
+ /**
+ * This error indicates that the operation would have resulted in a merge
+ * of two independent capture sequences.
+ */
+ CUDA_ERROR_STREAM_CAPTURE_MERGE = 902,
+
+ /**
+ * This error indicates that the capture was not initiated in this stream.
+ */
+ CUDA_ERROR_STREAM_CAPTURE_UNMATCHED = 903,
+
+ /**
+ * This error indicates that the capture sequence contains a fork that was
+ * not joined to the primary stream.
+ */
+ CUDA_ERROR_STREAM_CAPTURE_UNJOINED = 904,
+
+ /**
+ * This error indicates that a dependency would have been created which
+ * crosses the capture sequence boundary. Only implicit in-stream ordering
+ * dependencies are allowed to cross the boundary.
+ */
+ CUDA_ERROR_STREAM_CAPTURE_ISOLATION = 905,
+
+ /**
+ * This error indicates a disallowed implicit dependency on a current capture
+ * sequence from cudaStreamLegacy.
+ */
+ CUDA_ERROR_STREAM_CAPTURE_IMPLICIT = 906,
+
+ /**
+ * This error indicates that the operation is not permitted on an event which
+ * was last recorded in a capturing stream.
+ */
+ CUDA_ERROR_CAPTURED_EVENT = 907,
+
+ /**
+ * A stream capture sequence not initiated with the ::CU_STREAM_CAPTURE_MODE_RELAXED
+ * argument to ::cuStreamBeginCapture was passed to ::cuStreamEndCapture in a
+ * different thread.
+ */
+ CUDA_ERROR_STREAM_CAPTURE_WRONG_THREAD = 908,
+
+ /**
+ * This error indicates that the timeout specified for the wait operation has lapsed.
+ */
+ CUDA_ERROR_TIMEOUT = 909,
+
+ /**
+ * This error indicates that the graph update was not performed because it included
+ * changes which violated constraints specific to instantiated graph update.
+ */
+ CUDA_ERROR_GRAPH_EXEC_UPDATE_FAILURE = 910,
+
+ /**
+ * This indicates that an async error has occurred in a device outside of CUDA.
+ * If CUDA was waiting for an external device's signal before consuming shared data,
+ * the external device signaled an error indicating that the data is not valid for
+ * consumption. This leaves the process in an inconsistent state and any further CUDA
+ * work will return the same error. To continue using CUDA, the process must be
+ * terminated and relaunched.
+ */
+ CUDA_ERROR_EXTERNAL_DEVICE = 911,
+
+ /**
+ * Indicates a kernel launch error due to cluster misconfiguration.
+ */
+ CUDA_ERROR_INVALID_CLUSTER_SIZE = 912,
+
+ /**
+ * Indiciates a function handle is not loaded when calling an API that requires
+ * a loaded function.
+ */
+ CUDA_ERROR_FUNCTION_NOT_LOADED = 913,
+
+ /**
+ * This error indicates one or more resources passed in are not valid resource
+ * types for the operation.
+ */
+ CUDA_ERROR_INVALID_RESOURCE_TYPE = 914,
+
+ /**
+ * This error indicates one or more resources are insufficient or non-applicable for
+ * the operation.
+ */
+ CUDA_ERROR_INVALID_RESOURCE_CONFIGURATION = 915,
+
+ /**
+ * This error indicates that an error happened during the key rotation
+ * sequence.
+ */
+ CUDA_ERROR_KEY_ROTATION = 916,
+
+ /**
+ * This indicates that an unknown internal error has occurred.
+ */
+ CUDA_ERROR_UNKNOWN = 999
} CUresult;
typedef enum CUstream_flags_enum {
diff --git a/offload/plugins-nextgen/cuda/src/rtl.cpp b/offload/plugins-nextgen/cuda/src/rtl.cpp
index 3181fa26935f9..d0b0d37cba163 100644
--- a/offload/plugins-nextgen/cuda/src/rtl.cpp
+++ b/offload/plugins-nextgen/cuda/src/rtl.cpp
@@ -1858,17 +1858,51 @@ static Error Plugin::check(int32_t Code, const char *ErrFmt, ArgsTy... Args) {
if (Ret != CUDA_SUCCESS)
REPORT() << "Unrecognized " GETNAME(TARGET_NAME) " error code " << Code;
- // TODO: Add more entries to this switch
ErrorCode OffloadErrCode;
switch (ResultCode) {
+ case CUDA_ERROR_INVALID_VALUE:
+ OffloadErrCode = ErrorCode::INVALID_VALUE;
+ break;
+ case CUDA_ERROR_OUT_OF_MEMORY:
+ case CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES:
+ OffloadErrCode = ErrorCode::OUT_OF_RESOURCES;
+ break;
+ case CUDA_ERROR_NOT_INITIALIZED:
+ case CUDA_ERROR_DEINITIALIZED:
+ OffloadErrCode = ErrorCode::UNINITIALIZED;
+ break;
+ case CUDA_ERROR_NO_DEVICE:
+ case CUDA_ERROR_INVALID_DEVICE:
+ OffloadErrCode = ErrorCode::INVALID_DEVICE;
+ break;
+ case CUDA_ERROR_INVALID_IMAGE:
+ case CUDA_ERROR_INVALID_SOURCE:
+ case CUDA_ERROR_INVALID_PTX:
+ case CUDA_ERROR_UNSUPPORTED_PTX_VERSION:
+ OffloadErrCode = ErrorCode::INVALID_BINARY;
+ break;
+ case CUDA_ERROR_FILE_NOT_FOUND:
+ case CUDA_ERROR_OPERATING_SYSTEM:
+ OffloadErrCode = ErrorCode::HOST_IO;
+ break;
+ case CUDA_ERROR_JIT_COMPILER_NOT_FOUND:
+ OffloadErrCode = ErrorCode::HOST_TOOL_NOT_FOUND;
+ break;
case CUDA_ERROR_NOT_FOUND:
+ case CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND:
OffloadErrCode = ErrorCode::NOT_FOUND;
break;
+ case CUDA_ERROR_NOT_SUPPORTED:
+ OffloadErrCode = ErrorCode::UNSUPPORTED;
+ break;
+ case CUDA_ERROR_INVALID_HANDLE:
+ case CUDA_ERROR_INVALID_CONTEXT:
+ OffloadErrCode = ErrorCode::INVALID_ARGUMENT;
+ break;
default:
OffloadErrCode = ErrorCode::UNKNOWN;
}
- // TODO: Create a map for CUDA error codes to Offload error codes
return Plugin::error(OffloadErrCode, ErrFmt, Args..., Desc);
}
diff --git a/offload/plugins-nextgen/level_zero/include/L0Trace.h b/offload/plugins-nextgen/level_zero/include/L0Trace.h
index 0dd55e01c71ef..6f97b72e4c636 100644
--- a/offload/plugins-nextgen/level_zero/include/L0Trace.h
+++ b/offload/plugins-nextgen/level_zero/include/L0Trace.h
@@ -13,6 +13,7 @@
#ifndef OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0TRACE_H
#define OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0TRACE_H
+#include "OffloadError.h"
#include "Shared/Debug.h"
#include "omptarget.h"
#include <string>
@@ -40,7 +41,7 @@ using namespace llvm::offload::debug;
#define CALL_ZE_RET_ERROR_MTX(Fn, Mtx, ...) \
CALL_ZE_RET_MTX( \
- Plugin::error(ErrorCode::UNKNOWN, "%s failed with error %d, %s", \
+ Plugin::error(getOffloadErrorCode(rc), "%s failed with error %d, %s", \
#Fn, rc, getZeErrorName(rc)), Fn, Mtx, __VA_ARGS__)
/// For thread-safe functions.
@@ -57,7 +58,7 @@ using namespace llvm::offload::debug;
#define CALL_ZE_RET_ERROR(Fn, ...) \
CALL_ZE_RET( \
- Plugin::error(ErrorCode::UNKNOWN, "%s failed with error %d, %s", \
+ Plugin::error(getOffloadErrorCode(rc), "%s failed with error %d, %s", \
#Fn, rc, getZeErrorName(rc)), Fn, __VA_ARGS__)
#define CALL_ZE_SILENT(Fn, ...) \
@@ -72,7 +73,7 @@ using namespace llvm::offload::debug;
ze_result_t rc; \
CALL_ZE(rc, Fn, __VA_ARGS__); \
if (rc != ZE_RESULT_SUCCESS) { \
- HandleErrFn(Plugin::error(ErrorCode::UNKNOWN, "%s failed with error %d," \
+ HandleErrFn(Plugin::error(getOffloadErrorCode(rc), "%s failed with error %d," \
" %s", #Fn, rc, getZeErrorName(rc))); \
} \
} while (0)
@@ -83,7 +84,7 @@ using namespace llvm::offload::debug;
CALL_ZE(rc, Fn, __VA_ARGS__); \
if (rc != ZE_RESULT_SUCCESS) { \
Err = joinErrors(std::move(Err), \
- Plugin::error(ErrorCode::UNKNOWN, "%s failed with error %d," \
+ Plugin::error(getOffloadErrorCode(rc), "%s failed with error %d," \
" %s", #Fn, rc, getZeErrorName(rc))); \
} \
} while (0)
@@ -98,7 +99,7 @@ using namespace llvm::offload::debug;
#define CALL_ZE_EXT_RET_ERROR(Device, Name, ...) \
CALL_ZE_EXT_SILENT_RET(Device, \
- Plugin::error(ErrorCode::UNKNOWN, "%s failed with code %d, %s", \
+ Plugin::error(getOffloadErrorCode(rc), "%s failed with code %d, %s", \
#Name, rc, getZeErrorName(rc)), Name, __VA_ARGS__)
#define FOREACH_ZE_ERROR_CODE(Fn) \
@@ -153,4 +154,59 @@ inline const char *getZeErrorName(int32_t Error) {
}
}
+inline error::ErrorCode getOffloadErrorCode(ze_result_t Error) {
+ switch (Error) {
+ case ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY:
+ case ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY:
+ return error::ErrorCode::OUT_OF_RESOURCES;
+ case ZE_RESULT_ERROR_MODULE_BUILD_FAILURE:
+ return error::ErrorCode::COMPILE_FAILURE;
+ case ZE_RESULT_ERROR_MODULE_LINK_FAILURE:
+ return error::ErrorCode::LINK_FAILURE;
+ case ZE_RESULT_ERROR_DEVICE_LOST:
+ case ZE_RESULT_ERROR_DEVICE_REQUIRES_RESET:
+ case ZE_RESULT_ERROR_DEVICE_IN_LOW_POWER_STATE:
+ return error::ErrorCode::BACKEND_FAILURE;
+ case ZE_RESULT_ERROR_UNINITIALIZED:
+ return error::ErrorCode::UNINITIALIZED;
+ case ZE_RESULT_ERROR_NOT_AVAILABLE:
+ case ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE:
+ case ZE_RESULT_ERROR_UNSUPPORTED_VERSION:
+ case ZE_RESULT_ERROR_UNSUPPORTED_FEATURE:
+ case ZE_RESULT_ERROR_UNSUPPORTED_SIZE:
+ case ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT:
+ case ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION:
+ case ZE_RESULT_ERROR_UNSUPPORTED_IMAGE_FORMAT:
+ return error::ErrorCode::UNSUPPORTED;
+ case ZE_RESULT_ERROR_INVALID_NULL_HANDLE:
+ return error::ErrorCode::INVALID_NULL_HANDLE;
+ case ZE_RESULT_ERROR_INVALID_NULL_POINTER:
+ return error::ErrorCode::INVALID_NULL_POINTER;
+ case ZE_RESULT_ERROR_INVALID_SIZE:
+ return error::ErrorCode::INVALID_SIZE;
+ case ZE_RESULT_ERROR_INVALID_ENUMERATION:
+ return error::ErrorCode::INVALID_ENUMERATION;
+ case ZE_RESULT_ERROR_INVALID_NATIVE_BINARY:
+ case ZE_RESULT_ERROR_INVALID_MODULE_UNLINKED:
+ return error::ErrorCode::INVALID_BINARY;
+ case ZE_RESULT_ERROR_INVALID_GLOBAL_NAME:
+ case ZE_RESULT_ERROR_INVALID_KERNEL_NAME:
+ case ZE_RESULT_ERROR_INVALID_FUNCTION_NAME:
+ return error::ErrorCode::NOT_FOUND;
+ case ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS:
+ case ZE_RESULT_ERROR_INVALID_ARGUMENT:
+ case ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT:
+ case ZE_RESULT_ERROR_INVALID_GROUP_SIZE_DIMENSION:
+ case ZE_RESULT_ERROR_INVALID_GLOBAL_WIDTH_DIMENSION:
+ case ZE_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_INDEX:
+ case ZE_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_SIZE:
+ case ZE_RESULT_ERROR_INVALID_KERNEL_ATTRIBUTE_VALUE:
+ case ZE_RESULT_ERROR_INVALID_COMMAND_LIST_TYPE:
+ case ZE_RESULT_ERROR_OVERLAPPING_REGIONS:
+ return error::ErrorCode::INVALID_ARGUMENT;
+ default:
+ return error::ErrorCode::UNKNOWN;
+ }
+}
+
#endif // OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0TRACE_H
diff --git a/offload/unittests/OffloadAPI/common/Environment.cpp b/offload/unittests/OffloadAPI/common/Environment.cpp
index bb23a01ef6a05..9d2b16ea9647a 100644
--- a/offload/unittests/OffloadAPI/common/Environment.cpp
+++ b/offload/unittests/OffloadAPI/common/Environment.cpp
@@ -181,14 +181,18 @@ const std::string DeviceBinsDirectory = DEVICE_CODE_PATH;
bool TestEnvironment::loadDeviceBinary(
const std::string &BinaryName, ol_device_handle_t Device,
- std::unique_ptr<MemoryBuffer> &BinaryOut) {
-
- // Get the platform type
- ol_platform_handle_t Platform;
- olGetDeviceInfo(Device, OL_DEVICE_INFO_PLATFORM, sizeof(Platform), &Platform);
- ol_platform_backend_t Backend = OL_PLATFORM_BACKEND_UNKNOWN;
- olGetPlatformInfo(Platform, OL_PLATFORM_INFO_BACKEND, sizeof(Backend),
- &Backend);
+ std::unique_ptr<MemoryBuffer> &BinaryOut,
+ ol_platform_backend_t OverrideBackend) {
+
+ ol_platform_backend_t Backend = OverrideBackend;
+ // Without an explicit override, derive the binary's backend from the device.
+ if (Backend == OL_PLATFORM_BACKEND_UNKNOWN) {
+ ol_platform_handle_t Platform;
+ olGetDeviceInfo(Device, OL_DEVICE_INFO_PLATFORM, sizeof(Platform),
+ &Platform);
+ olGetPlatformInfo(Platform, OL_PLATFORM_INFO_BACKEND, sizeof(Backend),
+ &Backend);
+ }
std::string FileExtension;
if (Backend == OL_PLATFORM_BACKEND_AMDGPU) {
FileExtension = ".amdgpu.bin";
diff --git a/offload/unittests/OffloadAPI/common/Environment.hpp b/offload/unittests/OffloadAPI/common/Environment.hpp
index 7946a827fe2f4..7c5b75e40a689 100644
--- a/offload/unittests/OffloadAPI/common/Environment.hpp
+++ b/offload/unittests/OffloadAPI/common/Environment.hpp
@@ -22,5 +22,7 @@ struct Device {
const std::vector<Device> &getDevices();
ol_device_handle_t getHostDevice();
bool loadDeviceBinary(const std::string &BinaryName, ol_device_handle_t Device,
- std::unique_ptr<llvm::MemoryBuffer> &BinaryOut);
+ std::unique_ptr<llvm::MemoryBuffer> &BinaryOut,
+ ol_platform_backend_t OverrideBackend =
+ OL_PLATFORM_BACKEND_UNKNOWN);
} // namespace TestEnvironment
diff --git a/offload/unittests/OffloadAPI/program/olCreateProgram.cpp b/offload/unittests/OffloadAPI/program/olCreateProgram.cpp
index 02e82fe530ea3..5e81c9368375f 100644
--- a/offload/unittests/OffloadAPI/program/olCreateProgram.cpp
+++ b/offload/unittests/OffloadAPI/program/olCreateProgram.cpp
@@ -61,3 +61,59 @@ TEST_P(olCreateProgramTest, NullOutputProgram) {
olCreateProgram(Device, DeviceBin->getBufferStart(),
DeviceBin->getBufferSize(), nullptr));
}
+
+TEST_P(olCreateProgramTest, ZeroSizeBinary) {
+ std::unique_ptr<llvm::MemoryBuffer> DeviceBin;
+ ASSERT_TRUE(TestEnvironment::loadDeviceBinary("foo", Device, DeviceBin));
+ ASSERT_GT(DeviceBin->getBufferSize(), 0lu);
+
+ ol_program_handle_t Program = nullptr;
+
+ ASSERT_ERROR(OL_ERRC_INVALID_BINARY,
+ olCreateProgram(Device, DeviceBin->getBufferStart(), 0,
+ &Program));
+ ASSERT_EQ(Program, nullptr);
+}
+
+TEST_P(olCreateProgramTest, InvalidBinary) {
+ const char InvalidBinary[] = "not an offload binary";
+
+ ol_program_handle_t Program = nullptr;
+ ASSERT_ERROR(OL_ERRC_INVALID_BINARY,
+ olCreateProgram(Device, InvalidBinary,
+ sizeof(InvalidBinary) - 1, &Program));
+ ASSERT_EQ(Program, nullptr);
+}
+
+TEST_P(olCreateProgramTest, TruncatedBinary) {
+ std::unique_ptr<llvm::MemoryBuffer> DeviceBin;
+ ASSERT_TRUE(TestEnvironment::loadDeviceBinary("foo", Device, DeviceBin));
+ ASSERT_GT(DeviceBin->getBufferSize(), 1lu);
+
+ ol_program_handle_t Program = nullptr;
+ ASSERT_ERROR(OL_ERRC_INVALID_BINARY,
+ olCreateProgram(Device, DeviceBin->getBufferStart(),
+ DeviceBin->getBufferSize() / 2, &Program));
+ ASSERT_EQ(Program, nullptr);
+}
+
+TEST_P(olCreateProgramTest, WrongArchitecture) {
+ // Pick a backend different from the device's own, so the loaded binary is
+ // valid but built for the wrong architecture.
+ ol_platform_backend_t Backend = getPlatformBackend();
+ ol_platform_backend_t ForeignBackend =
+ Backend == OL_PLATFORM_BACKEND_CUDA ? OL_PLATFORM_BACKEND_AMDGPU
+ : OL_PLATFORM_BACKEND_CUDA;
+
+ std::unique_ptr<llvm::MemoryBuffer> ForeignBin;
+ if (!TestEnvironment::loadDeviceBinary("foo", Device, ForeignBin,
+ ForeignBackend))
+ GTEST_SKIP() << "No foreign-architecture binary available for this build.";
+ ASSERT_GT(ForeignBin->getBufferSize(), 0lu);
+
+ ol_program_handle_t Program = nullptr;
+ ASSERT_ERROR(OL_ERRC_INVALID_BINARY,
+ olCreateProgram(Device, ForeignBin->getBufferStart(),
+ ForeignBin->getBufferSize(), &Program));
+ ASSERT_EQ(Program, nullptr);
+}
>From 484364937aa754f620b83b74fbc48ca1c8aaf296 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Trusi=C5=82=C5=82o?= <113amper at gmail.com>
Date: Mon, 22 Jun 2026 15:55:06 +0000
Subject: [PATCH 3/7] [offload[ remove redundant cuda errc comments
---
offload/liboffload/API/Program.td | 6 +-
.../plugins-nextgen/cuda/dynamic_cuda/cuda.h | 759 +++---------------
2 files changed, 105 insertions(+), 660 deletions(-)
diff --git a/offload/liboffload/API/Program.td b/offload/liboffload/API/Program.td
index 7e11b3d8e331e..89b9dffbe0a48 100644
--- a/offload/liboffload/API/Program.td
+++ b/offload/liboffload/API/Program.td
@@ -21,7 +21,11 @@ def olCreateProgram : Function {
Param<"size_t", "ProgDataSize", "size of the program binary in bytes", PARAM_IN>,
Param<"ol_program_handle_t*", "Program", "output pointer for the created program", PARAM_OUT>
];
- let returns = [];
+ let returns = [
+ Return<"OL_ERRC_INVALID_BINARY", [
+ "If the buffer described by `ProgData` and `ProgDataSize` is not a valid binary image for the platform."
+ ]>,
+ ];
}
def olIsValidBinary : Function {
diff --git a/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h b/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h
index 2624a636592bf..8597ea0055d78 100644
--- a/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h
+++ b/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h
@@ -109,665 +109,106 @@ typedef CUmemAllocationProp_v1 CUmemAllocationProp;
* Error codes (as of CUDA 12.1)
*/
typedef enum cudaError_enum {
- /**
- * The API call returned with no errors. In the case of query calls, this
- * also means that the operation being queried is complete (see
- * ::cuEventQuery() and ::cuStreamQuery()).
- */
- CUDA_SUCCESS = 0,
-
- /**
- * This indicates that one or more of the parameters passed to the API call
- * is not within an acceptable range of values.
- */
- CUDA_ERROR_INVALID_VALUE = 1,
-
- /**
- * The API call failed because it was unable to allocate enough memory or
- * other resources to perform the requested operation.
- */
- CUDA_ERROR_OUT_OF_MEMORY = 2,
-
- /**
- * This indicates that the CUDA driver has not been initialized with
- * ::cuInit() or that initialization has failed.
- */
- CUDA_ERROR_NOT_INITIALIZED = 3,
-
- /**
- * This indicates that the CUDA driver is in the process of shutting down.
- */
- CUDA_ERROR_DEINITIALIZED = 4,
-
- /**
- * This indicates profiler is not initialized for this run. This can
- * happen when the application is running with external profiling tools
- * like visual profiler.
- */
- CUDA_ERROR_PROFILER_DISABLED = 5,
-
- /**
- * \deprecated
- * This error return is deprecated as of CUDA 5.0. It is no longer an error
- * to attempt to enable/disable the profiling via ::cuProfilerStart or
- * ::cuProfilerStop without initialization.
- */
- CUDA_ERROR_PROFILER_NOT_INITIALIZED = 6,
-
- /**
- * \deprecated
- * This error return is deprecated as of CUDA 5.0. It is no longer an error
- * to call cuProfilerStart() when profiling is already enabled.
- */
- CUDA_ERROR_PROFILER_ALREADY_STARTED = 7,
-
- /**
- * \deprecated
- * This error return is deprecated as of CUDA 5.0. It is no longer an error
- * to call cuProfilerStop() when profiling is already disabled.
- */
- CUDA_ERROR_PROFILER_ALREADY_STOPPED = 8,
-
- /**
- * This indicates that the CUDA driver that the application has loaded is a
- * stub library. Applications that run with the stub rather than a real
- * driver loaded will result in CUDA API returning this error.
- */
- CUDA_ERROR_STUB_LIBRARY = 34,
-
- /**
- * This indicates that requested CUDA device is unavailable at the current
- * time. Devices are often unavailable due to use of
- * ::CU_COMPUTEMODE_EXCLUSIVE_PROCESS or ::CU_COMPUTEMODE_PROHIBITED.
- */
- CUDA_ERROR_DEVICE_UNAVAILABLE = 46,
-
- /**
- * This indicates that no CUDA-capable devices were detected by the installed
- * CUDA driver.
- */
- CUDA_ERROR_NO_DEVICE = 100,
-
- /**
- * This indicates that the device ordinal supplied by the user does not
- * correspond to a valid CUDA device or that the action requested is
- * invalid for the specified device.
- */
- CUDA_ERROR_INVALID_DEVICE = 101,
-
- /**
- * This error indicates that the Grid license is not applied.
- */
- CUDA_ERROR_DEVICE_NOT_LICENSED = 102,
-
- /**
- * This indicates that the device kernel image is invalid. This can also
- * indicate an invalid CUDA module.
- */
- CUDA_ERROR_INVALID_IMAGE = 200,
-
- /**
- * This most frequently indicates that there is no context bound to the
- * current thread. This can also be returned if the context passed to an
- * API call is not a valid handle (such as a context that has had
- * ::cuCtxDestroy() invoked on it). This can also be returned if a user
- * mixes different API versions (i.e. 3010 context with 3020 API calls).
- * See ::cuCtxGetApiVersion() for more details.
- * This can also be returned if the green context passed to an API call
- * was not converted to a ::CUcontext using ::cuCtxFromGreenCtx API.
- */
- CUDA_ERROR_INVALID_CONTEXT = 201,
-
- /**
- * This indicated that the context being supplied as a parameter to the
- * API call was already the active context.
- * \deprecated
- * This error return is deprecated as of CUDA 3.2. It is no longer an
- * error to attempt to push the active context via ::cuCtxPushCurrent().
- */
- CUDA_ERROR_CONTEXT_ALREADY_CURRENT = 202,
-
- /**
- * This indicates that a map or register operation has failed.
- */
- CUDA_ERROR_MAP_FAILED = 205,
-
- /**
- * This indicates that an unmap or unregister operation has failed.
- */
- CUDA_ERROR_UNMAP_FAILED = 206,
-
- /**
- * This indicates that the specified array is currently mapped and thus
- * cannot be destroyed.
- */
- CUDA_ERROR_ARRAY_IS_MAPPED = 207,
-
- /**
- * This indicates that the resource is already mapped.
- */
- CUDA_ERROR_ALREADY_MAPPED = 208,
-
- /**
- * This indicates that there is no kernel image available that is suitable
- * for the device. This can occur when a user specifies code generation
- * options for a particular CUDA source file that do not include the
- * corresponding device configuration.
- */
- CUDA_ERROR_NO_BINARY_FOR_GPU = 209,
-
- /**
- * This indicates that a resource has already been acquired.
- */
- CUDA_ERROR_ALREADY_ACQUIRED = 210,
-
- /**
- * This indicates that a resource is not mapped.
- */
- CUDA_ERROR_NOT_MAPPED = 211,
-
- /**
- * This indicates that a mapped resource is not available for access as an
- * array.
- */
- CUDA_ERROR_NOT_MAPPED_AS_ARRAY = 212,
-
- /**
- * This indicates that a mapped resource is not available for access as a
- * pointer.
- */
- CUDA_ERROR_NOT_MAPPED_AS_POINTER = 213,
-
- /**
- * This indicates that an uncorrectable ECC error was detected during
- * execution.
- */
- CUDA_ERROR_ECC_UNCORRECTABLE = 214,
-
- /**
- * This indicates that the ::CUlimit passed to the API call is not
- * supported by the active device.
- */
- CUDA_ERROR_UNSUPPORTED_LIMIT = 215,
-
- /**
- * This indicates that the ::CUcontext passed to the API call can
- * only be bound to a single CPU thread at a time but is already
- * bound to a CPU thread.
- */
- CUDA_ERROR_CONTEXT_ALREADY_IN_USE = 216,
-
- /**
- * This indicates that peer access is not supported across the given
- * devices.
- */
- CUDA_ERROR_PEER_ACCESS_UNSUPPORTED = 217,
-
- /**
- * This indicates that a PTX JIT compilation failed.
- */
- CUDA_ERROR_INVALID_PTX = 218,
-
- /**
- * This indicates an error with OpenGL or DirectX context.
- */
- CUDA_ERROR_INVALID_GRAPHICS_CONTEXT = 219,
-
- /**
- * This indicates that an uncorrectable NVLink error was detected during the
- * execution.
- */
- CUDA_ERROR_NVLINK_UNCORRECTABLE = 220,
-
- /**
- * This indicates that the PTX JIT compiler library was not found.
- */
- CUDA_ERROR_JIT_COMPILER_NOT_FOUND = 221,
-
- /**
- * This indicates that the provided PTX was compiled with an unsupported toolchain.
- */
-
- CUDA_ERROR_UNSUPPORTED_PTX_VERSION = 222,
-
- /**
- * This indicates that the PTX JIT compilation was disabled.
- */
- CUDA_ERROR_JIT_COMPILATION_DISABLED = 223,
-
- /**
- * This indicates that the ::CUexecAffinityType passed to the API call is not
- * supported by the active device.
- */
- CUDA_ERROR_UNSUPPORTED_EXEC_AFFINITY = 224,
-
- /**
- * This indicates that the code to be compiled by the PTX JIT contains
- * unsupported call to cudaDeviceSynchronize.
- */
- CUDA_ERROR_UNSUPPORTED_DEVSIDE_SYNC = 225,
-
- /**
- * This indicates that an exception occurred on the device that is now
- * contained by the GPU's error containment capability. Common causes are -
- * a. Certain types of invalid accesses of peer GPU memory over nvlink
- * b. Certain classes of hardware errors
- * This leaves the process in an inconsistent state and any further CUDA
- * work will return the same error. To continue using CUDA, the process must
- * be terminated and relaunched.
- */
- CUDA_ERROR_CONTAINED = 226,
-
- /**
- * This indicates that the device kernel source is invalid. This includes
- * compilation/linker errors encountered in device code or user error.
- */
- CUDA_ERROR_INVALID_SOURCE = 300,
-
- /**
- * This indicates that the file specified was not found.
- */
- CUDA_ERROR_FILE_NOT_FOUND = 301,
-
- /**
- * This indicates that a link to a shared object failed to resolve.
- */
- CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND = 302,
-
- /**
- * This indicates that initialization of a shared object failed.
- */
- CUDA_ERROR_SHARED_OBJECT_INIT_FAILED = 303,
-
- /**
- * This indicates that an OS call failed.
- */
- CUDA_ERROR_OPERATING_SYSTEM = 304,
-
- /**
- * This indicates that a resource handle passed to the API call was not
- * valid. Resource handles are opaque types like ::CUstream and ::CUevent.
- */
- CUDA_ERROR_INVALID_HANDLE = 400,
-
- /**
- * This indicates that a resource required by the API call is not in a
- * valid state to perform the requested operation.
- */
- CUDA_ERROR_ILLEGAL_STATE = 401,
-
- /**
- * This indicates an attempt was made to introspect an object in a way that
- * would discard semantically important information. This is either due to
- * the object using funtionality newer than the API version used to
- * introspect it or omission of optional return arguments.
- */
- CUDA_ERROR_LOSSY_QUERY = 402,
-
- /**
- * This indicates that a named symbol was not found. Examples of symbols
- * are global/constant variable names, driver function names, texture names,
- * and surface names.
- */
- CUDA_ERROR_NOT_FOUND = 500,
-
- /**
- * This indicates that asynchronous operations issued previously have not
- * completed yet. This result is not actually an error, but must be indicated
- * differently than ::CUDA_SUCCESS (which indicates completion). Calls that
- * may return this value include ::cuEventQuery() and ::cuStreamQuery().
- */
- CUDA_ERROR_NOT_READY = 600,
-
- /**
- * While executing a kernel, the device encountered a
- * load or store instruction on an invalid memory address.
- * This leaves the process in an inconsistent state and any further CUDA work
- * will return the same error. To continue using CUDA, the process must be terminated
- * and relaunched.
- */
- CUDA_ERROR_ILLEGAL_ADDRESS = 700,
-
- /**
- * This indicates that a launch did not occur because it did not have
- * appropriate resources. This error usually indicates that the user has
- * attempted to pass too many arguments to the device kernel, or the
- * kernel launch specifies too many threads for the kernel's register
- * count. Passing arguments of the wrong size (i.e. a 64-bit pointer
- * when a 32-bit int is expected) is equivalent to passing too many
- * arguments and can also result in this error.
- */
- CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES = 701,
-
- /**
- * This indicates that the device kernel took too long to execute. This can
- * only occur if timeouts are enabled - see the device attribute
- * ::CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT for more information.
- * This leaves the process in an inconsistent state and any further CUDA work
- * will return the same error. To continue using CUDA, the process must be terminated
- * and relaunched.
- */
- CUDA_ERROR_LAUNCH_TIMEOUT = 702,
-
- /**
- * This error indicates a kernel launch that uses an incompatible texturing
- * mode.
- */
- CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING = 703,
-
- /**
- * This error indicates that a call to ::cuCtxEnablePeerAccess() is
- * trying to re-enable peer access to a context which has already
- * had peer access to it enabled.
- */
- CUDA_ERROR_PEER_ACCESS_ALREADY_ENABLED = 704,
-
- /**
- * This error indicates that ::cuCtxDisablePeerAccess() is
- * trying to disable peer access which has not been enabled yet
- * via ::cuCtxEnablePeerAccess().
- */
- CUDA_ERROR_PEER_ACCESS_NOT_ENABLED = 705,
-
- /**
- * This error indicates that the primary context for the specified device
- * has already been initialized.
- */
- CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE = 708,
-
- /**
- * This error indicates that the context current to the calling thread
- * has been destroyed using ::cuCtxDestroy, or is a primary context which
- * has not yet been initialized.
- */
- CUDA_ERROR_CONTEXT_IS_DESTROYED = 709,
-
- /**
- * A device-side assert triggered during kernel execution. The context
- * cannot be used anymore, and must be destroyed. All existing device
- * memory allocations from this context are invalid and must be
- * reconstructed if the program is to continue using CUDA.
- */
- CUDA_ERROR_ASSERT = 710,
-
- /**
- * This error indicates that the hardware resources required to enable
- * peer access have been exhausted for one or more of the devices
- * passed to ::cuCtxEnablePeerAccess().
- */
- CUDA_ERROR_TOO_MANY_PEERS = 711,
-
- /**
- * This error indicates that the memory range passed to ::cuMemHostRegister()
- * has already been registered.
- */
- CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED = 712,
-
- /**
- * This error indicates that the pointer passed to ::cuMemHostUnregister()
- * does not correspond to any currently registered memory region.
- */
- CUDA_ERROR_HOST_MEMORY_NOT_REGISTERED = 713,
-
- /**
- * While executing a kernel, the device encountered a stack error.
- * This can be due to stack corruption or exceeding the stack size limit.
- * This leaves the process in an inconsistent state and any further CUDA work
- * will return the same error. To continue using CUDA, the process must be terminated
- * and relaunched.
- */
- CUDA_ERROR_HARDWARE_STACK_ERROR = 714,
-
- /**
- * While executing a kernel, the device encountered an illegal instruction.
- * This leaves the process in an inconsistent state and any further CUDA work
- * will return the same error. To continue using CUDA, the process must be terminated
- * and relaunched.
- */
- CUDA_ERROR_ILLEGAL_INSTRUCTION = 715,
-
- /**
- * While executing a kernel, the device encountered a load or store instruction
- * on a memory address which is not aligned.
- * This leaves the process in an inconsistent state and any further CUDA work
- * will return the same error. To continue using CUDA, the process must be terminated
- * and relaunched.
- */
- CUDA_ERROR_MISALIGNED_ADDRESS = 716,
-
- /**
- * While executing a kernel, the device encountered an instruction
- * which can only operate on memory locations in certain address spaces
- * (global, shared, or local), but was supplied a memory address not
- * belonging to an allowed address space.
- * This leaves the process in an inconsistent state and any further CUDA work
- * will return the same error. To continue using CUDA, the process must be terminated
- * and relaunched.
- */
- CUDA_ERROR_INVALID_ADDRESS_SPACE = 717,
-
- /**
- * While executing a kernel, the device program counter wrapped its address space.
- * This leaves the process in an inconsistent state and any further CUDA work
- * will return the same error. To continue using CUDA, the process must be terminated
- * and relaunched.
- */
- CUDA_ERROR_INVALID_PC = 718,
-
- /**
- * An exception occurred on the device while executing a kernel. Common
- * causes include dereferencing an invalid device pointer and accessing
- * out of bounds shared memory. Less common cases can be system specific - more
- * information about these cases can be found in the system specific user guide.
- * This leaves the process in an inconsistent state and any further CUDA work
- * will return the same error. To continue using CUDA, the process must be terminated
- * and relaunched.
- */
- CUDA_ERROR_LAUNCH_FAILED = 719,
-
- /**
- * This error indicates that the number of blocks launched per grid for a kernel that was
- * launched via either ::cuLaunchCooperativeKernel or ::cuLaunchCooperativeKernelMultiDevice
- * exceeds the maximum number of blocks as allowed by ::cuOccupancyMaxActiveBlocksPerMultiprocessor
- * or ::cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags times the number of multiprocessors
- * as specified by the device attribute ::CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT.
- */
- CUDA_ERROR_COOPERATIVE_LAUNCH_TOO_LARGE = 720,
-
- /**
- * An exception occurred on the device while exiting a kernel using tensor memory: the
- * tensor memory was not completely deallocated. This leaves the process in an inconsistent
- * state and any further CUDA work will return the same error. To continue using CUDA, the
- * process must be terminated and relaunched.
- */
- CUDA_ERROR_TENSOR_MEMORY_LEAK = 721,
-
- /**
- * This error indicates that the attempted operation is not permitted.
- */
- CUDA_ERROR_NOT_PERMITTED = 800,
-
- /**
- * This error indicates that the attempted operation is not supported
- * on the current system or device.
- */
- CUDA_ERROR_NOT_SUPPORTED = 801,
-
- /**
- * This error indicates that the system is not yet ready to start any CUDA
- * work. To continue using CUDA, verify the system configuration is in a
- * valid state and all required driver daemons are actively running.
- * More information about this error can be found in the system specific
- * user guide.
- */
- CUDA_ERROR_SYSTEM_NOT_READY = 802,
-
- /**
- * This error indicates that there is a mismatch between the versions of
- * the display driver and the CUDA driver. Refer to the compatibility documentation
- * for supported versions.
- */
- CUDA_ERROR_SYSTEM_DRIVER_MISMATCH = 803,
-
- /**
- * This error indicates that the system was upgraded to run with forward compatibility
- * but the visible hardware detected by CUDA does not support this configuration.
- * Refer to the compatibility documentation for the supported hardware matrix or ensure
- * that only supported hardware is visible during initialization via the CUDA_VISIBLE_DEVICES
- * environment variable.
- */
- CUDA_ERROR_COMPAT_NOT_SUPPORTED_ON_DEVICE = 804,
-
- /**
- * This error indicates that the MPS client failed to connect to the MPS control daemon or the MPS server.
- */
- CUDA_ERROR_MPS_CONNECTION_FAILED = 805,
-
- /**
- * This error indicates that the remote procedural call between the MPS server and the MPS client failed.
- */
- CUDA_ERROR_MPS_RPC_FAILURE = 806,
-
- /**
- * This error indicates that the MPS server is not ready to accept new MPS client requests.
- * This error can be returned when the MPS server is in the process of recovering from a fatal failure.
- */
- CUDA_ERROR_MPS_SERVER_NOT_READY = 807,
-
- /**
- * This error indicates that the hardware resources required to create MPS client have been exhausted.
- */
- CUDA_ERROR_MPS_MAX_CLIENTS_REACHED = 808,
-
- /**
- * This error indicates the the hardware resources required to support device connections have been exhausted.
- */
- CUDA_ERROR_MPS_MAX_CONNECTIONS_REACHED = 809,
-
- /**
- * This error indicates that the MPS client has been terminated by the server. To continue using CUDA, the process must be terminated and relaunched.
- */
- CUDA_ERROR_MPS_CLIENT_TERMINATED = 810,
-
- /**
- * This error indicates that the module is using CUDA Dynamic Parallelism, but the current configuration, like MPS, does not support it.
- */
- CUDA_ERROR_CDP_NOT_SUPPORTED = 811,
-
- /**
- * This error indicates that a module contains an unsupported interaction between different versions of CUDA Dynamic Parallelism.
- */
- CUDA_ERROR_CDP_VERSION_MISMATCH = 812,
-
- /**
- * This error indicates that the operation is not permitted when
- * the stream is capturing.
- */
- CUDA_ERROR_STREAM_CAPTURE_UNSUPPORTED = 900,
-
- /**
- * This error indicates that the current capture sequence on the stream
- * has been invalidated due to a previous error.
- */
- CUDA_ERROR_STREAM_CAPTURE_INVALIDATED = 901,
-
- /**
- * This error indicates that the operation would have resulted in a merge
- * of two independent capture sequences.
- */
- CUDA_ERROR_STREAM_CAPTURE_MERGE = 902,
-
- /**
- * This error indicates that the capture was not initiated in this stream.
- */
- CUDA_ERROR_STREAM_CAPTURE_UNMATCHED = 903,
-
- /**
- * This error indicates that the capture sequence contains a fork that was
- * not joined to the primary stream.
- */
- CUDA_ERROR_STREAM_CAPTURE_UNJOINED = 904,
-
- /**
- * This error indicates that a dependency would have been created which
- * crosses the capture sequence boundary. Only implicit in-stream ordering
- * dependencies are allowed to cross the boundary.
- */
- CUDA_ERROR_STREAM_CAPTURE_ISOLATION = 905,
-
- /**
- * This error indicates a disallowed implicit dependency on a current capture
- * sequence from cudaStreamLegacy.
- */
- CUDA_ERROR_STREAM_CAPTURE_IMPLICIT = 906,
-
- /**
- * This error indicates that the operation is not permitted on an event which
- * was last recorded in a capturing stream.
- */
- CUDA_ERROR_CAPTURED_EVENT = 907,
-
- /**
- * A stream capture sequence not initiated with the ::CU_STREAM_CAPTURE_MODE_RELAXED
- * argument to ::cuStreamBeginCapture was passed to ::cuStreamEndCapture in a
- * different thread.
- */
- CUDA_ERROR_STREAM_CAPTURE_WRONG_THREAD = 908,
-
- /**
- * This error indicates that the timeout specified for the wait operation has lapsed.
- */
- CUDA_ERROR_TIMEOUT = 909,
-
- /**
- * This error indicates that the graph update was not performed because it included
- * changes which violated constraints specific to instantiated graph update.
- */
- CUDA_ERROR_GRAPH_EXEC_UPDATE_FAILURE = 910,
-
- /**
- * This indicates that an async error has occurred in a device outside of CUDA.
- * If CUDA was waiting for an external device's signal before consuming shared data,
- * the external device signaled an error indicating that the data is not valid for
- * consumption. This leaves the process in an inconsistent state and any further CUDA
- * work will return the same error. To continue using CUDA, the process must be
- * terminated and relaunched.
- */
- CUDA_ERROR_EXTERNAL_DEVICE = 911,
-
- /**
- * Indicates a kernel launch error due to cluster misconfiguration.
- */
- CUDA_ERROR_INVALID_CLUSTER_SIZE = 912,
-
- /**
- * Indiciates a function handle is not loaded when calling an API that requires
- * a loaded function.
- */
- CUDA_ERROR_FUNCTION_NOT_LOADED = 913,
-
- /**
- * This error indicates one or more resources passed in are not valid resource
- * types for the operation.
- */
- CUDA_ERROR_INVALID_RESOURCE_TYPE = 914,
-
- /**
- * This error indicates one or more resources are insufficient or non-applicable for
- * the operation.
- */
- CUDA_ERROR_INVALID_RESOURCE_CONFIGURATION = 915,
-
- /**
- * This error indicates that an error happened during the key rotation
- * sequence.
- */
- CUDA_ERROR_KEY_ROTATION = 916,
-
- /**
- * This indicates that an unknown internal error has occurred.
- */
- CUDA_ERROR_UNKNOWN = 999
+ CUDA_SUCCESS = 0,
+ CUDA_ERROR_INVALID_VALUE = 1,
+ CUDA_ERROR_OUT_OF_MEMORY = 2,
+ CUDA_ERROR_NOT_INITIALIZED = 3,
+ CUDA_ERROR_DEINITIALIZED = 4,
+ CUDA_ERROR_PROFILER_DISABLED = 5,
+ CUDA_ERROR_PROFILER_NOT_INITIALIZED = 6,
+ CUDA_ERROR_PROFILER_ALREADY_STARTED = 7,
+ CUDA_ERROR_PROFILER_ALREADY_STOPPED = 8,
+ CUDA_ERROR_STUB_LIBRARY = 34,
+ CUDA_ERROR_DEVICE_UNAVAILABLE = 46,
+ CUDA_ERROR_NO_DEVICE = 100,
+ CUDA_ERROR_INVALID_DEVICE = 101,
+ CUDA_ERROR_DEVICE_NOT_LICENSED = 102,
+ CUDA_ERROR_INVALID_IMAGE = 200,
+ CUDA_ERROR_INVALID_CONTEXT = 201,
+ CUDA_ERROR_CONTEXT_ALREADY_CURRENT = 202,
+ CUDA_ERROR_MAP_FAILED = 205,
+ CUDA_ERROR_UNMAP_FAILED = 206,
+ CUDA_ERROR_ARRAY_IS_MAPPED = 207,
+ CUDA_ERROR_ALREADY_MAPPED = 208,
+ CUDA_ERROR_NO_BINARY_FOR_GPU = 209,
+ CUDA_ERROR_ALREADY_ACQUIRED = 210,
+ CUDA_ERROR_NOT_MAPPED = 211,
+ CUDA_ERROR_NOT_MAPPED_AS_ARRAY = 212,
+ CUDA_ERROR_NOT_MAPPED_AS_POINTER = 213,
+ CUDA_ERROR_ECC_UNCORRECTABLE = 214,
+ CUDA_ERROR_UNSUPPORTED_LIMIT = 215,
+ CUDA_ERROR_CONTEXT_ALREADY_IN_USE = 216,
+ CUDA_ERROR_PEER_ACCESS_UNSUPPORTED = 217,
+ CUDA_ERROR_INVALID_PTX = 218,
+ CUDA_ERROR_INVALID_GRAPHICS_CONTEXT = 219,
+ CUDA_ERROR_NVLINK_UNCORRECTABLE = 220,
+ CUDA_ERROR_JIT_COMPILER_NOT_FOUND = 221,
+ CUDA_ERROR_UNSUPPORTED_PTX_VERSION = 222,
+ CUDA_ERROR_JIT_COMPILATION_DISABLED = 223,
+ CUDA_ERROR_UNSUPPORTED_EXEC_AFFINITY = 224,
+ CUDA_ERROR_UNSUPPORTED_DEVSIDE_SYNC = 225,
+ CUDA_ERROR_CONTAINED = 226,
+ CUDA_ERROR_INVALID_SOURCE = 300,
+ CUDA_ERROR_FILE_NOT_FOUND = 301,
+ CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND = 302,
+ CUDA_ERROR_SHARED_OBJECT_INIT_FAILED = 303,
+ CUDA_ERROR_OPERATING_SYSTEM = 304,
+ CUDA_ERROR_INVALID_HANDLE = 400,
+ CUDA_ERROR_ILLEGAL_STATE = 401,
+ CUDA_ERROR_LOSSY_QUERY = 402,
+ CUDA_ERROR_NOT_FOUND = 500,
+ CUDA_ERROR_NOT_READY = 600,
+ CUDA_ERROR_ILLEGAL_ADDRESS = 700,
+ CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES = 701,
+ CUDA_ERROR_LAUNCH_TIMEOUT = 702,
+ CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING = 703,
+ CUDA_ERROR_PEER_ACCESS_ALREADY_ENABLED = 704,
+ CUDA_ERROR_PEER_ACCESS_NOT_ENABLED = 705,
+ CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE = 708,
+ CUDA_ERROR_CONTEXT_IS_DESTROYED = 709,
+ CUDA_ERROR_ASSERT = 710,
+ CUDA_ERROR_TOO_MANY_PEERS = 711,
+ CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED = 712,
+ CUDA_ERROR_HOST_MEMORY_NOT_REGISTERED = 713,
+ CUDA_ERROR_HARDWARE_STACK_ERROR = 714,
+ CUDA_ERROR_ILLEGAL_INSTRUCTION = 715,
+ CUDA_ERROR_MISALIGNED_ADDRESS = 716,
+ CUDA_ERROR_INVALID_ADDRESS_SPACE = 717,
+ CUDA_ERROR_INVALID_PC = 718,
+ CUDA_ERROR_LAUNCH_FAILED = 719,
+ CUDA_ERROR_COOPERATIVE_LAUNCH_TOO_LARGE = 720,
+ CUDA_ERROR_TENSOR_MEMORY_LEAK = 721,
+ CUDA_ERROR_NOT_PERMITTED = 800,
+ CUDA_ERROR_NOT_SUPPORTED = 801,
+ CUDA_ERROR_SYSTEM_NOT_READY = 802,
+ CUDA_ERROR_SYSTEM_DRIVER_MISMATCH = 803,
+ CUDA_ERROR_COMPAT_NOT_SUPPORTED_ON_DEVICE = 804,
+ CUDA_ERROR_MPS_CONNECTION_FAILED = 805,
+ CUDA_ERROR_MPS_RPC_FAILURE = 806,
+ CUDA_ERROR_MPS_SERVER_NOT_READY = 807,
+ CUDA_ERROR_MPS_MAX_CLIENTS_REACHED = 808,
+ CUDA_ERROR_MPS_MAX_CONNECTIONS_REACHED = 809,
+ CUDA_ERROR_MPS_CLIENT_TERMINATED = 810,
+ CUDA_ERROR_CDP_NOT_SUPPORTED = 811,
+ CUDA_ERROR_CDP_VERSION_MISMATCH = 812,
+ CUDA_ERROR_STREAM_CAPTURE_UNSUPPORTED = 900,
+ CUDA_ERROR_STREAM_CAPTURE_INVALIDATED = 901,
+ CUDA_ERROR_STREAM_CAPTURE_MERGE = 902,
+ CUDA_ERROR_STREAM_CAPTURE_UNMATCHED = 903,
+ CUDA_ERROR_STREAM_CAPTURE_UNJOINED = 904,
+ CUDA_ERROR_STREAM_CAPTURE_ISOLATION = 905,
+ CUDA_ERROR_STREAM_CAPTURE_IMPLICIT = 906,
+ CUDA_ERROR_CAPTURED_EVENT = 907,
+ CUDA_ERROR_STREAM_CAPTURE_WRONG_THREAD = 908,
+ CUDA_ERROR_TIMEOUT = 909,
+ CUDA_ERROR_GRAPH_EXEC_UPDATE_FAILURE = 910,
+ CUDA_ERROR_EXTERNAL_DEVICE = 911,
+ CUDA_ERROR_INVALID_CLUSTER_SIZE = 912,
+ CUDA_ERROR_FUNCTION_NOT_LOADED = 913,
+ CUDA_ERROR_INVALID_RESOURCE_TYPE = 914,
+ CUDA_ERROR_INVALID_RESOURCE_CONFIGURATION = 915,
+ CUDA_ERROR_KEY_ROTATION = 916,
+ CUDA_ERROR_UNKNOWN = 999
} CUresult;
typedef enum CUstream_flags_enum {
>From 101697ef0b06844b247b938fb0453261b5ca4b96 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Trusi=C5=82=C5=82o?= <113amper at gmail.com>
Date: Mon, 22 Jun 2026 16:08:30 +0000
Subject: [PATCH 4/7] [offload] extract error code mapping to helpers
---
offload/plugins-nextgen/amdgpu/src/rtl.cpp | 45 ++++++++--------
offload/plugins-nextgen/cuda/src/rtl.cpp | 60 ++++++++++------------
2 files changed, 47 insertions(+), 58 deletions(-)
diff --git a/offload/plugins-nextgen/amdgpu/src/rtl.cpp b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
index f270417b0f2b2..f4d7aea1db6bb 100644
--- a/offload/plugins-nextgen/amdgpu/src/rtl.cpp
+++ b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
@@ -4368,47 +4368,44 @@ Error AMDGPUKernelTy::printLaunchInfoDetails(GenericDeviceTy &GenericDevice,
return Plugin::success();
}
-template <typename... ArgsTy>
-static Error Plugin::check(int32_t Code, const char *ErrFmt, ArgsTy... Args) {
- hsa_status_t ResultCode = static_cast<hsa_status_t>(Code);
- if (ResultCode == HSA_STATUS_SUCCESS || ResultCode == HSA_STATUS_INFO_BREAK)
- return Plugin::success();
-
- const char *Desc = "unknown error";
- hsa_status_t Ret = hsa_status_string(ResultCode, &Desc);
- if (Ret != HSA_STATUS_SUCCESS)
- REPORT() << "Unrecognized " GETNAME(TARGET_NAME) " error code " << Code;
-
- ErrorCode OffloadErrCode;
+/// Map an HSA status code to the corresponding offload error code.
+static ErrorCode getOffloadErrorCode(hsa_status_t ResultCode) {
switch (ResultCode) {
case HSA_STATUS_ERROR_INVALID_SYMBOL_NAME:
case HSA_STATUS_ERROR_INVALID_ISA_NAME:
- OffloadErrCode = ErrorCode::NOT_FOUND;
- break;
+ return ErrorCode::NOT_FOUND;
case HSA_STATUS_ERROR_INVALID_CODE_OBJECT:
case HSA_STATUS_ERROR_INVALID_ISA:
case HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS:
- OffloadErrCode = ErrorCode::INVALID_BINARY;
- break;
+ return ErrorCode::INVALID_BINARY;
case HSA_STATUS_ERROR_OUT_OF_RESOURCES:
- OffloadErrCode = ErrorCode::OUT_OF_RESOURCES;
- break;
+ return ErrorCode::OUT_OF_RESOURCES;
case HSA_STATUS_ERROR_NOT_INITIALIZED:
- OffloadErrCode = ErrorCode::UNINITIALIZED;
- break;
+ return ErrorCode::UNINITIALIZED;
case HSA_STATUS_ERROR_INVALID_ARGUMENT:
case HSA_STATUS_ERROR_INVALID_ALLOCATION:
case HSA_STATUS_ERROR_INVALID_AGENT:
case HSA_STATUS_ERROR_INVALID_REGION:
case HSA_STATUS_ERROR_INVALID_QUEUE:
case HSA_STATUS_ERROR_INVALID_INDEX:
- OffloadErrCode = ErrorCode::INVALID_ARGUMENT;
- break;
+ return ErrorCode::INVALID_ARGUMENT;
default:
- OffloadErrCode = ErrorCode::UNKNOWN;
+ return ErrorCode::UNKNOWN;
}
+}
+
+template <typename... ArgsTy>
+static Error Plugin::check(int32_t Code, const char *ErrFmt, ArgsTy... Args) {
+ hsa_status_t ResultCode = static_cast<hsa_status_t>(Code);
+ if (ResultCode == HSA_STATUS_SUCCESS || ResultCode == HSA_STATUS_INFO_BREAK)
+ return Plugin::success();
+
+ const char *Desc = "unknown error";
+ hsa_status_t Ret = hsa_status_string(ResultCode, &Desc);
+ if (Ret != HSA_STATUS_SUCCESS)
+ REPORT() << "Unrecognized " GETNAME(TARGET_NAME) " error code " << Code;
- return Plugin::error(OffloadErrCode, ErrFmt, Args..., Desc);
+ return Plugin::error(getOffloadErrorCode(ResultCode), ErrFmt, Args..., Desc);
}
Expected<void *> AMDGPUMemoryManagerTy::allocate(size_t Size, void *HstPtr,
diff --git a/offload/plugins-nextgen/cuda/src/rtl.cpp b/offload/plugins-nextgen/cuda/src/rtl.cpp
index d0b0d37cba163..b89d5b4d79be3 100644
--- a/offload/plugins-nextgen/cuda/src/rtl.cpp
+++ b/offload/plugins-nextgen/cuda/src/rtl.cpp
@@ -1847,63 +1847,55 @@ Error CUDADeviceTy::dataExchangeImpl(const void *SrcPtr,
return Plugin::check(Res, "error in cuMemcpyDtoDAsync: %s");
}
-template <typename... ArgsTy>
-static Error Plugin::check(int32_t Code, const char *ErrFmt, ArgsTy... Args) {
- CUresult ResultCode = static_cast<CUresult>(Code);
- if (ResultCode == CUDA_SUCCESS)
- return Plugin::success();
-
- const char *Desc = "Unknown error";
- CUresult Ret = cuGetErrorString(ResultCode, &Desc);
- if (Ret != CUDA_SUCCESS)
- REPORT() << "Unrecognized " GETNAME(TARGET_NAME) " error code " << Code;
-
- ErrorCode OffloadErrCode;
+/// Map a CUDA driver result code to the corresponding offload error code.
+static ErrorCode getOffloadErrorCode(CUresult ResultCode) {
switch (ResultCode) {
case CUDA_ERROR_INVALID_VALUE:
- OffloadErrCode = ErrorCode::INVALID_VALUE;
- break;
+ return ErrorCode::INVALID_VALUE;
case CUDA_ERROR_OUT_OF_MEMORY:
case CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES:
- OffloadErrCode = ErrorCode::OUT_OF_RESOURCES;
- break;
+ return ErrorCode::OUT_OF_RESOURCES;
case CUDA_ERROR_NOT_INITIALIZED:
case CUDA_ERROR_DEINITIALIZED:
- OffloadErrCode = ErrorCode::UNINITIALIZED;
- break;
+ return ErrorCode::UNINITIALIZED;
case CUDA_ERROR_NO_DEVICE:
case CUDA_ERROR_INVALID_DEVICE:
- OffloadErrCode = ErrorCode::INVALID_DEVICE;
- break;
+ return ErrorCode::INVALID_DEVICE;
case CUDA_ERROR_INVALID_IMAGE:
case CUDA_ERROR_INVALID_SOURCE:
case CUDA_ERROR_INVALID_PTX:
case CUDA_ERROR_UNSUPPORTED_PTX_VERSION:
- OffloadErrCode = ErrorCode::INVALID_BINARY;
- break;
+ return ErrorCode::INVALID_BINARY;
case CUDA_ERROR_FILE_NOT_FOUND:
case CUDA_ERROR_OPERATING_SYSTEM:
- OffloadErrCode = ErrorCode::HOST_IO;
- break;
+ return ErrorCode::HOST_IO;
case CUDA_ERROR_JIT_COMPILER_NOT_FOUND:
- OffloadErrCode = ErrorCode::HOST_TOOL_NOT_FOUND;
- break;
+ return ErrorCode::HOST_TOOL_NOT_FOUND;
case CUDA_ERROR_NOT_FOUND:
case CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND:
- OffloadErrCode = ErrorCode::NOT_FOUND;
- break;
+ return ErrorCode::NOT_FOUND;
case CUDA_ERROR_NOT_SUPPORTED:
- OffloadErrCode = ErrorCode::UNSUPPORTED;
- break;
+ return ErrorCode::UNSUPPORTED;
case CUDA_ERROR_INVALID_HANDLE:
case CUDA_ERROR_INVALID_CONTEXT:
- OffloadErrCode = ErrorCode::INVALID_ARGUMENT;
- break;
+ return ErrorCode::INVALID_ARGUMENT;
default:
- OffloadErrCode = ErrorCode::UNKNOWN;
+ return ErrorCode::UNKNOWN;
}
+}
+
+template <typename... ArgsTy>
+static Error Plugin::check(int32_t Code, const char *ErrFmt, ArgsTy... Args) {
+ CUresult ResultCode = static_cast<CUresult>(Code);
+ if (ResultCode == CUDA_SUCCESS)
+ return Plugin::success();
+
+ const char *Desc = "Unknown error";
+ CUresult Ret = cuGetErrorString(ResultCode, &Desc);
+ if (Ret != CUDA_SUCCESS)
+ REPORT() << "Unrecognized " GETNAME(TARGET_NAME) " error code " << Code;
- return Plugin::error(OffloadErrCode, ErrFmt, Args..., Desc);
+ return Plugin::error(getOffloadErrorCode(ResultCode), ErrFmt, Args..., Desc);
}
} // namespace plugin
>From f550cd65eab57c108bcb786b245b5456ef0b2983 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Trusi=C5=82=C5=82o?= <113amper at gmail.com>
Date: Tue, 23 Jun 2026 07:39:30 +0000
Subject: [PATCH 5/7] [offload] remove redundant hsa errc comments
---
.../plugins-nextgen/amdgpu/dynamic_hsa/hsa.h | 83 -------------------
1 file changed, 83 deletions(-)
diff --git a/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h b/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h
index 5f7591cc23914..f66326a7f240e 100644
--- a/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h
+++ b/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h
@@ -29,114 +29,31 @@ extern "C" {
* @brief Status codes.
*/
typedef enum {
- /**
- * The function has been executed successfully.
- */
HSA_STATUS_SUCCESS = 0x0,
- /**
- * A traversal over a list of elements has been interrupted by the
- * application before completing.
- */
HSA_STATUS_INFO_BREAK = 0x1,
- /**
- * A generic error has occurred.
- */
HSA_STATUS_ERROR = 0x1000,
- /**
- * One of the actual arguments does not meet a precondition stated in the
- * documentation of the corresponding formal argument.
- */
HSA_STATUS_ERROR_INVALID_ARGUMENT = 0x1001,
- /**
- * The requested queue creation is not valid.
- */
HSA_STATUS_ERROR_INVALID_QUEUE_CREATION = 0x1002,
- /**
- * The requested allocation is not valid.
- */
HSA_STATUS_ERROR_INVALID_ALLOCATION = 0x1003,
- /**
- * The agent is invalid.
- */
HSA_STATUS_ERROR_INVALID_AGENT = 0x1004,
- /**
- * The memory region is invalid.
- */
HSA_STATUS_ERROR_INVALID_REGION = 0x1005,
- /**
- * The signal is invalid.
- */
HSA_STATUS_ERROR_INVALID_SIGNAL = 0x1006,
- /**
- * The queue is invalid.
- */
HSA_STATUS_ERROR_INVALID_QUEUE = 0x1007,
- /**
- * The HSA runtime failed to allocate the necessary resources. This error
- * may also occur when the HSA runtime needs to spawn threads or create
- * internal OS-specific events.
- */
HSA_STATUS_ERROR_OUT_OF_RESOURCES = 0x1008,
- /**
- * The AQL packet is malformed.
- */
HSA_STATUS_ERROR_INVALID_PACKET_FORMAT = 0x1009,
- /**
- * An error has been detected while releasing a resource.
- */
HSA_STATUS_ERROR_RESOURCE_FREE = 0x100A,
- /**
- * An API other than ::hsa_init has been invoked while the reference count
- * of the HSA runtime is 0.
- */
HSA_STATUS_ERROR_NOT_INITIALIZED = 0x100B,
- /**
- * The maximum reference count for the object has been reached.
- */
HSA_STATUS_ERROR_REFCOUNT_OVERFLOW = 0x100C,
- /**
- * The arguments passed to a functions are not compatible.
- */
HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS = 0x100D,
- /**
- * The index is invalid.
- */
HSA_STATUS_ERROR_INVALID_INDEX = 0x100E,
- /**
- * The instruction set architecture is invalid.
- */
HSA_STATUS_ERROR_INVALID_ISA = 0x100F,
- /**
- * The instruction set architecture name is invalid.
- */
HSA_STATUS_ERROR_INVALID_ISA_NAME = 0x1017,
- /**
- * The code object is invalid.
- */
HSA_STATUS_ERROR_INVALID_CODE_OBJECT = 0x1010,
- /**
- * The executable is invalid.
- */
HSA_STATUS_ERROR_INVALID_EXECUTABLE = 0x1011,
- /**
- * The executable is frozen.
- */
HSA_STATUS_ERROR_FROZEN_EXECUTABLE = 0x1012,
- /**
- * There is no symbol with the given name.
- */
HSA_STATUS_ERROR_INVALID_SYMBOL_NAME = 0x1013,
- /**
- * The variable is already defined.
- */
HSA_STATUS_ERROR_VARIABLE_ALREADY_DEFINED = 0x1014,
- /**
- * The variable is undefined.
- */
HSA_STATUS_ERROR_VARIABLE_UNDEFINED = 0x1015,
- /**
- * An HSAIL operation resulted on a hardware exception.
- */
HSA_STATUS_ERROR_EXCEPTION = 0x1016
} hsa_status_t;
>From edafb25a5d93289eebd2f43855f1d951360f4f5d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Trusi=C5=82=C5=82o?= <113amper at gmail.com>
Date: Tue, 30 Jun 2026 08:51:11 +0000
Subject: [PATCH 6/7] [offload] ensure invalid_binary on l0 compile failure
---
offload/liboffload/src/OffloadImpl.cpp | 11 ++++--
.../level_zero/src/L0Program.cpp | 37 +++++++++++--------
.../OffloadAPI/common/Environment.cpp | 20 +++++-----
.../OffloadAPI/common/Environment.hpp | 9 +++--
4 files changed, 43 insertions(+), 34 deletions(-)
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index d2b714ae657bf..460289d8110f2 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -1044,10 +1044,13 @@ Error olMemPrefetch_impl(ol_queue_handle_t Queue, size_t Count,
Error olCreateProgram_impl(ol_device_handle_t Device, const void *ProgData,
size_t ProgDataSize, ol_program_handle_t *Program) {
- // an empty image is not a valid binary
- // plugins behave differently given empty binaries - e.g. CUDA will map to INVALID_BINARY,
- // while L0 will map to INVALID_SIZE which is also associated with invalid kernel launch dims etc.
- // so we guard here for consistent behavior
+ // An empty image is not a valid binary.
+ // Plugins behave differently given empty binaries - e.g. CUDA will map to
+ // INVALID_BINARY, while L0 will map to INVALID_SIZE (which is also associated
+ // with invalid kernel launch dims etc.), so we guard here for consistent
+ // behavior.
+ // TODO: This should be part of the plugin interface contract so this check
+ // can be removed from here.
if (ProgDataSize == 0)
return createOffloadError(ErrorCode::INVALID_BINARY,
"provided binary image is empty");
diff --git a/offload/plugins-nextgen/level_zero/src/L0Program.cpp b/offload/plugins-nextgen/level_zero/src/L0Program.cpp
index f9089799ef9e9..4887f36776bb2 100644
--- a/offload/plugins-nextgen/level_zero/src/L0Program.cpp
+++ b/offload/plugins-nextgen/level_zero/src/L0Program.cpp
@@ -86,19 +86,22 @@ Error L0ProgramBuilderTy::addModule(size_t Size, const uint8_t *Image,
ModuleDesc.pInputModule = Image;
ModuleDesc.pBuildFlags = BuildOptions.c_str();
ModuleDesc.pConstants = &SpecConstants;
- Error CreateErrors = Error::success();
- auto handleError = [&](Error Err) {
- if (BuildLog)
- zeModuleBuildLogDestroy(BuildLog);
- CreateErrors = joinErrors(std::move(CreateErrors), std::move(Err));
- };
- CALL_ZE_HANDLE_ERROR(handleError, zeModuleCreate, l0Device.getZeContext(),
- l0Device.getZeDevice(), &ModuleDesc, &Module, &BuildLog);
- if (CreateErrors)
- return CreateErrors;
-
+ ze_result_t RC;
+ CALL_ZE(RC, zeModuleCreate, l0Device.getZeContext(), l0Device.getZeDevice(),
+ &ModuleDesc, &Module, &BuildLog);
if (BuildLog)
zeModuleBuildLogDestroy(BuildLog);
+ if (RC != ZE_RESULT_SUCCESS) {
+ // zeModuleCreate compiles/loads the provided image, so a build failure here
+ // means the image itself could not be loaded for this device (e.g. a
+ // truncated or malformed binary) rather than a generic JIT failure of an
+ // otherwise valid program. Report it as INVALID_BINARY in that case.
+ const auto ErrCode = RC == ZE_RESULT_ERROR_MODULE_BUILD_FAILURE
+ ? ErrorCode::INVALID_BINARY
+ : getOffloadErrorCode(RC);
+ return Plugin::error(ErrCode, "zeModuleCreate failed with error %d, %s", RC,
+ getZeErrorName(RC));
+ }
// Check if module link is required. We do not need this check for
// library module.
@@ -240,14 +243,14 @@ Error L0ProgramBuilderTy::buildModules(const std::string_view BuildOptions) {
auto InnerBinariesOrErr = llvm::object::OffloadBinary::create(Image);
if (!InnerBinariesOrErr)
return Plugin::error(
- ErrorCode::UNKNOWN, "Failed to parse inner OffloadBinary: %s",
+ ErrorCode::INVALID_BINARY, "Failed to parse inner OffloadBinary: %s",
llvm::toString(InnerBinariesOrErr.takeError()).c_str());
auto &InnerBinaries = *InnerBinariesOrErr;
// Should contain exactly one image
if (InnerBinaries.size() != 1)
- return Plugin::error(ErrorCode::UNKNOWN,
+ return Plugin::error(ErrorCode::INVALID_BINARY,
"Expected single inner OffloadBinary entry, got %zu",
InnerBinaries.size());
@@ -290,7 +293,7 @@ Error L0ProgramBuilderTy::buildModules(const std::string_view BuildOptions) {
ODBG(OLDT_Module) << "Loading native binary module";
ModuleFormat = ZE_MODULE_FORMAT_NATIVE;
} else {
- return Plugin::error(ErrorCode::UNKNOWN,
+ return Plugin::error(ErrorCode::INVALID_BINARY,
"Unsupported image kind %d in inner OffloadBinary",
static_cast<int>(ImageKind));
}
@@ -310,7 +313,8 @@ Error L0ProgramBuilderTy::buildModules(const std::string_view BuildOptions) {
uint64_t MajorVer, MinorVer;
if (!isValidOneOmpImage(Image.getBuffer(), MajorVer, MinorVer)) {
ODBG(OLDT_Module) << "Warning: image is not a valid oneAPI OpenMP image.";
- return Plugin::error(ErrorCode::UNKNOWN, "Invalid oneAPI OpenMP image");
+ return Plugin::error(ErrorCode::INVALID_BINARY,
+ "Invalid oneAPI OpenMP image");
}
ODBG(OLDT_Module) << "Processing ELF-wrapped SPIR-V image";
@@ -523,7 +527,8 @@ Error L0ProgramBuilderTy::buildModules(const std::string_view BuildOptions) {
return Plugin::success();
}
- return Plugin::error(ErrorCode::UNKNOWN, "Failed to create program modules.");
+ return Plugin::error(ErrorCode::INVALID_BINARY,
+ "Failed to create program modules.");
}
Expected<std::unique_ptr<MemoryBuffer>> L0ProgramBuilderTy::getELF() {
diff --git a/offload/unittests/OffloadAPI/common/Environment.cpp b/offload/unittests/OffloadAPI/common/Environment.cpp
index 9d2b16ea9647a..89660a5d6a7b4 100644
--- a/offload/unittests/OffloadAPI/common/Environment.cpp
+++ b/offload/unittests/OffloadAPI/common/Environment.cpp
@@ -13,6 +13,7 @@
#include <OffloadAPI.h>
#include <cstdlib>
#include <fstream>
+#include <optional>
using namespace llvm;
@@ -182,17 +183,16 @@ const std::string DeviceBinsDirectory = DEVICE_CODE_PATH;
bool TestEnvironment::loadDeviceBinary(
const std::string &BinaryName, ol_device_handle_t Device,
std::unique_ptr<MemoryBuffer> &BinaryOut,
- ol_platform_backend_t OverrideBackend) {
+ std::optional<ol_platform_backend_t> OverrideBackend) {
+ ol_platform_backend_t DeviceBackend = OL_PLATFORM_BACKEND_UNKNOWN;
+
+ ol_platform_handle_t Platform;
+ olGetDeviceInfo(Device, OL_DEVICE_INFO_PLATFORM, sizeof(Platform), &Platform);
+ olGetPlatformInfo(Platform, OL_PLATFORM_INFO_BACKEND, sizeof(DeviceBackend),
+ &DeviceBackend);
+
+ ol_platform_backend_t Backend = OverrideBackend.value_or(DeviceBackend);
- ol_platform_backend_t Backend = OverrideBackend;
- // Without an explicit override, derive the binary's backend from the device.
- if (Backend == OL_PLATFORM_BACKEND_UNKNOWN) {
- ol_platform_handle_t Platform;
- olGetDeviceInfo(Device, OL_DEVICE_INFO_PLATFORM, sizeof(Platform),
- &Platform);
- olGetPlatformInfo(Platform, OL_PLATFORM_INFO_BACKEND, sizeof(Backend),
- &Backend);
- }
std::string FileExtension;
if (Backend == OL_PLATFORM_BACKEND_AMDGPU) {
FileExtension = ".amdgpu.bin";
diff --git a/offload/unittests/OffloadAPI/common/Environment.hpp b/offload/unittests/OffloadAPI/common/Environment.hpp
index 7c5b75e40a689..507cbb85debe0 100644
--- a/offload/unittests/OffloadAPI/common/Environment.hpp
+++ b/offload/unittests/OffloadAPI/common/Environment.hpp
@@ -11,6 +11,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include <OffloadAPI.h>
#include <gtest/gtest.h>
+#include <optional>
namespace TestEnvironment {
@@ -21,8 +22,8 @@ struct Device {
const std::vector<Device> &getDevices();
ol_device_handle_t getHostDevice();
-bool loadDeviceBinary(const std::string &BinaryName, ol_device_handle_t Device,
- std::unique_ptr<llvm::MemoryBuffer> &BinaryOut,
- ol_platform_backend_t OverrideBackend =
- OL_PLATFORM_BACKEND_UNKNOWN);
+bool loadDeviceBinary(
+ const std::string &BinaryName, ol_device_handle_t Device,
+ std::unique_ptr<llvm::MemoryBuffer> &BinaryOut,
+ std::optional<ol_platform_backend_t> OverrideBackend = std::nullopt);
} // namespace TestEnvironment
>From e41a0a31f1e79dfaa164861016184e0e89b7f7fa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Trusi=C5=82=C5=82o?= <jan.trusillo at intel.com>
Date: Mon, 6 Jul 2026 16:18:25 +0000
Subject: [PATCH 7/7] [offload] move prog data zero size check to plugin
interface
Offload API impl featured a check that ensured that passing a zero size
binary to olCreateProgram yielded a consistent error code across
plugins. This commit moves the check into the plugin interface layer, so
that libomptarget can also benefit from this added
predictability.
---
offload/liboffload/src/OffloadImpl.cpp | 12 ------------
.../plugins-nextgen/common/src/PluginInterface.cpp | 9 +++++++++
offload/plugins-nextgen/level_zero/src/L0Program.cpp | 4 +++-
3 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 460289d8110f2..1aec20a225196 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -1043,18 +1043,6 @@ Error olMemPrefetch_impl(ol_queue_handle_t Queue, size_t Count,
Error olCreateProgram_impl(ol_device_handle_t Device, const void *ProgData,
size_t ProgDataSize, ol_program_handle_t *Program) {
-
- // An empty image is not a valid binary.
- // Plugins behave differently given empty binaries - e.g. CUDA will map to
- // INVALID_BINARY, while L0 will map to INVALID_SIZE (which is also associated
- // with invalid kernel launch dims etc.), so we guard here for consistent
- // behavior.
- // TODO: This should be part of the plugin interface contract so this check
- // can be removed from here.
- if (ProgDataSize == 0)
- return createOffloadError(ErrorCode::INVALID_BINARY,
- "provided binary image is empty");
-
StringRef Buffer(reinterpret_cast<const char *>(ProgData), ProgDataSize);
Expected<plugin::DeviceImageTy *> Res =
Device->Device->loadBinary(Device->Device->Plugin, Buffer);
diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp
index 112aa5383c1d7..7b821e77df179 100644
--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp
+++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp
@@ -675,6 +675,15 @@ Expected<DeviceImageTy *> GenericDeviceTy::loadBinary(GenericPluginTy &Plugin,
ODBG(OLDT_Init) << "Load data from image "
<< static_cast<const void *>(InputTgtImage.bytes_begin());
+ // An empty image is not a valid binary. Plugins behave differently given
+ // empty binaries - e.g. CUDA will map to INVALID_BINARY, while L0 will map to
+ // INVALID_SIZE (which is also associated with invalid kernel launch dims
+ // etc.), so we guard here for consistent behavior across plugins and API
+ // consumers (liboffload and libomptarget).
+ if (InputTgtImage.empty())
+ return Plugin::error(ErrorCode::INVALID_BINARY,
+ "provided binary image is empty");
+
std::unique_ptr<MemoryBuffer> Buffer;
if (identify_magic(InputTgtImage) == file_magic::bitcode) {
auto CompiledImageOrErr = Plugin.getJIT().process(InputTgtImage, *this);
diff --git a/offload/plugins-nextgen/level_zero/src/L0Program.cpp b/offload/plugins-nextgen/level_zero/src/L0Program.cpp
index 4887f36776bb2..8df8eb9f7bc46 100644
--- a/offload/plugins-nextgen/level_zero/src/L0Program.cpp
+++ b/offload/plugins-nextgen/level_zero/src/L0Program.cpp
@@ -95,7 +95,9 @@ Error L0ProgramBuilderTy::addModule(size_t Size, const uint8_t *Image,
// zeModuleCreate compiles/loads the provided image, so a build failure here
// means the image itself could not be loaded for this device (e.g. a
// truncated or malformed binary) rather than a generic JIT failure of an
- // otherwise valid program. Report it as INVALID_BINARY in that case.
+ // otherwise valid program. Report it as INVALID_BINARY in that case (as
+ // opposed to the default mapping of ZE_RESULT_ERROR_MODULE_BUILD_FAILURE
+ // to ErrorCode::COMPILE_FAILURE).
const auto ErrCode = RC == ZE_RESULT_ERROR_MODULE_BUILD_FAILURE
? ErrorCode::INVALID_BINARY
: getOffloadErrorCode(RC);
More information about the llvm-commits
mailing list