[llvm] [offload] add translation of plugin-specific error codes to Offload API ECs (PR #207208)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 2 08:42:34 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?= <113amper at gmail.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/207208 at github.com>


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: 311Volt

<details>
<summary>Changes</summary>

liboffload plugins would not always exhaustively map the underlying API's error values to ol_errc_t, resulting in unintended behavior - e.g. olCreateProgram, given an invalid binary, would return OL_ERRC_UNKNOWN instead of OL_ERRC_INVALID_BINARY.

This patch largely eliminates the most glaring cases of this by assigning an ol_errc_t value to every error code of the underlying API in every plugin. The proper granularity for this mapping is per-API call, but that is a large rework that belongs in a separate patch.

Assisted-by: Claude

---

Patch is 28.81 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/207208.diff


11 Files Affected:

- (modified) offload/liboffload/API/Program.td (+5-1) 
- (modified) offload/liboffload/src/OffloadImpl.cpp (+12) 
- (modified) offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h (+24-2) 
- (modified) offload/plugins-nextgen/amdgpu/src/rtl.cpp (+27-14) 
- (modified) offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h (+96) 
- (modified) offload/plugins-nextgen/cuda/src/rtl.cpp (+38-12) 
- (modified) offload/plugins-nextgen/level_zero/include/L0Trace.h (+61-5) 
- (modified) offload/plugins-nextgen/level_zero/src/L0Program.cpp (+21-16) 
- (modified) offload/unittests/OffloadAPI/common/Environment.cpp (+9-5) 
- (modified) offload/unittests/OffloadAPI/common/Environment.hpp (+5-2) 
- (modified) offload/unittests/OffloadAPI/program/olCreateProgram.cpp (+91) 


``````````diff
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/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 58ca5319c2a4e..ee84d9107122c 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -1019,6 +1019,18 @@ Error olMemFill_impl(ol_queue_handle_t Queue, void *Ptr, size_t PatternSize,
 
 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/amdgpu/dynamic_hsa/hsa.h b/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h
index 258c7234251d5..f66326a7f240e 100644
--- a/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h
+++ b/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h
@@ -25,14 +25,36 @@
 extern "C" {
 #endif
 
+/**
+ * @brief Status codes.
+ */
 typedef enum {
   HSA_STATUS_SUCCESS = 0x0,
   HSA_STATUS_INFO_BREAK = 0x1,
   HSA_STATUS_ERROR = 0x1000,
+  HSA_STATUS_ERROR_INVALID_ARGUMENT = 0x1001,
+  HSA_STATUS_ERROR_INVALID_QUEUE_CREATION = 0x1002,
+  HSA_STATUS_ERROR_INVALID_ALLOCATION = 0x1003,
+  HSA_STATUS_ERROR_INVALID_AGENT = 0x1004,
+  HSA_STATUS_ERROR_INVALID_REGION = 0x1005,
+  HSA_STATUS_ERROR_INVALID_SIGNAL = 0x1006,
+  HSA_STATUS_ERROR_INVALID_QUEUE = 0x1007,
+  HSA_STATUS_ERROR_OUT_OF_RESOURCES = 0x1008,
+  HSA_STATUS_ERROR_INVALID_PACKET_FORMAT = 0x1009,
+  HSA_STATUS_ERROR_RESOURCE_FREE = 0x100A,
+  HSA_STATUS_ERROR_NOT_INITIALIZED = 0x100B,
+  HSA_STATUS_ERROR_REFCOUNT_OVERFLOW = 0x100C,
+  HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS = 0x100D,
+  HSA_STATUS_ERROR_INVALID_INDEX = 0x100E,
+  HSA_STATUS_ERROR_INVALID_ISA = 0x100F,
+  HSA_STATUS_ERROR_INVALID_ISA_NAME = 0x1017,
   HSA_STATUS_ERROR_INVALID_CODE_OBJECT = 0x1010,
+  HSA_STATUS_ERROR_INVALID_EXECUTABLE = 0x1011,
+  HSA_STATUS_ERROR_FROZEN_EXECUTABLE = 0x1012,
   HSA_STATUS_ERROR_INVALID_SYMBOL_NAME = 0x1013,
-  HSA_STATUS_ERROR_NOT_INITIALIZED = 0x100B,
-  HSA_STATUS_ERROR_EXCEPTION = 0x1016,
+  HSA_STATUS_ERROR_VARIABLE_ALREADY_DEFINED = 0x1014,
+  HSA_STATUS_ERROR_VARIABLE_UNDEFINED = 0x1015,
+  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 d1c6d0de11280..ffccd71313b6a 100644
--- a/offload/plugins-nextgen/amdgpu/src/rtl.cpp
+++ b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
@@ -4324,6 +4324,32 @@ Error AMDGPUKernelTy::printLaunchInfoDetails(GenericDeviceTy &GenericDevice,
   return Plugin::success();
 }
 
+/// 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:
+    return ErrorCode::NOT_FOUND;
+  case HSA_STATUS_ERROR_INVALID_CODE_OBJECT:
+  case HSA_STATUS_ERROR_INVALID_ISA:
+  case HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS:
+    return ErrorCode::INVALID_BINARY;
+  case HSA_STATUS_ERROR_OUT_OF_RESOURCES:
+    return ErrorCode::OUT_OF_RESOURCES;
+  case HSA_STATUS_ERROR_NOT_INITIALIZED:
+    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:
+    return ErrorCode::INVALID_ARGUMENT;
+  default:
+    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);
@@ -4335,20 +4361,7 @@ 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:
-    OffloadErrCode = ErrorCode::NOT_FOUND;
-    break;
-  case HSA_STATUS_ERROR_INVALID_CODE_OBJECT:
-    OffloadErrCode = ErrorCode::INVALID_BINARY;
-    break;
-  default:
-    OffloadErrCode = ErrorCode::UNKNOWN;
-  }
-
-  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/dynamic_cuda/cuda.h b/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h
index c832157921cfb..acf8c9e46613d 100644
--- a/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h
+++ b/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h
@@ -104,14 +104,110 @@ 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_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 {
diff --git a/offload/plugins-nextgen/cuda/src/rtl.cpp b/offload/plugins-nextgen/cuda/src/rtl.cpp
index 51e2bdb0c01dc..c965b75f487ac 100644
--- a/offload/plugins-nextgen/cuda/src/rtl.cpp
+++ b/offload/plugins-nextgen/cuda/src/rtl.cpp
@@ -1802,6 +1802,43 @@ Error CUDADeviceTy::dataExchangeImpl(const void *SrcPtr,
   return Plugin::check(Res, "error in cuMemcpyDtoDAsync: %s");
 }
 
+/// Map a CUDA driver result code to the corresponding offload error code.
+static ErrorCode getOffloadErrorCode(CUresult ResultCode) {
+  switch (ResultCode) {
+  case CUDA_ERROR_INVALID_VALUE:
+    return ErrorCode::INVALID_VALUE;
+  case CUDA_ERROR_OUT_OF_MEMORY:
+  case CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES:
+    return ErrorCode::OUT_OF_RESOURCES;
+  case CUDA_ERROR_NOT_INITIALIZED:
+  case CUDA_ERROR_DEINITIALIZED:
+    return ErrorCode::UNINITIALIZED;
+  case CUDA_ERROR_NO_DEVICE:
+  case CUDA_ERROR_INVALID_DEVICE:
+    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:
+    return ErrorCode::INVALID_BINARY;
+  case CUDA_ERROR_FILE_NOT_FOUND:
+  case CUDA_ERROR_OPERATING_SYSTEM:
+    return ErrorCode::HOST_IO;
+  case CUDA_ERROR_JIT_COMPILER_NOT_FOUND:
+    return ErrorCode::HOST_TOOL_NOT_FOUND;
+  case CUDA_ERROR_NOT_FOUND:
+  case CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND:
+    return ErrorCode::NOT_FOUND;
+  case CUDA_ERROR_NOT_SUPPORTED:
+    return ErrorCode::UNSUPPORTED;
+  case CUDA_ERROR_INVALID_HANDLE:
+  case CUDA_ERROR_INVALID_CONTEXT:
+    return ErrorCode::INVALID_ARGUMENT;
+  default:
+    return ErrorCode::UNKNOWN;
+  }
+}
+
 template <typename... ArgsTy>
 static Error Plugin::check(int32_t Code, const char *ErrFmt, ArgsTy... Args) {
   CUresult ResultCode = static_cast<CUresult>(Code);
@@ -1813,18 +1850,7 @@ 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_NOT_FOUND:
-    OffloadErrCode = ErrorCode::NOT_FOUND;
-    break;
-  default:
-    OffloadErrCode = ErrorCode::UNKNOWN;
-  }
-
-  // TODO: Create a map for CUDA error codes to Offload error codes
-  return Plugin::error(OffloadErrCode, ErrFmt, Args..., Desc);
+  return Plugin::error(getOffloadErrorCode(ResultCode), ErrFmt, Args..., Desc);
 }
 
 } // namespace plugin
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/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...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/207208


More information about the llvm-commits mailing list