Halide  20.0.0
Halide compiler and libraries
runtime_internal.h
Go to the documentation of this file.
1 #ifndef HALIDE_RUNTIME_INTERNAL_H
2 #define HALIDE_RUNTIME_INTERNAL_H
3 
4 #ifdef COMPILING_HALIDE_RUNTIME_TESTS
5 // Only allowed if building Halide runtime tests ... since they use system compiler which may be GCC or MSVS
6 #else
7 #if __STDC_HOSTED__
8 #error "Halide runtime files must be compiled with clang in freestanding mode."
9 #endif
10 #endif
11 
12 #ifdef __UINT8_TYPE__
13 typedef __INT64_TYPE__ int64_t;
14 typedef __UINT64_TYPE__ uint64_t;
15 typedef __INT32_TYPE__ int32_t;
16 typedef __UINT32_TYPE__ uint32_t;
17 typedef __INT16_TYPE__ int16_t;
18 typedef __UINT16_TYPE__ uint16_t;
19 typedef __INT8_TYPE__ int8_t;
20 typedef __UINT8_TYPE__ uint8_t;
21 #else
22 typedef signed __INT64_TYPE__ int64_t;
23 typedef unsigned __INT64_TYPE__ uint64_t;
24 typedef signed __INT32_TYPE__ int32_t;
25 typedef unsigned __INT32_TYPE__ uint32_t;
26 typedef signed __INT16_TYPE__ int16_t;
27 typedef unsigned __INT16_TYPE__ uint16_t;
28 typedef signed __INT8_TYPE__ int8_t;
29 typedef unsigned __INT8_TYPE__ uint8_t;
30 #endif
31 typedef __SIZE_TYPE__ size_t;
32 typedef __PTRDIFF_TYPE__ ptrdiff_t;
33 
35 
36 // --------------
37 
38 // In Halide runtime code, most functions should just be WEAK, whether or not
39 // they're part of the public API.
40 //
41 // ALWAYS_INLINE is for things that either should be inlined for performance
42 // reasons, or for things that go into every compiled pipeline (not just the
43 // standalone runtime), as those things have to either disappear entirely by
44 // being inlined away, or have "inline" linkage to avoid multiple definition
45 // errors on platforms that have no weak linkage.
46 //
47 // WEAK_INLINED is a special case where we are 'inlining' the bitcode at
48 // bitcode-compilation time (rather than C++ compilation time); it's needed
49 // for a few places in the runtime where we can't inline in the traditional
50 // way.
51 
52 #define WEAK __attribute__((weak))
53 
54 #define NEVER_INLINE __attribute__((noinline))
55 
56 // Note that ALWAYS_INLINE should *always* also be `inline`.
57 #define ALWAYS_INLINE inline __attribute__((always_inline))
58 
59 // Note that WEAK_INLINE should *not* also be `inline`
60 #define WEAK_INLINE __attribute__((weak, always_inline))
61 
62 // --------------
63 
64 #ifdef BITS_64
65 typedef uint64_t uintptr_t;
66 typedef int64_t intptr_t;
67 #endif
68 
69 #ifdef BITS_32
70 typedef uint32_t uintptr_t;
71 typedef int32_t intptr_t;
72 #endif
73 
74 #if !defined(BITS_32) && !defined(BITS_64)
75 typedef __UINTPTR_TYPE__ uintptr_t;
76 typedef __INTPTR_TYPE__ intptr_t;
77 static_assert(sizeof(uintptr_t) == sizeof(void *));
78 static_assert(sizeof(intptr_t) == sizeof(void *));
79 #endif
80 
81 #define STDOUT_FILENO 1
82 #define STDERR_FILENO 2
83 
84 // Commonly-used extern functions
85 extern "C" {
86 void *halide_malloc(void *user_context, size_t x);
87 void halide_free(void *user_context, void *ptr);
89 WEAK void halide_print(void *user_context, const char *msg);
90 WEAK void halide_error(void *user_context, const char *msg);
91 WEAK void (*halide_set_custom_print(void (*print)(void *, const char *)))(void *, const char *);
92 WEAK void (*halide_set_error_handler(void (*handler)(void *, const char *)))(void *, const char *);
93 
94 char *getenv(const char *);
95 void free(void *);
96 void *malloc(size_t);
97 const char *strstr(const char *, const char *);
98 int atoi(const char *);
99 int strcmp(const char *s, const char *t);
100 int strncmp(const char *s, const char *t, size_t n);
101 size_t strlen(const char *s);
102 const char *strchr(const char *s, int c);
103 void *memcpy(void *s1, const void *s2, size_t n);
104 void *memmove(void *dest, const void *src, size_t n);
105 int memcmp(const void *s1, const void *s2, size_t n);
106 void *memset(void *s, int val, size_t n);
107 
108 // No: don't call fopen() directly; some platforms may want to require
109 // use of other calls instead, so you should bottleneck all calls to fopen()
110 // to halide_fopen() instead, which allows for link-time overriding.
111 //
112 // Use fopen+fileno+fclose instead of open+close - the value of the
113 // flags passed to open are different on every platform
114 //
115 // void *fopen(const char *, const char *);
116 
117 WEAK_INLINE void *halide_fopen(const char *filename, const char *type);
118 
119 int fileno(void *);
120 int fclose(void *);
121 int close(int);
122 size_t fwrite(const void *, size_t, size_t, void *);
123 ssize_t write(int fd, const void *buf, size_t bytes);
124 int remove(const char *pathname);
125 int ioctl(int fd, unsigned long request, ...);
126 char *strncpy(char *dst, const char *src, size_t n);
127 void abort();
128 
129 // Below are prototypes for various functions called by generated code
130 // and parts of the runtime but not exposed to users:
131 
132 // Similar to strncpy, but with various non-string arguments. Writes
133 // arg to dst. Does not write to pointer end or beyond. Returns
134 // pointer to one beyond the last character written so that calls can
135 // be chained.
136 
137 struct halide_buffer_t;
138 struct halide_type_t;
139 WEAK char *halide_string_to_string(char *dst, char *end, const char *arg);
140 WEAK char *halide_double_to_string(char *dst, char *end, double arg, int scientific);
141 WEAK char *halide_int64_to_string(char *dst, char *end, int64_t arg, int digits);
142 WEAK char *halide_uint64_to_string(char *dst, char *end, uint64_t arg, int digits);
143 WEAK char *halide_pointer_to_string(char *dst, char *end, const void *arg);
144 WEAK char *halide_buffer_to_string(char *dst, char *end, const halide_buffer_t *arg);
145 WEAK char *halide_type_to_string(char *dst, char *end, const halide_type_t *arg);
146 
147 // Search the current process for a symbol with the given name.
148 WEAK void *halide_get_symbol(const char *name);
149 // Platform specific implementations of dlopen/dlsym.
150 WEAK void *halide_load_library(const char *name);
151 // If lib is nullptr, this call should be equivalent to halide_get_symbol(name).
152 WEAK void *halide_get_library_symbol(void *lib, const char *name);
153 
156 WEAK void halide_sleep_us(void *user_context, int us);
160 
161 struct halide_profiler_instance_state;
163  halide_profiler_instance_state *instance,
164  uint64_t *f_values);
166  halide_profiler_instance_state *instance,
167  int func_id,
168  uint64_t incr);
170  halide_profiler_instance_state *instance,
171  int func_id,
172  uint64_t decr);
174  const char *pipeline_name,
175  int num_funcs,
176  const uint64_t *func_names,
177  halide_profiler_instance_state *instance);
179  halide_profiler_instance_state *instance);
180 
184 
186 
188  const struct halide_device_interface_t *device_interface);
190 
192 
194  const char *func,
195  void *value, int *coords,
196  int type_code, int type_bits, int type_lanes,
197  int code,
198  int parent_id, int value_index, int dimensions,
199  const char *trace_tag);
200 
202  void *ptr;
203  size_t size;
205 };
206 
209 
210 // These are all intended to be inlined into other pieces of runtime code;
211 // they are not intended to be called or replaced by user code.
213 WEAK_INLINE void *halide_internal_aligned_alloc(size_t alignment, size_t size);
215 
217 
218 } // extern "C"
219 
220 template<typename T>
221 ALWAYS_INLINE T align_up(T p, size_t alignment) {
222  return (p + alignment - 1) & ~(alignment - 1);
223 }
224 
225 template<typename T>
227  return (value != 0) && ((value & (value - 1)) == 0);
228 }
229 
230 namespace {
231 template<typename T>
232 ALWAYS_INLINE void swap(T &a, T &b) noexcept {
233  T t = a;
234  a = b;
235  b = t;
236 }
237 
238 template<typename T>
239 ALWAYS_INLINE T max(const T &a, const T &b) {
240  return a > b ? a : b;
241 }
242 
243 template<typename T>
244 ALWAYS_INLINE T min(const T &a, const T &b) {
245  return a < b ? a : b;
246 }
247 
248 } // namespace
249 
250 // A namespace for runtime modules to store their internal state
251 // in. Should not be for things communicated between runtime modules,
252 // because it's possible for them to be compiled with different c++
253 // name mangling due to mixing and matching target triples (this usually
254 // only affects Windows builds).
255 namespace Halide {
256 namespace Runtime {
257 namespace Internal {
258 // Empty
259 }
260 } // namespace Runtime
261 } // namespace Halide
262 using namespace Halide::Runtime::Internal;
263 
264 /** halide_abort_if_false() is a macro that calls halide_print if the supplied condition is
265  * false, then aborts. Used for unrecoverable errors, or should-never-happen errors.
266  *
267  * Note that this is *NOT* a debug-only macro;
268  * the condition will be checked in *all* build modes! */
269 #define _halide_stringify(x) #x
270 #define _halide_expand_and_stringify(x) _halide_stringify(x)
271 #define halide_abort_if_false(user_context, cond) \
272  do { \
273  if (!(cond)) { \
274  halide_print(user_context, __FILE__ ":" _halide_expand_and_stringify(__LINE__) " halide_abort_if_false() failed: " #cond "\n"); \
275  abort(); \
276  } \
277  } while (0)
278 
279 /** halide_debug_assert() is like halide_assert(), but only expands into a check when
280  * DEBUG_RUNTIME is defined. It is what you want to use in almost all cases. */
281 #ifdef DEBUG_RUNTIME
282 #define halide_debug_assert(user_context, cond) \
283  do { \
284  if (!(cond)) { \
285  halide_print(user_context, __FILE__ ":" _halide_expand_and_stringify(__LINE__) " halide_debug_assert() failed: " #cond "\n"); \
286  abort(); \
287  } \
288  } while (0)
289 #else
290 #define halide_debug_assert(user_context, cond)
291 #endif
292 
293 #endif // HALIDE_RUNTIME_INTERNAL_H
ConstantInterval min(const ConstantInterval &a, const ConstantInterval &b)
ConstantInterval max(const ConstantInterval &a, const ConstantInterval &b)
auto end(reverse_adaptor< T > i)
Definition: Util.h:472
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
@ Internal
Not visible externally, similar to 'static' linkage in C.
Expr print(const std::vector< Expr > &values)
Create an Expr that prints out its value whenever it is evaluated.
unsigned __INT64_TYPE__ uint64_t
int remove(const char *pathname)
ALWAYS_INLINE T is_power_of_two(T value)
WEAK void halide_start_timer_chain()
WEAK void halide_profiler_memory_free(void *user_context, halide_profiler_instance_state *instance, int func_id, uint64_t decr)
__INTPTR_TYPE__ intptr_t
WEAK char * halide_buffer_to_string(char *dst, char *end, const halide_buffer_t *arg)
signed __INT64_TYPE__ int64_t
WEAK int halide_host_cpu_count()
int ioctl(int fd, unsigned long request,...)
int fileno(void *)
void * malloc(size_t)
int strcmp(const char *s, const char *t)
WEAK_INLINE void * halide_fopen(const char *filename, const char *type)
#define WEAK_INLINE
WEAK int halide_profiler_instance_end(void *user_context, halide_profiler_instance_state *instance)
WEAK int halide_profiler_instance_start(void *user_context, const char *pipeline_name, int num_funcs, const uint64_t *func_names, halide_profiler_instance_state *instance)
const char * strchr(const char *s, int c)
void halide_free(void *user_context, void *ptr)
WEAK int halide_device_and_host_malloc(void *user_context, struct halide_buffer_t *buf, const struct halide_device_interface_t *device_interface)
WEAK int halide_trace_helper(void *user_context, const char *func, void *value, int *coords, int type_code, int type_bits, int type_lanes, int code, int parent_id, int value_index, int dimensions, const char *trace_tag)
int strncmp(const char *s, const char *t, size_t n)
WEAK int halide_start_clock(void *user_context)
WEAK void halide_enable_timer_interrupt()
WEAK void * halide_get_symbol(const char *name)
WEAK void halide_device_free_as_destructor(void *user_context, void *obj)
WEAK char * halide_uint64_to_string(char *dst, char *end, uint64_t arg, int digits)
size_t fwrite(const void *, size_t, size_t, void *)
__UINTPTR_TYPE__ uintptr_t
WEAK char * halide_double_to_string(char *dst, char *end, double arg, int scientific)
int fclose(void *)
WEAK void halide_profiler_memory_allocate(void *user_context, halide_profiler_instance_state *instance, int func_id, uint64_t incr)
int atoi(const char *)
ALWAYS_INLINE T align_up(T p, size_t alignment)
WEAK int halide_device_and_host_free(void *user_context, struct halide_buffer_t *buf)
WEAK void halide_release_jit_module()
signed __INT32_TYPE__ int32_t
unsigned __INT8_TYPE__ uint8_t
WEAK void halide_disable_timer_interrupt()
WEAK void halide_device_and_host_free_as_destructor(void *user_context, void *obj)
void * memset(void *s, int val, size_t n)
WEAK char * halide_string_to_string(char *dst, char *end, const char *arg)
__PTRDIFF_TYPE__ ptrdiff_t
WEAK void(*)(void *, const char *) halide_set_custom_print(void(*print)(void *, const char *))
void halide_thread_yield()
void * memmove(void *dest, const void *src, size_t n)
unsigned __INT16_TYPE__ uint16_t
char * getenv(const char *)
WEAK char * halide_type_to_string(char *dst, char *end, const halide_type_t *arg)
ssize_t write(int fd, const void *buf, size_t bytes)
WEAK void halide_print(void *user_context, const char *msg)
WEAK void halide_profiler_stack_peak_update(void *user_context, halide_profiler_instance_state *instance, uint64_t *f_values)
int memcmp(const void *s1, const void *s2, size_t n)
WEAK_INLINE void * halide_internal_aligned_alloc(size_t alignment, size_t size)
#define ALWAYS_INLINE
size_t strlen(const char *s)
const char * strstr(const char *, const char *)
void * halide_malloc(void *user_context, size_t x)
__SIZE_TYPE__ size_t
WEAK_INLINE int halide_internal_malloc_alignment()
unsigned __INT32_TYPE__ uint32_t
ptrdiff_t ssize_t
WEAK void halide_sleep_us(void *user_context, int us)
WEAK int64_t halide_current_time_ns(void *user_context)
signed __INT16_TYPE__ int16_t
WEAK void * halide_get_library_symbol(void *lib, const char *name)
WEAK void halide_error(void *user_context, const char *msg)
WEAK void halide_use_jit_module()
void abort()
WEAK_INLINE void halide_internal_aligned_free(void *ptr)
WEAK void * halide_load_library(const char *name)
signed __INT8_TYPE__ int8_t
#define WEAK
char * strncpy(char *dst, const char *src, size_t n)
void * memcpy(void *s1, const void *s2, size_t n)
int close(int)
WEAK char * halide_pointer_to_string(char *dst, char *end, const void *arg)
WEAK void(*)(void *, const char *) halide_set_error_handler(void(*handler)(void *, const char *))
void free(void *)
WEAK void halide_device_host_nop_free(void *user_context, void *obj)
WEAK char * halide_int64_to_string(char *dst, char *end, int64_t arg, int digits)
The raw representation of an image passed around by generated Halide code.
Each GPU API provides a halide_device_interface_t struct pointing to the code that manages device all...
A runtime tag for a type in the halide type system.
void * user_context