Halide
Util.h
Go to the documentation of this file.
1 // Always use assert, even if llvm-config defines NDEBUG
2 #ifdef NDEBUG
3 #undef NDEBUG
4 #include <assert.h>
5 #define NDEBUG
6 #else
7 #include <cassert>
8 #endif
9 
10 #ifndef HALIDE_UTIL_H
11 #define HALIDE_UTIL_H
12 
13 /** \file
14  * Various utility functions used internally Halide. */
15 
16 #include <cstdint>
17 #include <cstring>
18 #include <functional>
19 #include <limits>
20 #include <string>
21 #include <utility>
22 #include <vector>
23 
24 #include "runtime/HalideRuntime.h"
25 
26 #ifdef Halide_STATIC_DEFINE
27 #define HALIDE_EXPORT
28 #else
29 #if defined(_MSC_VER)
30 // Halide_EXPORTS is quietly defined by CMake when building a shared library
31 #ifdef Halide_EXPORTS
32 #define HALIDE_EXPORT __declspec(dllexport)
33 #else
34 #define HALIDE_EXPORT __declspec(dllimport)
35 #endif
36 #else
37 #define HALIDE_EXPORT __attribute__((visibility("default")))
38 #endif
39 #endif
40 
41 // If we're in user code, we don't want certain functions to be inlined.
42 #if defined(COMPILING_HALIDE) || defined(BUILDING_PYTHON)
43 #define HALIDE_NO_USER_CODE_INLINE
44 #else
45 #define HALIDE_NO_USER_CODE_INLINE HALIDE_NEVER_INLINE
46 #endif
47 
48 // Clang uses __has_feature() for sanitizers...
49 #if defined(__has_feature)
50 #if __has_feature(address_sanitizer)
51 #define HALIDE_INTERNAL_USING_ASAN
52 #endif
53 #if __has_feature(memory_sanitizer)
54 #define HALIDE_INTERNAL_USING_MSAN
55 #endif
56 #if __has_feature(thread_sanitizer)
57 #define HALIDE_INTERNAL_USING_TSAN
58 #endif
59 #if __has_feature(coverage_sanitizer)
60 #define HALIDE_INTERNAL_USING_COVSAN
61 #endif
62 #if __has_feature(undefined_behavior_sanitizer)
63 #define HALIDE_INTERNAL_USING_UBSAN
64 #endif
65 #endif
66 
67 // ...but GCC/MSVC don't like __has_feature, so handle them separately.
68 // (Only AddressSanitizer for now, not sure if any others are well-supported
69 // outside of Clang.
70 #if defined(__SANITIZE_ADDRESS__) && !defined(HALIDE_INTERNAL_USING_ASAN)
71 #define HALIDE_INTERNAL_USING_ASAN
72 #endif
73 
74 namespace Halide {
75 
76 /** Load a plugin in the form of a dynamic library (e.g. for custom autoschedulers).
77  * If the string doesn't contain any . characters, the proper prefix and/or suffix
78  * for the platform will be added:
79  *
80  * foo -> libfoo.so (Linux/OSX/etc -- note that .dylib is not supported)
81  * foo -> foo.dll (Windows)
82  *
83  * otherwise, it is assumed to be an appropriate pathname.
84  *
85  * Any error in loading will assert-fail. */
86 void load_plugin(const std::string &lib_name);
87 
88 namespace Internal {
89 
90 /** Some numeric conversions are UB if the value won't fit in the result;
91  * safe_numeric_cast<>() is meant as a drop-in replacement for a C/C++ cast
92  * that adds well-defined behavior for the UB cases, attempting to mimic
93  * common implementation behavior as much as possible.
94  */
95 template<typename DST, typename SRC,
96  typename std::enable_if<std::is_floating_point<SRC>::value>::type * = nullptr>
97 DST safe_numeric_cast(SRC s) {
98  if (std::is_integral<DST>::value) {
99  // Treat float -> int as a saturating cast; this is handled
100  // in different ways by different compilers, so an arbitrary but safe
101  // choice like this is reasonable.
102  if (s < (SRC)std::numeric_limits<DST>::min()) {
104  }
105  if (s > (SRC)std::numeric_limits<DST>::max()) {
107  }
108  }
109  return (DST)s;
110 }
111 
112 template<typename DST, typename SRC,
113  typename std::enable_if<std::is_integral<SRC>::value>::type * = nullptr>
114 DST safe_numeric_cast(SRC s) {
115  if (std::is_integral<DST>::value) {
116  // any-int -> signed-int is technically UB if value won't fit;
117  // in practice, common compilers implement such conversions as done below
118  // (as verified by exhaustive testing on Clang for x86-64). We could
119  // probably continue to rely on that behavior, but making it explicit
120  // avoids possible wrather of UBSan and similar debug helpers.
121  // (Yes, using sizeof for this comparison is a little odd for the uint->int
122  // case, but the intent is to match existing common behavior, which this does.)
123  if (std::is_integral<SRC>::value && std::is_signed<DST>::value && sizeof(DST) < sizeof(SRC)) {
124  using UnsignedSrc = typename std::make_unsigned<SRC>::type;
125  return (DST)(s & (UnsignedSrc)(-1));
126  }
127  }
128  return (DST)s;
129 }
130 
131 /** An aggressive form of reinterpret cast used for correct type-punning. */
132 template<typename DstType, typename SrcType>
133 DstType reinterpret_bits(const SrcType &src) {
134  static_assert(sizeof(SrcType) == sizeof(DstType), "Types must be same size");
135  DstType dst;
136  memcpy(&dst, &src, sizeof(SrcType));
137  return dst;
138 }
139 
140 /** Make a unique name for an object based on the name of the stack
141  * variable passed in. If introspection isn't working or there are no
142  * debug symbols, just uses unique_name with the given prefix. */
143 std::string make_entity_name(void *stack_ptr, const std::string &type, char prefix);
144 
145 /** Get value of an environment variable. Returns its value
146  * is defined in the environment. If the var is not defined, an empty string
147  * is returned.
148  */
149 std::string get_env_variable(char const *env_var_name);
150 
151 /** Get the name of the currently running executable. Platform-specific.
152  * If program name cannot be retrieved, function returns an empty string. */
153 std::string running_program_name();
154 
155 /** Generate a unique name starting with the given prefix. It's unique
156  * relative to all other strings returned by unique_name in this
157  * process.
158  *
159  * The single-character version always appends a numeric suffix to the
160  * character.
161  *
162  * The string version will either return the input as-is (with high
163  * probability on the first time it is called with that input), or
164  * replace any existing '$' characters with underscores, then add a
165  * '$' sign and a numeric suffix to it.
166  *
167  * Note that unique_name('f') therefore differs from
168  * unique_name("f"). The former returns something like f123, and the
169  * latter returns either f or f$123.
170  */
171 // @{
172 std::string unique_name(char prefix);
173 std::string unique_name(const std::string &prefix);
174 // @}
175 
176 /** Test if the first string starts with the second string */
177 bool starts_with(const std::string &str, const std::string &prefix);
178 
179 /** Test if the first string ends with the second string */
180 bool ends_with(const std::string &str, const std::string &suffix);
181 
182 /** Replace all matches of the second string in the first string with the last string */
183 std::string replace_all(const std::string &str, const std::string &find, const std::string &replace);
184 
185 /** Split the source string using 'delim' as the divider. */
186 std::vector<std::string> split_string(const std::string &source, const std::string &delim);
187 
188 /** Perform a left fold of a vector. Returns a default-constructed
189  * vector element if the vector is empty. Similar to std::accumulate
190  * but with a less clunky syntax. */
191 template<typename T, typename Fn>
192 T fold_left(const std::vector<T> &vec, Fn f) {
193  T result;
194  if (vec.empty()) {
195  return result;
196  }
197  result = vec[0];
198  for (size_t i = 1; i < vec.size(); i++) {
199  result = f(result, vec[i]);
200  }
201  return result;
202 }
203 
204 /** Returns a right fold of a vector. Returns a default-constructed
205  * vector element if the vector is empty. */
206 template<typename T, typename Fn>
207 T fold_right(const std::vector<T> &vec, Fn f) {
208  T result;
209  if (vec.empty()) {
210  return result;
211  }
212  result = vec.back();
213  for (size_t i = vec.size() - 1; i > 0; i--) {
214  result = f(vec[i - 1], result);
215  }
216  return result;
217 }
218 
219 template<typename... T>
220 struct meta_and : std::true_type {};
221 
222 template<typename T1, typename... Args>
223 struct meta_and<T1, Args...> : std::integral_constant<bool, T1::value && meta_and<Args...>::value> {};
224 
225 template<typename... T>
226 struct meta_or : std::false_type {};
227 
228 template<typename T1, typename... Args>
229 struct meta_or<T1, Args...> : std::integral_constant<bool, T1::value || meta_or<Args...>::value> {};
230 
231 template<typename To, typename... Args>
232 struct all_are_convertible : meta_and<std::is_convertible<Args, To>...> {};
233 
234 /** Returns base name and fills in namespaces, outermost one first in vector. */
235 std::string extract_namespaces(const std::string &name, std::vector<std::string> &namespaces);
236 
237 /** Like extract_namespaces(), but strip and discard the namespaces, returning base name only */
238 std::string strip_namespaces(const std::string &name);
239 
240 struct FileStat {
242  uint32_t mod_time; // Unix epoch time
246 };
247 
248 /** Create a unique file with a name of the form prefixXXXXXsuffix in an arbitrary
249  * (but writable) directory; this is typically /tmp, but the specific
250  * location is not guaranteed. (Note that the exact form of the file name
251  * may vary; in particular, the suffix may be ignored on Windows.)
252  * The file is created (but not opened), thus this can be called from
253  * different threads (or processes, e.g. when building with parallel make)
254  * without risking collision. Note that if this file is used as a temporary
255  * file, the caller is responsibly for deleting it. Neither the prefix nor suffix
256  * may contain a directory separator.
257  */
258 std::string file_make_temp(const std::string &prefix, const std::string &suffix);
259 
260 /** Create a unique directory in an arbitrary (but writable) directory; this is
261  * typically somewhere inside /tmp, but the specific location is not guaranteed.
262  * The directory will be empty (i.e., this will never return /tmp itself,
263  * but rather a new directory inside /tmp). The caller is responsible for removing the
264  * directory after use.
265  */
266 std::string dir_make_temp();
267 
268 /** Wrapper for access(). Quietly ignores errors. */
269 bool file_exists(const std::string &name);
270 
271 /** assert-fail if the file doesn't exist. useful primarily for testing purposes. */
272 void assert_file_exists(const std::string &name);
273 
274 /** assert-fail if the file DOES exist. useful primarily for testing purposes. */
275 void assert_no_file_exists(const std::string &name);
276 
277 /** Wrapper for unlink(). Asserts upon error. */
278 void file_unlink(const std::string &name);
279 
280 /** Wrapper for unlink(). Quietly ignores errors. */
281 void file_unlink(const std::string &name);
282 
283 /** Ensure that no file with this path exists. If such a file
284  * exists and cannot be removed, assert-fail. */
285 void ensure_no_file_exists(const std::string &name);
286 
287 /** Wrapper for rmdir(). Asserts upon error. */
288 void dir_rmdir(const std::string &name);
289 
290 /** Wrapper for stat(). Asserts upon error. */
291 FileStat file_stat(const std::string &name);
292 
293 /** Read the entire contents of a file into a vector<char>. The file
294  * is read in binary mode. Errors trigger an assertion failure. */
295 std::vector<char> read_entire_file(const std::string &pathname);
296 
297 /** Create or replace the contents of a file with a given pointer-and-length
298  * of memory. If the file doesn't exist, it is created; if it does exist, it
299  * is completely overwritten. Any error triggers an assertion failure. */
300 void write_entire_file(const std::string &pathname, const void *source, size_t source_len);
301 
302 inline void write_entire_file(const std::string &pathname, const std::vector<char> &source) {
303  write_entire_file(pathname, source.data(), source.size());
304 }
305 
306 /** A simple utility class that creates a temporary file in its ctor and
307  * deletes that file in its dtor; this is useful for temporary files that you
308  * want to ensure are deleted when exiting a certain scope. Since this is essentially
309  * just an RAII wrapper around file_make_temp() and file_unlink(), it has the same
310  * failure modes (i.e.: assertion upon error).
311  */
312 class TemporaryFile final {
313 public:
314  TemporaryFile(const std::string &prefix, const std::string &suffix)
315  : temp_path(file_make_temp(prefix, suffix)) {
316  }
317  const std::string &pathname() const {
318  return temp_path;
319  }
321  if (do_unlink) {
322  file_unlink(temp_path);
323  }
324  }
325  // You can call this if you want to defeat the automatic deletion;
326  // this is rarely what you want to do (since it defeats the purpose
327  // of this class), but can be quite handy for debugging purposes.
328  void detach() {
329  do_unlink = false;
330  }
331 
332 private:
333  const std::string temp_path;
334  bool do_unlink = true;
335 
336 public:
337  TemporaryFile(const TemporaryFile &) = delete;
338  TemporaryFile &operator=(const TemporaryFile &) = delete;
339  TemporaryFile(TemporaryFile &&) = delete;
340  TemporaryFile &operator=(TemporaryFile &&) = delete;
341 };
342 
343 /** Routines to test if math would overflow for signed integers with
344  * the given number of bits. */
345 // @{
346 bool add_would_overflow(int bits, int64_t a, int64_t b);
347 bool sub_would_overflow(int bits, int64_t a, int64_t b);
348 bool mul_would_overflow(int bits, int64_t a, int64_t b);
349 // @}
350 
351 /** Routines to perform arithmetic on signed types without triggering signed
352  * overflow. If overflow would occur, sets result to zero, and returns
353  * false. Otherwise set result to the correct value, and returns true. */
354 // @{
355 HALIDE_MUST_USE_RESULT bool add_with_overflow(int bits, int64_t a, int64_t b, int64_t *result);
356 HALIDE_MUST_USE_RESULT bool sub_with_overflow(int bits, int64_t a, int64_t b, int64_t *result);
357 HALIDE_MUST_USE_RESULT bool mul_with_overflow(int bits, int64_t a, int64_t b, int64_t *result);
358 // @}
359 
360 /** Helper class for saving/restoring variable values on the stack, to allow
361  * for early-exit that preserves correctness */
362 template<typename T>
363 struct ScopedValue {
364  T &var;
366  /** Preserve the old value, restored at dtor time */
368  : var(var), old_value(var) {
369  }
370  /** Preserve the old value, then set the var to a new value. */
371  ScopedValue(T &var, T new_value)
372  : var(var), old_value(var) {
373  var = new_value;
374  }
376  var = old_value;
377  }
378  operator T() const {
379  return old_value;
380  }
381  // allow move but not copy
382  ScopedValue(const ScopedValue &that) = delete;
383  ScopedValue(ScopedValue &&that) noexcept = default;
384 };
385 
386 // Helpers for timing blocks of code. Put 'TIC;' at the start and
387 // 'TOC;' at the end. Timing is reported at the toc via
388 // debug(0). The calls can be nested and will pretty-print
389 // appropriately. Took this idea from matlab via Jon Barron.
390 //
391 // Note that this uses global state internally, and is not thread-safe
392 // at all. Only use it for single-threaded debugging sessions.
393 
394 void halide_tic_impl(const char *file, int line);
395 void halide_toc_impl(const char *file, int line);
396 #define HALIDE_TIC Halide::Internal::halide_tic_impl(__FILE__, __LINE__)
397 #define HALIDE_TOC Halide::Internal::halide_toc_impl(__FILE__, __LINE__)
398 #ifdef COMPILING_HALIDE
399 #define TIC HALIDE_TIC
400 #define TOC HALIDE_TOC
401 #endif
402 
403 // statically cast a value from one type to another: this is really just
404 // some syntactic sugar around static_cast<>() to avoid compiler warnings
405 // regarding 'bool' in some compliation configurations.
406 template<typename TO>
407 struct StaticCast {
408  template<typename FROM>
409  inline constexpr static TO value(const FROM &from) {
410  if constexpr (std::is_same<TO, bool>::value) {
411  return from != 0;
412  } else {
413  return static_cast<TO>(from);
414  }
415  }
416 };
417 
418 // Like std::is_convertible, but with additional tests for arithmetic types:
419 // ensure that the value will roundtrip losslessly (e.g., no integer truncation
420 // or dropping of fractional parts).
421 template<typename TO>
423  template<typename FROM>
424  inline constexpr static bool value(const FROM &from) {
425  if constexpr (std::is_convertible<FROM, TO>::value) {
426  if constexpr (std::is_arithmetic<TO>::value &&
427  std::is_arithmetic<FROM>::value &&
428  !std::is_same<TO, FROM>::value) {
429  const TO to = static_cast<TO>(from);
430  const FROM roundtripped = static_cast<FROM>(to);
431  return roundtripped == from;
432  } else {
433  return true;
434  }
435  } else {
436  return false;
437  }
438  }
439 };
440 
441 /** Emit a version of a string that is a valid identifier in C (. is replaced with _)
442  * If prefix_underscore is true (the default), an underscore will be prepended if the
443  * input starts with an alphabetic character to avoid reserved word clashes.
444  */
445 std::string c_print_name(const std::string &name, bool prefix_underscore = true);
446 
447 /** Return the LLVM_VERSION against which this libHalide is compiled. This is provided
448  * only for internal tests which need to verify behavior; please don't use this outside
449  * of Halide tests. */
450 int get_llvm_version();
451 
452 } // namespace Internal
453 
454 /** Set how much stack the compiler should use for compilation in
455  * bytes. This can also be set through the environment variable
456  * HL_COMPILER_STACK_SIZE, though this function takes precedence. A
457  * value of zero causes the compiler to just use the calling stack for
458  * all compilation tasks.
459  *
460  * Calling this or setting the environment variable should not be
461  * necessary. It is provided for three kinds of testing:
462  *
463  * First, Halide uses it in our internal tests to make sure
464  * we're not using a silly amount of stack size on some
465  * canary programs to avoid stack usage regressions.
466  *
467  * Second, if you have a mysterious crash inside a generator, you can
468  * set a larger stack size as a way to test if it's a stack
469  * overflow. Perhaps our default stack size is not large enough for
470  * your program and schedule. Use this call or the environment var as
471  * a workaround, and then open a bug with a reproducer at
472  * github.com/halide/Halide/issues so that we can determine what's
473  * going wrong that is causing your code to use so much stack.
474  *
475  * Third, perhaps using a side-stack is causing problems with
476  * sanitizing, debugging, or profiling tools. If this is a problem,
477  * you can set HL_COMPILER_STACK_SIZE to zero to make Halide stay on
478  * the main thread's stack.
479  */
480 void set_compiler_stack_size(size_t);
481 
482 /** The default amount of stack used for lowering and codegen. 32 MB
483  * ought to be enough for anyone. */
484 constexpr size_t default_compiler_stack_size = 32 * 1024 * 1024;
485 
486 /** Return how much stack size the compiler should use for calls that
487  * go through run_with_large_stack below. Currently that's lowering
488  * and codegen. If no call to set_compiler_stack_size has been made,
489  * this checks the value of the environment variable
490  * HL_COMPILER_STACK_SIZE. If that's unset, it returns
491  * default_compiler_stack_size, defined above. */
492 size_t get_compiler_stack_size();
493 
494 namespace Internal {
495 
496 /** Call the given action in a platform-specific context that
497  * provides at least the stack space returned by
498  * get_compiler_stack_size. If that value is zero, just calls the
499  * function on the calling thread. Otherwise on Windows this
500  * uses a Fiber, and on other platforms it uses swapcontext. */
501 void run_with_large_stack(const std::function<void()> &action);
502 
503 /** Portable versions of popcount, count-leading-zeros, and
504  count-trailing-zeros. */
505 // @{
506 int popcount64(uint64_t x);
507 int clz64(uint64_t x);
508 int ctz64(uint64_t x);
509 // @}
510 
511 } // namespace Internal
512 } // namespace Halide
513 
514 #endif
Halide::Internal::TemporaryFile::pathname
const std::string & pathname() const
Definition: Util.h:317
Halide::Internal::all_are_convertible
Definition: Util.h:232
Halide::set_compiler_stack_size
void set_compiler_stack_size(size_t)
Set how much stack the compiler should use for compilation in bytes.
Halide::Internal::run_with_large_stack
void run_with_large_stack(const std::function< void()> &action)
Call the given action in a platform-specific context that provides at least the stack space returned ...
Halide::Internal::clz64
int clz64(uint64_t x)
Halide::get_compiler_stack_size
size_t get_compiler_stack_size()
Return how much stack size the compiler should use for calls that go through run_with_large_stack bel...
Halide::Internal::running_program_name
std::string running_program_name()
Get the name of the currently running executable.
Halide::Internal::sub_would_overflow
bool sub_would_overflow(int bits, int64_t a, int64_t b)
Halide::Internal::halide_tic_impl
void halide_tic_impl(const char *file, int line)
Halide::Internal::FileStat
Definition: Util.h:240
Halide::Internal::replace_all
std::string replace_all(const std::string &str, const std::string &find, const std::string &replace)
Replace all matches of the second string in the first string with the last string.
Halide::min
Expr min(const FuncRef &a, const FuncRef &b)
Explicit overloads of min and max for FuncRef.
Definition: Func.h:584
Halide::Internal::split_string
std::vector< std::string > split_string(const std::string &source, const std::string &delim)
Split the source string using 'delim' as the divider.
Halide::Internal::make_entity_name
std::string make_entity_name(void *stack_ptr, const std::string &type, char prefix)
Make a unique name for an object based on the name of the stack variable passed in.
Halide::Internal::strip_namespaces
std::string strip_namespaces(const std::string &name)
Like extract_namespaces(), but strip and discard the namespaces, returning base name only.
Halide::Internal::get_env_variable
std::string get_env_variable(char const *env_var_name)
Get value of an environment variable.
Definition: halide_test_dirs.h:26
Halide::Internal::meta_and
Definition: Util.h:220
Halide::default_compiler_stack_size
constexpr size_t default_compiler_stack_size
The default amount of stack used for lowering and codegen.
Definition: Util.h:484
Halide::Internal::extract_namespaces
std::string extract_namespaces(const std::string &name, std::vector< std::string > &namespaces)
Returns base name and fills in namespaces, outermost one first in vector.
Halide::Internal::StaticCast::value
constexpr static TO value(const FROM &from)
Definition: Util.h:409
Halide::Internal::ScopedValue
Helper class for saving/restoring variable values on the stack, to allow for early-exit that preserve...
Definition: Util.h:363
Halide::Internal::ScopedValue::~ScopedValue
~ScopedValue()
Definition: Util.h:375
Halide::Internal::dir_rmdir
void dir_rmdir(const std::string &name)
Wrapper for rmdir().
Halide::Internal::StaticCast
Definition: Util.h:407
Halide::Internal::read_entire_file
std::vector< char > read_entire_file(const std::string &pathname)
Read the entire contents of a file into a vector<char>.
Halide::Internal::file_make_temp
std::string file_make_temp(const std::string &prefix, const std::string &suffix)
Create a unique file with a name of the form prefixXXXXXsuffix in an arbitrary (but writable) directo...
Halide::Internal::TemporaryFile::operator=
TemporaryFile & operator=(const TemporaryFile &)=delete
uint64_t
unsigned __INT64_TYPE__ uint64_t
Definition: runtime_internal.h:23
Halide::Internal::add_with_overflow
HALIDE_MUST_USE_RESULT bool add_with_overflow(int bits, int64_t a, int64_t b, int64_t *result)
Routines to perform arithmetic on signed types without triggering signed overflow.
Halide::Internal::add_would_overflow
bool add_would_overflow(int bits, int64_t a, int64_t b)
Routines to test if math would overflow for signed integers with the given number of bits.
Halide
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
Definition: AbstractGenerator.h:19
Halide::Internal::ensure_no_file_exists
void ensure_no_file_exists(const std::string &name)
Ensure that no file with this path exists.
Halide::LinkageType::Internal
@ Internal
Not visible externally, similar to 'static' linkage in C.
Halide::Internal::ScopedValue::ScopedValue
ScopedValue(T &var, T new_value)
Preserve the old value, then set the var to a new value.
Definition: Util.h:371
Halide::Internal::FileStat::gid
uint32_t gid
Definition: Util.h:244
Halide::Internal::write_entire_file
void write_entire_file(const std::string &pathname, const void *source, size_t source_len)
Create or replace the contents of a file with a given pointer-and-length of memory.
Halide::Internal::file_stat
FileStat file_stat(const std::string &name)
Wrapper for stat().
Halide::Internal::fold_right
T fold_right(const std::vector< T > &vec, Fn f)
Returns a right fold of a vector.
Definition: Util.h:207
Halide::Internal::file_unlink
void file_unlink(const std::string &name)
Wrapper for unlink().
HALIDE_MUST_USE_RESULT
#define HALIDE_MUST_USE_RESULT
Definition: HalideRuntime.h:56
Halide::Internal::assert_no_file_exists
void assert_no_file_exists(const std::string &name)
assert-fail if the file DOES exist.
Halide::Internal::TemporaryFile::detach
void detach()
Definition: Util.h:328
Halide::Internal::safe_numeric_cast
DST safe_numeric_cast(SRC s)
Some numeric conversions are UB if the value won't fit in the result; safe_numeric_cast<>() is meant ...
Definition: Util.h:97
Halide::Internal::popcount64
int popcount64(uint64_t x)
Portable versions of popcount, count-leading-zeros, and count-trailing-zeros.
Halide::Internal::dir_make_temp
std::string dir_make_temp()
Create a unique directory in an arbitrary (but writable) directory; this is typically somewhere insid...
Halide::Internal::starts_with
bool starts_with(const std::string &str, const std::string &prefix)
Test if the first string starts with the second string.
Halide::Internal::FileStat::mode
uint32_t mode
Definition: Util.h:245
int64_t
signed __INT64_TYPE__ int64_t
Definition: runtime_internal.h:22
Halide::Internal::FileStat::file_size
uint64_t file_size
Definition: Util.h:241
Halide::Internal::FileStat::uid
uint32_t uid
Definition: Util.h:243
Halide::Internal::ScopedValue::ScopedValue
ScopedValue(T &var)
Preserve the old value, restored at dtor time.
Definition: Util.h:367
Halide::Internal::TemporaryFile::~TemporaryFile
~TemporaryFile()
Definition: Util.h:320
Halide::Internal::mul_with_overflow
HALIDE_MUST_USE_RESULT bool mul_with_overflow(int bits, int64_t a, int64_t b, int64_t *result)
Halide::Internal::halide_toc_impl
void halide_toc_impl(const char *file, int line)
Halide::Internal::fold_left
T fold_left(const std::vector< T > &vec, Fn f)
Perform a left fold of a vector.
Definition: Util.h:192
Halide::Internal::reinterpret_bits
DstType reinterpret_bits(const SrcType &src)
An aggressive form of reinterpret cast used for correct type-punning.
Definition: Util.h:133
HalideRuntime.h
memcpy
void * memcpy(void *s1, const void *s2, size_t n)
Halide::Internal::sub_with_overflow
HALIDE_MUST_USE_RESULT bool sub_with_overflow(int bits, int64_t a, int64_t b, int64_t *result)
Halide::Internal::TemporaryFile
A simple utility class that creates a temporary file in its ctor and deletes that file in its dtor; t...
Definition: Util.h:312
Halide::Internal::c_print_name
std::string c_print_name(const std::string &name, bool prefix_underscore=true)
Emit a version of a string that is a valid identifier in C (.
Halide::Internal::ScopedValue::old_value
T old_value
Definition: Util.h:365
Halide::Internal::ends_with
bool ends_with(const std::string &str, const std::string &suffix)
Test if the first string ends with the second string.
Halide::Internal::IsRoundtrippable
Definition: Util.h:422
Halide::Internal::FileStat::mod_time
uint32_t mod_time
Definition: Util.h:242
Halide::load_plugin
void load_plugin(const std::string &lib_name)
Load a plugin in the form of a dynamic library (e.g.
Halide::Internal::mul_would_overflow
bool mul_would_overflow(int bits, int64_t a, int64_t b)
Halide::Internal::IsRoundtrippable::value
constexpr static bool value(const FROM &from)
Definition: Util.h:424
Halide::Internal::meta_or
Definition: Util.h:226
Halide::Internal::unique_name
std::string unique_name(char prefix)
Generate a unique name starting with the given prefix.
uint32_t
unsigned __INT32_TYPE__ uint32_t
Definition: runtime_internal.h:25
Halide::max
Expr max(const FuncRef &a, const FuncRef &b)
Definition: Func.h:587
Halide::Internal::ctz64
int ctz64(uint64_t x)
Halide::Internal::file_exists
bool file_exists(const std::string &name)
Wrapper for access().
Halide::Internal::ScopedValue::var
T & var
Definition: Util.h:364
Halide::Internal::TemporaryFile::TemporaryFile
TemporaryFile(const std::string &prefix, const std::string &suffix)
Definition: Util.h:314
Halide::Internal::get_llvm_version
int get_llvm_version()
Return the LLVM_VERSION against which this libHalide is compiled.
Halide::Internal::assert_file_exists
void assert_file_exists(const std::string &name)
assert-fail if the file doesn't exist.