@@ -62,30 +62,56 @@ constexpr char kStatusPropagationTraceKey[] =
62
62
#define XLA_STATUS_VAR_ XLA_CONCAT_ (status_, __LINE__)
63
63
64
64
// Provides a flexible way to handle error checking with optional message
65
- // modification. It evaluates `expr`, checks if it's OK, and either:
66
- // 1. Returns early with an error status
67
- // 2. Proceeds with the given `then` block if successful
68
- #define XLA_RETURN_IF_ERROR_IMPL_ (expr, var, then, ...) \
69
- auto var = (expr); \
70
- if (!var.ok()) { \
71
- return ::torch_xla::status_internal::MaybeWithNewMessage ( \
72
- ::torch_xla::status_internal::GetStatus (var), __FILE__, __LINE__, \
73
- __FUNCTION__, ##__VA_ARGS__); \
74
- } \
75
- then
76
-
77
- // Propagates `rexpr`, in case it's a non-ok status.
65
+ // modification. It evaluates `expr`, and:
78
66
//
79
- // Example:
67
+ // 1. Runs the `on_error` block, if the returned status is an error
68
+ // 2. Runs the `on_success` block, otherwise
80
69
//
81
- // XLA_RETURN_IF_ERROR(
82
- // FnThatReturnsStatus(),
83
- // "New error message."
84
- // );
70
+ #define XLA_PROCESS_STATUS_IMPL_ (on_error, on_success, expr, var, ...) \
71
+ auto var = (expr); \
72
+ if (!var.ok()) { \
73
+ on_error (var, ##__VA_ARGS__); \
74
+ } \
75
+ on_success
76
+
77
+ // `on_error` implementation for propagating the status `var`.
78
+ //
79
+ // This macro wraps `var` (error status returned) into a new status, adding
80
+ // source location information to the status propagation trace if
81
+ // `TORCH_SHOW_CPP_STACKTRACES` is set. And then, returns the newly created
82
+ // status.
83
+ //
84
+ // It should be only used as parameter to `XLA_PROCESS_STATUS_IMPL_` macro
85
+ // defined above.
86
+ //
87
+ #define XLA_PROPAGATE_STATUS_IMPL_ (var, ...) \
88
+ return ::torch_xla::status_internal::MaybeWithNewMessage( \
89
+ ::torch_xla::status_internal::GetStatus (var), __FILE__, __LINE__, \
90
+ __FUNCTION__, ##__VA_ARGS__)
91
+
92
+ // `on_error` implementation for throwing an exception with the status `var`.
85
93
//
86
- // If the function call results in an ok status, execution continues. Otherwise,
87
- // we early return a non-ok status. Then, if `TORCH_SHOW_CPP_STACKTRACES` is
88
- // set, the error shown will be:
94
+ // This macro wraps `var` (error status returned) into a new status, adding
95
+ // source location information to the status propagation trace if
96
+ // `TORCH_SHOW_CPP_STACKTRACES` is set. And then, throws an exception using the
97
+ // `ThrowStatusError()` function.
98
+ //
99
+ // It should be only used as parameter to `XLA_PROCESS_STATUS_IMPL_` macro
100
+ // defined above.
101
+ //
102
+ #define XLA_THROW_STATUS_IMPL_ (var, ...) \
103
+ ::torch_xla::status_internal::ThrowStatusError ( \
104
+ ::torch_xla::status_internal::GetStatus (var), __FILE__, __LINE__, \
105
+ __FUNCTION__, ##__VA_ARGS__)
106
+
107
+ // Macro implementation for processing an `absl::Status` value. This is the core
108
+ // definition of `XLA_*_IF_ERROR()` macros that, given that `rexpr` is an error
109
+ // status, either throws or returns (i.e. propagates) a newly created status
110
+ // with source location information.
111
+ //
112
+ // If `rexpr` results in an ok status, execution continues. Otherwise, we run
113
+ // `on_error`. Then, if `TORCH_SHOW_CPP_STACKTRACES` is set, the error shown
114
+ // will be:
89
115
//
90
116
// RuntimeError: New error message.
91
117
//
@@ -95,18 +121,61 @@ constexpr char kStatusPropagationTraceKey[] =
95
121
// ...
96
122
// From: <cpp-source-file>:<line> (error: New error message.)
97
123
//
98
- #define XLA_RETURN_IF_ERROR (rexpr, ...) \
99
- do { \
100
- XLA_RETURN_IF_ERROR_IMPL_ (rexpr, XLA_STATUS_VAR_, {}, ##__VA_ARGS__) \
124
+ #define XLA_DO_IF_ERROR_IMPL_ (on_error, rexpr, ...) \
125
+ do { \
126
+ XLA_PROCESS_STATUS_IMPL_ (on_error, /* on_success= */ {}, rexpr, \
127
+ XLA_STATUS_VAR_, ##__VA_ARGS__) \
101
128
} while (false )
102
129
103
- // Propagates `rexpr`, in case it's a non-ok status. Otherwise, assign
104
- // its result to `lhs`.
130
+ // If `rexpr` returns a non-ok status, this macro propagates the returned status
131
+ // by early-returning a, possibly, new status with source location information.
132
+ // Otherwise, continues execution.
133
+ //
134
+ // Example:
135
+ //
136
+ // XLA_RETURN_IF_ERROR(
137
+ // FnThatReturnsStatus(),
138
+ // "New error message."
139
+ // );
140
+ //
141
+ #define XLA_RETURN_IF_ERROR (rexpr, ...) \
142
+ XLA_DO_IF_ERROR_IMPL_ (XLA_PROPAGATE_STATUS_IMPL_, rexpr, ##__VA_ARGS__)
143
+
144
+ // If `rexpr` returns a non-ok status, this macro throws an exception with the
145
+ // returned status, possibly, wrapped by a new status with source location
146
+ // information. Otherwise, continues execution.
147
+ //
148
+ // Example:
149
+ //
150
+ // XLA_THROW_IF_ERROR(
151
+ // FnThatReturnsStatus(),
152
+ // "New error message."
153
+ // );
154
+ //
155
+ #define XLA_THROW_IF_ERROR (rexpr, ...) \
156
+ XLA_DO_IF_ERROR_IMPL_ (XLA_THROW_STATUS_IMPL_, rexpr, ##__VA_ARGS__)
157
+
158
+ // Macro implementation for processing an `absl::Status` value. This is the core
159
+ // definition of `XLA_ASSIGN_OR_*()` macros that, given that `rexpr` is an error
160
+ // status, either throws or returns (i.e. propagates) a newly created status
161
+ // with source location information.
162
+ //
163
+ // If `rexpr` results in an ok status, we assign the value held by the status
164
+ // returned by `rexpr` to `lhs`. Otherwise, we run `on_error`.
105
165
//
106
166
// Note 1: `lhs` might be a variable declarate, e.g:
107
167
//
108
168
// Note 2: this macro will be replaced by multiple statements that live on
109
- // the scope it was called (see XLA_RETURN_IF_ERROR_IMPL).
169
+ // the scope it was called (see `XLA_PROCESS_STATUS_IMPL_`).
170
+ //
171
+ #define XLA_ASSIGN_OR_DO_IMPL_ (on_error, lhs, rexpr, ...) \
172
+ XLA_PROCESS_STATUS_IMPL_ ( \
173
+ on_error, /* on_success= */ lhs = std::move(XLA_STATUS_VAR_).value(), \
174
+ rexpr, XLA_STATUS_VAR_, ##__VA_ARGS__)
175
+
176
+ // If `rexpr` returns a non-ok status, this macro propagates the returned status
177
+ // by early-returning a, possibly, new status with source location information.
178
+ // Otherwise, assigns `rexpr` to `lhs`.
110
179
//
111
180
// Example:
112
181
//
@@ -116,16 +185,23 @@ constexpr char kStatusPropagationTraceKey[] =
116
185
// "New error message."
117
186
// );
118
187
//
119
- // If the function call results in an ok status, execution continues with
120
- // `result` set to `ret.value()`, where `ret` is the returned value of the
121
- // function. Otherwise, we early return a non-ok status. Then, if
122
- // `TORCH_SHOW_CPP_STACKTRACES` is set, the error shown will be similar to
123
- // the one above.
188
+ #define XLA_ASSIGN_OR_RETURN (lhs, rexpr, ...) \
189
+ XLA_ASSIGN_OR_DO_IMPL_ (XLA_PROPAGATE_STATUS_IMPL_, lhs, rexpr, ##__VA_ARGS__)
190
+
191
+ // If `rexpr` returns a non-ok status, this macro throws an exception with the
192
+ // returned status, possibly, wrapped by a new status with source location
193
+ // information. Otherwise, assigns `rexpr` to `lhs`.
194
+ //
195
+ // Example:
196
+ //
197
+ // XLA_ASSIGN_OR_THROW(
198
+ // int result,
199
+ // FnThatReturnsStatus(),
200
+ // "New error message."
201
+ // );
124
202
//
125
- #define XLA_ASSIGN_OR_RETURN (lhs, rexpr, ...) \
126
- XLA_RETURN_IF_ERROR_IMPL_ (rexpr, XLA_STATUS_VAR_, \
127
- lhs = std::move(XLA_STATUS_VAR_).value(), \
128
- ##__VA_ARGS__)
203
+ #define XLA_ASSIGN_OR_THROW (lhs, rexpr, ...) \
204
+ XLA_ASSIGN_OR_DO_IMPL_ (XLA_THROW_STATUS_IMPL_, lhs, rexpr, ##__VA_ARGS__)
129
205
130
206
// Crashes if `status` is not an ok status.
131
207
//
@@ -191,6 +267,18 @@ absl::Status MaybeWithNewMessage(const absl::Status& status, const char* file,
191
267
int32_t line, const char * function,
192
268
std::string_view new_message = " " );
193
269
270
+ // Throws an exception from the given `status`
271
+ //
272
+ // This function wraps `status` within a new status, with the current source
273
+ // location information added to its status propagation trace payload.
274
+ //
275
+ // Then, it throws an exception by using the `TORCH_CHECK(false)` macro, which
276
+ // also displays the C++ stacktrace at the end, if `TORCH_SHOW_CPP_STACKTRACES`
277
+ // is set.
278
+ void ThrowStatusError (const absl::Status& status, const char * file,
279
+ const int32_t line, const char * function,
280
+ std::string_view message = " " );
281
+
194
282
// Checks that `status` is an ok status.
195
283
//
196
284
// Otherwise, it will create a new status instance with the given source
0 commit comments