1 /* 2 * Copyright (c) Meta Platforms, Inc. and affiliates. 3 * All rights reserved. 4 * 5 * This source code is licensed under the BSD-style license found in the 6 * LICENSE file in the root directory of this source tree. 7 */ 8 9 /** 10 * @file 11 * ExecuTorch Error declarations. 12 */ 13 14 #pragma once 15 16 #include <stdint.h> 17 18 #include <executorch/runtime/platform/log.h> 19 20 namespace executorch { 21 namespace runtime { 22 23 // Alias error code integral type to minimal platform width (32-bits for now). 24 typedef uint32_t error_code_t; 25 26 /** 27 * ExecuTorch Error type. 28 */ 29 enum class Error : error_code_t { 30 /* 31 * System errors. 32 */ 33 34 /// Status indicating a successful operation. 35 Ok = 0x00, 36 37 /// An internal error occurred. 38 Internal = 0x01, 39 40 /// Status indicating the executor is in an invalid state for a target 41 /// operation 42 InvalidState = 0x2, 43 44 /// Status indicating there are no more steps of execution to run 45 EndOfMethod = 0x03, 46 47 /* 48 * Logical errors. 49 */ 50 51 /// Operation is not supported in the current context. 52 NotSupported = 0x10, 53 54 /// Operation is not yet implemented. 55 NotImplemented = 0x11, 56 57 /// User provided an invalid argument. 58 InvalidArgument = 0x12, 59 60 /// Object is an invalid type for the operation. 61 InvalidType = 0x13, 62 63 /// Operator(s) missing in the operator registry. 64 OperatorMissing = 0x14, 65 66 /* 67 * Resource errors. 68 */ 69 70 /// Requested resource could not be found. 71 NotFound = 0x20, 72 73 /// Could not allocate the requested memory. 74 MemoryAllocationFailed = 0x21, 75 76 /// Could not access a resource. 77 AccessFailed = 0x22, 78 79 /// Error caused by the contents of a program. 80 InvalidProgram = 0x23, 81 82 /* 83 * Delegate errors. 84 */ 85 86 /// Init stage: Backend receives an incompatible delegate version. 87 DelegateInvalidCompatibility = 0x30, 88 /// Init stage: Backend fails to allocate memory. 89 DelegateMemoryAllocationFailed = 0x31, 90 /// Execute stage: The handle is invalid. 91 DelegateInvalidHandle = 0x32, 92 93 }; 94 95 } // namespace runtime 96 } // namespace executorch 97 98 namespace torch { 99 namespace executor { 100 // TODO(T197294990): Remove these deprecated aliases once all users have moved 101 // to the new `::executorch` namespaces. 102 using ::executorch::runtime::Error; 103 using ::executorch::runtime::error_code_t; 104 } // namespace executor 105 } // namespace torch 106 107 /** 108 * If cond__ is false, log the specified message and return the specified Error 109 * from the current function, which must be of return type 110 * executorch::runtime::Error. 111 * 112 * @param[in] cond__ The condition to be checked, asserted as true. 113 * @param[in] error__ Error enum value to return without the `Error::` prefix, 114 * like `InvalidArgument`. 115 * @param[in] message__ Format string for the log error message. 116 * @param[in] ... Optional additional arguments for the format string. 117 */ 118 #define ET_CHECK_OR_RETURN_ERROR(cond__, error__, message__, ...) \ 119 { \ 120 if (!(cond__)) { \ 121 ET_LOG(Error, message__, ##__VA_ARGS__); \ 122 return ::executorch::runtime::Error::error__; \ 123 } \ 124 } 125 126 /** 127 * If error__ is not Error::Ok, optionally log a message and return the error 128 * from the current function, which must be of return type 129 * executorch::runtime::Error. 130 * 131 * @param[in] error__ Error enum value asserted to be Error::Ok. 132 * @param[in] ... Optional format string for the log error message and its 133 * arguments. 134 */ 135 #define ET_CHECK_OK_OR_RETURN_ERROR(error__, ...) \ 136 ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR(error__, ##__VA_ARGS__) 137 138 // Internal only: Use ET_CHECK_OK_OR_RETURN_ERROR() instead. 139 #define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR(...) \ 140 ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_SELECT( \ 141 __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) \ 142 (__VA_ARGS__) 143 144 /** 145 * Internal only: Use ET_CHECK_OK_OR_RETURN_ERROR() instead. 146 * This macro selects the correct version of 147 * ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR based on the number of arguments passed. 148 * It uses a trick with the preprocessor to count the number of arguments and 149 * then selects the appropriate macro. 150 * 151 * The macro expansion uses __VA_ARGS__ to accept any number of arguments and 152 * then appends them to ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_, followed by the 153 * count of arguments. The count is determined by the macro 154 * ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_SELECT which takes the arguments and 155 * passes them along with a sequence of numbers (2, 1). The preprocessor then 156 * matches this sequence to the correct number of arguments provided. 157 * 158 * If two arguments are passed, ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2 is 159 * selected, suitable for cases where an error code and a custom message are 160 * provided. If only one argument is passed, 161 * ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_1 is selected, which is used for cases 162 * with just an error code. 163 * 164 * Usage: 165 * ET_CHECK_OK_OR_RETURN_ERROR(error_code); // Calls v1 166 * ET_CHECK_OK_OR_RETURN_ERROR(error_code, "Error message", ...); // Calls v2 167 */ 168 #define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_SELECT( \ 169 _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) \ 170 ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_##N 171 172 // Internal only: Use ET_CHECK_OK_OR_RETURN_ERROR() instead. 173 #define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_1(error__) \ 174 do { \ 175 const auto et_error__ = (error__); \ 176 if (et_error__ != ::executorch::runtime::Error::Ok) { \ 177 return et_error__; \ 178 } \ 179 } while (0) 180 181 // Internal only: Use ET_CHECK_OK_OR_RETURN_ERROR() instead. 182 #define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2(error__, message__, ...) \ 183 do { \ 184 const auto et_error__ = (error__); \ 185 if (et_error__ != ::executorch::runtime::Error::Ok) { \ 186 ET_LOG(Error, message__, ##__VA_ARGS__); \ 187 return et_error__; \ 188 } \ 189 } while (0) 190 191 // Internal only: Use ET_CHECK_OK_OR_RETURN_ERROR() instead. 192 #define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_3 \ 193 ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2 194 #define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_4 \ 195 ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2 196 #define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_5 \ 197 ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2 198 #define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_6 \ 199 ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2 200 #define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_7 \ 201 ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2 202 #define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_8 \ 203 ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2 204 #define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_9 \ 205 ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2 206 #define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_10 \ 207 ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2 208