[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:36:02 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>,
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/8] [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/8] [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/8] [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/8] [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/8] [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/8] [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/8] [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);

>From 463e63e412c91cd3bfeaeeca611fc83a9325ee31 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Trusi=C5=82=C5=82o?= <jan.trusillo at intel.com>
Date: Mon, 13 Jul 2026 09:35:22 +0000
Subject: [PATCH 8/8] run clang-format

---
 .../plugins-nextgen/level_zero/src/L0Program.cpp |  2 +-
 .../OffloadAPI/program/olCreateProgram.cpp       | 16 ++++++++--------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/offload/plugins-nextgen/level_zero/src/L0Program.cpp b/offload/plugins-nextgen/level_zero/src/L0Program.cpp
index 8df8eb9f7bc46..ea1c2792e608a 100644
--- a/offload/plugins-nextgen/level_zero/src/L0Program.cpp
+++ b/offload/plugins-nextgen/level_zero/src/L0Program.cpp
@@ -96,7 +96,7 @@ Error L0ProgramBuilderTy::addModule(size_t Size, const uint8_t *Image,
     // 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 (as
-    // opposed to the default mapping of ZE_RESULT_ERROR_MODULE_BUILD_FAILURE 
+    // 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
diff --git a/offload/unittests/OffloadAPI/program/olCreateProgram.cpp b/offload/unittests/OffloadAPI/program/olCreateProgram.cpp
index 5e81c9368375f..4f661cf4b4cd0 100644
--- a/offload/unittests/OffloadAPI/program/olCreateProgram.cpp
+++ b/offload/unittests/OffloadAPI/program/olCreateProgram.cpp
@@ -69,9 +69,9 @@ TEST_P(olCreateProgramTest, ZeroSizeBinary) {
 
   ol_program_handle_t Program = nullptr;
 
-  ASSERT_ERROR(OL_ERRC_INVALID_BINARY,
-               olCreateProgram(Device, DeviceBin->getBufferStart(), 0,
-                               &Program));
+  ASSERT_ERROR(
+      OL_ERRC_INVALID_BINARY,
+      olCreateProgram(Device, DeviceBin->getBufferStart(), 0, &Program));
   ASSERT_EQ(Program, nullptr);
 }
 
@@ -80,8 +80,8 @@ TEST_P(olCreateProgramTest, InvalidBinary) {
 
   ol_program_handle_t Program = nullptr;
   ASSERT_ERROR(OL_ERRC_INVALID_BINARY,
-               olCreateProgram(Device, InvalidBinary,
-                               sizeof(InvalidBinary) - 1, &Program));
+               olCreateProgram(Device, InvalidBinary, sizeof(InvalidBinary) - 1,
+                               &Program));
   ASSERT_EQ(Program, nullptr);
 }
 
@@ -101,9 +101,9 @@ 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;
+  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,



More information about the llvm-commits mailing list