Halide
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 // Note that ALWAYS_INLINE should *always* also be `inline`.
55 #define ALWAYS_INLINE inline __attribute__((always_inline))
56 
57 // Note that WEAK_INLINE should *not* also be `inline`
58 #define WEAK_INLINE __attribute__((weak, always_inline))
59 
60 // --------------
61 
62 #ifdef BITS_64
63 typedef uint64_t uintptr_t;
64 typedef int64_t intptr_t;
65 #endif
66 
67 #ifdef BITS_32
68 typedef uint32_t uintptr_t;
69 typedef int32_t intptr_t;
70 #endif
71 
72 #if !defined(BITS_32) && !defined(BITS_64)
73 typedef __UINTPTR_TYPE__ uintptr_t;
74 typedef __INTPTR_TYPE__ intptr_t;
75 static_assert(sizeof(uintptr_t) == sizeof(void *));
76 static_assert(sizeof(intptr_t) == sizeof(void *));
77 #endif
78 
79 #define STDOUT_FILENO 1
80 #define STDERR_FILENO 2
81 
82 // Commonly-used extern functions
83 extern "C" {
84 void *halide_malloc(void *user_context, size_t x);
85 void halide_free(void *user_context, void *ptr);
86 WEAK int64_t halide_current_time_ns(void *user_context);
87 WEAK void halide_print(void *user_context, const char *msg);
88 WEAK void halide_error(void *user_context, const char *msg);
89 WEAK void (*halide_set_custom_print(void (*print)(void *, const char *)))(void *, const char *);
90 WEAK void (*halide_set_error_handler(void (*handler)(void *, const char *)))(void *, const char *);
91 
92 char *getenv(const char *);
93 void free(void *);
94 void *malloc(size_t);
95 const char *strstr(const char *, const char *);
96 int atoi(const char *);
97 int strcmp(const char *s, const char *t);
98 int strncmp(const char *s, const char *t, size_t n);
99 size_t strlen(const char *s);
100 const char *strchr(const char *s, int c);
101 void *memcpy(void *s1, const void *s2, size_t n);
102 void *memmove(void *dest, const void *src, size_t n);
103 int memcmp(const void *s1, const void *s2, size_t n);
104 void *memset(void *s, int val, size_t n);
105 
106 // No: don't call fopen() directly; some platforms may want to require
107 // use of other calls instead, so you should bottleneck all calls to fopen()
108 // to halide_fopen() instead, which allows for link-time overriding.
109 //
110 // Use fopen+fileno+fclose instead of open+close - the value of the
111 // flags passed to open are different on every platform
112 //
113 // void *fopen(const char *, const char *);
114 
115 WEAK_INLINE void *halide_fopen(const char *filename, const char *type);
116 
117 int fileno(void *);
118 int fclose(void *);
119 int close(int);
120 size_t fwrite(const void *, size_t, size_t, void *);
121 ssize_t write(int fd, const void *buf, size_t bytes);
122 int remove(const char *pathname);
123 int ioctl(int fd, unsigned long request, ...);
124 char *strncpy(char *dst, const char *src, size_t n);
125 void abort();
126 
127 // Below are prototypes for various functions called by generated code
128 // and parts of the runtime but not exposed to users:
129 
130 // Similar to strncpy, but with various non-string arguments. Writes
131 // arg to dst. Does not write to pointer end or beyond. Returns
132 // pointer to one beyond the last character written so that calls can
133 // be chained.
134 
135 struct halide_buffer_t;
136 struct halide_type_t;
137 WEAK char *halide_string_to_string(char *dst, char *end, const char *arg);
138 WEAK char *halide_double_to_string(char *dst, char *end, double arg, int scientific);
139 WEAK char *halide_int64_to_string(char *dst, char *end, int64_t arg, int digits);
140 WEAK char *halide_uint64_to_string(char *dst, char *end, uint64_t arg, int digits);
141 WEAK char *halide_pointer_to_string(char *dst, char *end, const void *arg);
142 WEAK char *halide_buffer_to_string(char *dst, char *end, const halide_buffer_t *arg);
143 WEAK char *halide_type_to_string(char *dst, char *end, const halide_type_t *arg);
144 
145 // Search the current process for a symbol with the given name.
146 WEAK void *halide_get_symbol(const char *name);
147 // Platform specific implementations of dlopen/dlsym.
148 WEAK void *halide_load_library(const char *name);
149 // If lib is nullptr, this call should be equivalent to halide_get_symbol(name).
150 WEAK void *halide_get_library_symbol(void *lib, const char *name);
151 
152 WEAK int halide_start_clock(void *user_context);
153 WEAK int64_t halide_current_time_ns(void *user_context);
154 WEAK void halide_sleep_ms(void *user_context, int ms);
155 WEAK void halide_device_free_as_destructor(void *user_context, void *obj);
156 WEAK void halide_device_and_host_free_as_destructor(void *user_context, void *obj);
157 WEAK void halide_device_host_nop_free(void *user_context, void *obj);
158 
159 // The pipeline_state is declared as void* type since halide_profiler_pipeline_stats
160 // is defined inside HalideRuntime.h which includes this header file.
161 WEAK void halide_profiler_stack_peak_update(void *user_context,
162  void *pipeline_state,
163  uint64_t *f_values);
164 WEAK void halide_profiler_memory_allocate(void *user_context,
165  void *pipeline_state,
166  int func_id,
167  uint64_t incr);
168 WEAK void halide_profiler_memory_free(void *user_context,
169  void *pipeline_state,
170  int func_id,
171  uint64_t decr);
172 WEAK int halide_profiler_pipeline_start(void *user_context,
173  const char *pipeline_name,
174  int num_funcs,
175  const uint64_t *func_names);
177 
178 WEAK int halide_device_and_host_malloc(void *user_context, struct halide_buffer_t *buf,
179  const struct halide_device_interface_t *device_interface);
180 WEAK int halide_device_and_host_free(void *user_context, struct halide_buffer_t *buf);
181 
183 
184 WEAK int halide_trace_helper(void *user_context,
185  const char *func,
186  void *value, int *coords,
187  int type_code, int type_bits, int type_lanes,
188  int code,
189  int parent_id, int value_index, int dimensions,
190  const char *trace_tag);
191 
193  void *ptr;
194  size_t size;
196 };
197 
200 
201 // These are all intended to be inlined into other pieces of runtime code;
202 // they are not intended to be called or replaced by user code.
204 WEAK_INLINE void *halide_internal_aligned_alloc(size_t alignment, size_t size);
206 
207 void halide_thread_yield();
208 
209 } // extern "C"
210 
211 template<typename T>
212 ALWAYS_INLINE T align_up(T p, size_t alignment) {
213  return (p + alignment - 1) & ~(alignment - 1);
214 }
215 
216 template<typename T>
218  return (value != 0) && ((value & (value - 1)) == 0);
219 }
220 
221 namespace {
222 template<typename T>
223 ALWAYS_INLINE void swap(T &a, T &b) {
224  T t = a;
225  a = b;
226  b = t;
227 }
228 
229 template<typename T>
230 ALWAYS_INLINE T max(const T &a, const T &b) {
231  return a > b ? a : b;
232 }
233 
234 template<typename T>
235 ALWAYS_INLINE T min(const T &a, const T &b) {
236  return a < b ? a : b;
237 }
238 
239 } // namespace
240 
241 // A namespace for runtime modules to store their internal state
242 // in. Should not be for things communicated between runtime modules,
243 // because it's possible for them to be compiled with different c++
244 // name mangling due to mixing and matching target triples (this usually
245 // only affects Windows builds).
246 namespace Halide {
247 namespace Runtime {
248 namespace Internal {
249 // Empty
250 }
251 } // namespace Runtime
252 } // namespace Halide
253 using namespace Halide::Runtime::Internal;
254 
255 /** halide_abort_if_false() is a macro that calls halide_print if the supplied condition is
256  * false, then aborts. Used for unrecoverable errors, or should-never-happen errors.
257  *
258  * Note that this is *NOT* a debug-only macro;
259  * the condition will be checked in *all* build modes! */
260 #define _halide_stringify(x) #x
261 #define _halide_expand_and_stringify(x) _halide_stringify(x)
262 #define halide_abort_if_false(user_context, cond) \
263  do { \
264  if (!(cond)) { \
265  halide_print(user_context, __FILE__ ":" _halide_expand_and_stringify(__LINE__) " halide_abort_if_false() failed: " #cond "\n"); \
266  abort(); \
267  } \
268  } while (0)
269 
270 /** halide_debug_assert() is like halide_assert(), but only expands into a check when
271  * DEBUG_RUNTIME is defined. It is what you want to use in almost all cases. */
272 #ifdef DEBUG_RUNTIME
273 #define halide_debug_assert(user_context, cond) \
274  do { \
275  if (!(cond)) { \
276  halide_print(user_context, __FILE__ ":" _halide_expand_and_stringify(__LINE__) " halide_debug_assert() failed: " #cond "\n"); \
277  abort(); \
278  } \
279  } while (0)
280 #else
281 #define halide_debug_assert(user_context, cond)
282 #endif
283 
284 #endif // HALIDE_RUNTIME_INTERNAL_H
halide_get_library_symbol
WEAK void * halide_get_library_symbol(void *lib, const char *name)
halide_free
void halide_free(void *user_context, void *ptr)
int32_t
signed __INT32_TYPE__ int32_t
Definition: runtime_internal.h:24
halide_double_to_string
WEAK char * halide_double_to_string(char *dst, char *end, double arg, int scientific)
halide_type_to_string
WEAK char * halide_type_to_string(char *dst, char *end, const halide_type_t *arg)
halide_internal_aligned_alloc
WEAK_INLINE void * halide_internal_aligned_alloc(size_t alignment, size_t size)
halide_error
WEAK void halide_error(void *user_context, const char *msg)
halide_set_error_handler
WEAK void(*)(void *, const char *) halide_set_error_handler(void(*handler)(void *, const char *))
Definition: runtime_internal.h:90
uint8_t
unsigned __INT8_TYPE__ uint8_t
Definition: runtime_internal.h:29
halide_sleep_ms
WEAK void halide_sleep_ms(void *user_context, int ms)
is_power_of_two
ALWAYS_INLINE T is_power_of_two(T value)
Definition: runtime_internal.h:217
uint16_t
unsigned __INT16_TYPE__ uint16_t
Definition: runtime_internal.h:27
halide_device_and_host_free
WEAK int halide_device_and_host_free(void *user_context, struct halide_buffer_t *buf)
halide_profiler_memory_allocate
WEAK void halide_profiler_memory_allocate(void *user_context, void *pipeline_state, int func_id, uint64_t incr)
memcmp
int memcmp(const void *s1, const void *s2, size_t n)
Halide::min
Expr min(const FuncRef &a, const FuncRef &b)
Explicit overloads of min and max for FuncRef.
Definition: Func.h:584
strchr
const char * strchr(const char *s, int c)
write
ssize_t write(int fd, const void *buf, size_t bytes)
int8_t
signed __INT8_TYPE__ int8_t
Definition: runtime_internal.h:28
halide_pseudostack_slot_t::ptr
void * ptr
Definition: runtime_internal.h:193
WEAK_INLINE
#define WEAK_INLINE
Definition: runtime_internal.h:58
halide_get_symbol
WEAK void * halide_get_symbol(const char *name)
getenv
char * getenv(const char *)
halide_use_jit_module
WEAK void halide_use_jit_module()
halide_type_t
A runtime tag for a type in the halide type system.
Definition: HalideRuntime.h:476
halide_buffer_to_string
WEAK char * halide_buffer_to_string(char *dst, char *end, const halide_buffer_t *arg)
fwrite
size_t fwrite(const void *, size_t, size_t, void *)
uintptr_t
__UINTPTR_TYPE__ uintptr_t
Definition: runtime_internal.h:73
uint64_t
unsigned __INT64_TYPE__ uint64_t
Definition: runtime_internal.h:23
malloc
void * malloc(size_t)
halide_start_clock
WEAK int halide_start_clock(void *user_context)
Halide
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
Definition: AbstractGenerator.h:19
abort
void abort()
memmove
void * memmove(void *dest, const void *src, size_t n)
atoi
int atoi(const char *)
Halide::LinkageType::Internal
@ Internal
Not visible externally, similar to 'static' linkage in C.
memset
void * memset(void *s, int val, size_t n)
halide_malloc
void * halide_malloc(void *user_context, size_t x)
Halide::print
Expr print(const std::vector< Expr > &values)
Create an Expr that prints out its value whenever it is evaluated.
halide_host_cpu_count
WEAK int halide_host_cpu_count()
halide_load_library
WEAK void * halide_load_library(const char *name)
halide_internal_malloc_alignment
WEAK_INLINE int halide_internal_malloc_alignment()
size_t
__SIZE_TYPE__ size_t
Definition: runtime_internal.h:31
halide_release_jit_module
WEAK void halide_release_jit_module()
halide_current_time_ns
WEAK int64_t halide_current_time_ns(void *user_context)
strncmp
int strncmp(const char *s, const char *t, size_t n)
halide_profiler_memory_free
WEAK void halide_profiler_memory_free(void *user_context, void *pipeline_state, int func_id, uint64_t decr)
halide_device_host_nop_free
WEAK void halide_device_host_nop_free(void *user_context, void *obj)
int64_t
signed __INT64_TYPE__ int64_t
Definition: runtime_internal.h:22
ssize_t
ptrdiff_t ssize_t
Definition: runtime_internal.h:34
close
int close(int)
halide_set_custom_print
WEAK void(*)(void *, const char *) halide_set_custom_print(void(*print)(void *, const char *))
Definition: runtime_internal.h:89
halide_pseudostack_slot_t::size
size_t size
Definition: runtime_internal.h:194
halide_internal_aligned_free
WEAK_INLINE void halide_internal_aligned_free(void *ptr)
halide_int64_to_string
WEAK char * halide_int64_to_string(char *dst, char *end, int64_t arg, int digits)
strcmp
int strcmp(const char *s, const char *t)
halide_fopen
WEAK_INLINE void * halide_fopen(const char *filename, const char *type)
halide_thread_yield
void halide_thread_yield()
halide_profiler_pipeline_start
WEAK int halide_profiler_pipeline_start(void *user_context, const char *pipeline_name, int num_funcs, const uint64_t *func_names)
fclose
int fclose(void *)
halide_trace_helper
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)
ALWAYS_INLINE
#define ALWAYS_INLINE
Definition: runtime_internal.h:55
align_up
ALWAYS_INLINE T align_up(T p, size_t alignment)
Definition: runtime_internal.h:212
halide_device_and_host_malloc
WEAK int halide_device_and_host_malloc(void *user_context, struct halide_buffer_t *buf, const struct halide_device_interface_t *device_interface)
memcpy
void * memcpy(void *s1, const void *s2, size_t n)
strstr
const char * strstr(const char *, const char *)
halide_pseudostack_slot_t::cumulative_size
size_t cumulative_size
Definition: runtime_internal.h:195
free
void free(void *)
halide_buffer_t
The raw representation of an image passed around by generated Halide code.
Definition: HalideRuntime.h:1490
halide_device_free_as_destructor
WEAK void halide_device_free_as_destructor(void *user_context, void *obj)
halide_uint64_to_string
WEAK char * halide_uint64_to_string(char *dst, char *end, uint64_t arg, int digits)
intptr_t
__INTPTR_TYPE__ intptr_t
Definition: runtime_internal.h:74
halide_pointer_to_string
WEAK char * halide_pointer_to_string(char *dst, char *end, const void *arg)
fileno
int fileno(void *)
halide_device_interface_t
Each GPU API provides a halide_device_interface_t struct pointing to the code that manages device all...
Definition: HalideRuntime.h:770
ioctl
int ioctl(int fd, unsigned long request,...)
int16_t
signed __INT16_TYPE__ int16_t
Definition: runtime_internal.h:26
halide_string_to_string
WEAK char * halide_string_to_string(char *dst, char *end, const char *arg)
halide_print
WEAK void halide_print(void *user_context, const char *msg)
WEAK
#define WEAK
Definition: runtime_internal.h:52
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_pseudostack_slot_t
Definition: runtime_internal.h:192
halide_device_and_host_free_as_destructor
WEAK void halide_device_and_host_free_as_destructor(void *user_context, void *obj)
strlen
size_t strlen(const char *s)
halide_filter_metadata_t
Definition: HalideRuntime.h:1734
ptrdiff_t
__PTRDIFF_TYPE__ ptrdiff_t
Definition: runtime_internal.h:32
strncpy
char * strncpy(char *dst, const char *src, size_t n)
Halide::Runtime::Internal
Definition: constants.h:13
halide_profiler_stack_peak_update
WEAK void halide_profiler_stack_peak_update(void *user_context, void *pipeline_state, uint64_t *f_values)
remove
int remove(const char *pathname)