Halide 14.0.0
Halide compiler and libraries
Error.h
Go to the documentation of this file.
1#ifndef HALIDE_ERROR_H
2#define HALIDE_ERROR_H
3
4#include <sstream>
5#include <stdexcept>
6
7#include "Debug.h"
8#include "runtime/HalideRuntime.h" // for HALIDE_ALWAYS_INLINE
9
10namespace Halide {
11
12/** Query whether Halide was compiled with exceptions. */
14
15/** A base class for Halide errors. */
16struct Error : public std::runtime_error {
17 // Give each class a non-inlined constructor so that the type
18 // doesn't get separately instantiated in each compilation unit.
19 Error(const std::string &msg);
20};
21
22/** An error that occurs while running a JIT-compiled Halide pipeline. */
23struct RuntimeError : public Error {
24 RuntimeError(const std::string &msg);
25};
26
27/** An error that occurs while compiling a Halide pipeline that Halide
28 * attributes to a user error. */
29struct CompileError : public Error {
30 CompileError(const std::string &msg);
31};
32
33/** An error that occurs while compiling a Halide pipeline that Halide
34 * attributes to an internal compiler bug, or to an invalid use of
35 * Halide's internals. */
36struct InternalError : public Error {
37 InternalError(const std::string &msg);
38};
39
40/** CompileTimeErrorReporter is used at compile time (*not* runtime) when
41 * an error or warning is generated by Halide. Note that error() is called
42 * a fatal error has occurred, and returning to Halide may cause a crash;
43 * implementations of CompileTimeErrorReporter::error() should never return.
44 * (Implementations of CompileTimeErrorReporter::warning() may return but
45 * may also abort(), exit(), etc.)
46 */
48public:
49 virtual ~CompileTimeErrorReporter() = default;
50 virtual void warning(const char *msg) = 0;
51 virtual void error(const char *msg) = 0;
52};
53
54/** The default error reporter logs to stderr, then throws an exception
55 * (if HALIDE_WITH_EXCEPTIONS) or calls abort (if not). This allows customization
56 * of that behavior if a more gentle response to error reporting is desired.
57 * Note that error_reporter is expected to remain valid across all Halide usage;
58 * it is up to the caller to ensure that this is the case (and to do any
59 * cleanup necessary).
60 */
62
63namespace Internal {
64
66 enum {
67 User = 0x0001,
68 Warning = 0x0002,
69 Runtime = 0x0004
70 };
71
72 std::ostringstream msg;
73 const int flags;
74
75 ErrorReport(const char *f, int l, const char *cs, int flags);
76
77 // Just a trick used to convert RValue into LValue
79 return *this;
80 }
81
82 template<typename T>
83 ErrorReport &operator<<(const T &x) {
84 msg << x;
85 return *this;
86 }
87
88 /** When you're done using << on the object, and let it fall out of
89 * scope, this errors out, or throws an exception if they are
90 * enabled. This is a little dangerous because the destructor will
91 * also be called if there's an exception in flight due to an
92 * error in one of the arguments passed to operator<<. We handle
93 * this by only actually throwing if there isn't an exception in
94 * flight already.
95 */
96 ~ErrorReport() noexcept(false);
97};
98
99// This uses operator precedence as a trick to avoid argument evaluation if
100// an assertion is true: it is intended to be used as part of the
101// _halide_internal_assertion macro, to coerce the result of the stream
102// expression to void (to match the condition-is-false case).
104public:
106 // This has to be an operator with a precedence lower than << but
107 // higher than ?:
109 }
110};
111
112/**
113 * _halide_internal_assertion is used to implement our assertion macros
114 * in such a way that the messages output for the assertion are only
115 * evaluated if the assertion's value is false.
116 *
117 * Note that this macro intentionally has no parens internally; in actual
118 * use, the implicit grouping will end up being
119 *
120 * condition ? (void) : (Voidifier() & (ErrorReport << arg1 << arg2 ... << argN))
121 *
122 * This (regrettably) requires a macro to work, but has the highly desirable
123 * effect that all assertion parameters are totally skipped (not ever evaluated)
124 * when the assertion is true.
125 */
126#define _halide_internal_assertion(condition, flags) \
127 /* NOLINTNEXTLINE(bugprone-macro-parentheses) */ \
128 (condition) ? (void)0 : ::Halide::Internal::Voidifier() & ::Halide::Internal::ErrorReport(__FILE__, __LINE__, #condition, flags).ref()
129
130#define internal_error Halide::Internal::ErrorReport(__FILE__, __LINE__, nullptr, 0)
131#define user_error Halide::Internal::ErrorReport(__FILE__, __LINE__, nullptr, Halide::Internal::ErrorReport::User)
132#define user_warning Halide::Internal::ErrorReport(__FILE__, __LINE__, nullptr, Halide::Internal::ErrorReport::User | Halide::Internal::ErrorReport::Warning)
133#define halide_runtime_error Halide::Internal::ErrorReport(__FILE__, __LINE__, nullptr, Halide::Internal::ErrorReport::User | Halide::Internal::ErrorReport::Runtime)
134
135#define internal_assert(c) _halide_internal_assertion(c, 0)
136#define user_assert(c) _halide_internal_assertion(c, Halide::Internal::ErrorReport::User)
137
138// The nicely named versions get cleaned up at the end of Halide.h,
139// but user code might want to do halide-style user_asserts (e.g. the
140// Extern macros introduce calls to user_assert), so for that purpose
141// we define an equivalent macro that can be used outside of Halide.h
142#define _halide_user_assert(c) _halide_internal_assertion(c, Halide::Internal::ErrorReport::User)
143
144// N.B. Any function that might throw a user_assert or user_error may
145// not be inlined into the user's code, or the line number will be
146// misattributed to Halide.h. Either make such functions internal to
147// libHalide, or mark them as HALIDE_NO_USER_CODE_INLINE.
148
149} // namespace Internal
150
151} // namespace Halide
152
153#endif
Defines functions for debug logging during code generation.
This file declares the routines used by Halide internally in its runtime.
#define HALIDE_ALWAYS_INLINE
Definition: HalideRuntime.h:38
CompileTimeErrorReporter is used at compile time (not runtime) when an error or warning is generated ...
Definition: Error.h:47
virtual void warning(const char *msg)=0
virtual void error(const char *msg)=0
virtual ~CompileTimeErrorReporter()=default
HALIDE_ALWAYS_INLINE void operator&(ErrorReport &)
Definition: Error.h:108
HALIDE_ALWAYS_INLINE Voidifier()=default
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
@ Internal
Not visible externally, similar to 'static' linkage in C.
bool exceptions_enabled()
Query whether Halide was compiled with exceptions.
void set_custom_compile_time_error_reporter(CompileTimeErrorReporter *error_reporter)
The default error reporter logs to stderr, then throws an exception (if HALIDE_WITH_EXCEPTIONS) or ca...
An error that occurs while compiling a Halide pipeline that Halide attributes to a user error.
Definition: Error.h:29
CompileError(const std::string &msg)
A base class for Halide errors.
Definition: Error.h:16
Error(const std::string &msg)
~ErrorReport() noexcept(false)
When you're done using << on the object, and let it fall out of scope, this errors out,...
ErrorReport(const char *f, int l, const char *cs, int flags)
std::ostringstream msg
Definition: Error.h:72
ErrorReport & operator<<(const T &x)
Definition: Error.h:83
HALIDE_ALWAYS_INLINE ErrorReport & ref()
Definition: Error.h:78
An error that occurs while compiling a Halide pipeline that Halide attributes to an internal compiler...
Definition: Error.h:36
InternalError(const std::string &msg)
An error that occurs while running a JIT-compiled Halide pipeline.
Definition: Error.h:23
RuntimeError(const std::string &msg)