Halide 16.0.0
Halide compiler and libraries
Loading...
Searching...
No Matches
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__
13typedef __INT64_TYPE__ int64_t;
14typedef __UINT64_TYPE__ uint64_t;
15typedef __INT32_TYPE__ int32_t;
16typedef __UINT32_TYPE__ uint32_t;
17typedef __INT16_TYPE__ int16_t;
18typedef __UINT16_TYPE__ uint16_t;
19typedef __INT8_TYPE__ int8_t;
20typedef __UINT8_TYPE__ uint8_t;
21#else
22typedef signed __INT64_TYPE__ int64_t;
23typedef unsigned __INT64_TYPE__ uint64_t;
24typedef signed __INT32_TYPE__ int32_t;
25typedef unsigned __INT32_TYPE__ uint32_t;
26typedef signed __INT16_TYPE__ int16_t;
27typedef unsigned __INT16_TYPE__ uint16_t;
28typedef signed __INT8_TYPE__ int8_t;
29typedef unsigned __INT8_TYPE__ uint8_t;
30#endif
31typedef __SIZE_TYPE__ size_t;
32typedef __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
63typedef uint64_t uintptr_t;
64typedef int64_t intptr_t;
65#endif
66
67#ifdef BITS_32
68typedef uint32_t uintptr_t;
69typedef int32_t intptr_t;
70#endif
71
72#if !defined(BITS_32) && !defined(BITS_64)
73typedef __UINTPTR_TYPE__ uintptr_t;
74typedef __INTPTR_TYPE__ intptr_t;
75static_assert(sizeof(uintptr_t) == sizeof(void *));
76static_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
83extern "C" {
84void *halide_malloc(void *user_context, size_t x);
85void halide_free(void *user_context, void *ptr);
87WEAK void halide_print(void *user_context, const char *msg);
88WEAK void halide_error(void *user_context, const char *msg);
89WEAK void (*halide_set_custom_print(void (*print)(void *, const char *)))(void *, const char *);
90WEAK void (*halide_set_error_handler(void (*handler)(void *, const char *)))(void *, const char *);
91
92char *getenv(const char *);
93void free(void *);
94void *malloc(size_t);
95const char *strstr(const char *, const char *);
96int atoi(const char *);
97int strcmp(const char *s, const char *t);
98int strncmp(const char *s, const char *t, size_t n);
99size_t strlen(const char *s);
100const char *strchr(const char *s, int c);
101void *memcpy(void *s1, const void *s2, size_t n);
102void *memmove(void *dest, const void *src, size_t n);
103int memcmp(const void *s1, const void *s2, size_t n);
104void *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
115WEAK_INLINE void *halide_fopen(const char *filename, const char *type);
116
117int fileno(void *);
118int fclose(void *);
119int close(int);
120size_t fwrite(const void *, size_t, size_t, void *);
121ssize_t write(int fd, const void *buf, size_t bytes);
122int remove(const char *pathname);
123int ioctl(int fd, unsigned long request, ...);
124char *strncpy(char *dst, const char *src, size_t n);
125void 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
135struct halide_buffer_t;
136struct halide_type_t;
137WEAK char *halide_string_to_string(char *dst, char *end, const char *arg);
138WEAK char *halide_double_to_string(char *dst, char *end, double arg, int scientific);
139WEAK char *halide_int64_to_string(char *dst, char *end, int64_t arg, int digits);
140WEAK char *halide_uint64_to_string(char *dst, char *end, uint64_t arg, int digits);
141WEAK char *halide_pointer_to_string(char *dst, char *end, const void *arg);
142WEAK char *halide_buffer_to_string(char *dst, char *end, const halide_buffer_t *arg);
143WEAK 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.
146WEAK void *halide_get_symbol(const char *name);
147// Platform specific implementations of dlopen/dlsym.
148WEAK void *halide_load_library(const char *name);
149// If lib is nullptr, this call should be equivalent to halide_get_symbol(name).
150WEAK void *halide_get_library_symbol(void *lib, const char *name);
151
152WEAK int halide_start_clock(void *user_context);
153WEAK int64_t halide_current_time_ns(void *user_context);
154WEAK void halide_sleep_ms(void *user_context, int ms);
155WEAK void halide_device_free_as_destructor(void *user_context, void *obj);
156WEAK void halide_device_and_host_free_as_destructor(void *user_context, void *obj);
157WEAK 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.
162 void *pipeline_state,
163 uint64_t *f_values);
164WEAK void halide_profiler_memory_allocate(void *user_context,
165 void *pipeline_state,
166 int func_id,
167 uint64_t incr);
168WEAK void halide_profiler_memory_free(void *user_context,
169 void *pipeline_state,
170 int func_id,
171 uint64_t decr);
173 const char *pipeline_name,
174 int num_funcs,
175 const uint64_t *func_names);
177
178WEAK int halide_device_and_host_malloc(void *user_context, struct halide_buffer_t *buf,
179 const struct halide_device_interface_t *device_interface);
180WEAK int halide_device_and_host_free(void *user_context, struct halide_buffer_t *buf);
181
183
184WEAK 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.
204WEAK_INLINE void *halide_internal_aligned_alloc(size_t alignment, size_t size);
206
208
209} // extern "C"
210
211template<typename T>
212ALWAYS_INLINE T align_up(T p, size_t alignment) {
213 return (p + alignment - 1) & ~(alignment - 1);
214}
215
216template<typename T>
218 return (value != 0) && ((value & (value - 1)) == 0);
219}
220
221namespace {
222template<typename T>
223ALWAYS_INLINE void swap(T &a, T &b) {
224 T t = a;
225 a = b;
226 b = t;
227}
228
229template<typename T>
230ALWAYS_INLINE T max(const T &a, const T &b) {
231 return a > b ? a : b;
232}
233
234template<typename T>
235ALWAYS_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).
246namespace Halide {
247namespace Runtime {
248namespace Internal {
249// Empty
250}
251} // namespace Runtime
252} // namespace Halide
253using 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
size_t strlen(const char *string)
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 min(const FuncRef &a, const FuncRef &b)
Explicit overloads of min and max for FuncRef.
Definition Func.h:584
Expr max(const FuncRef &a, const FuncRef &b)
Definition Func.h:587
unsigned __INT64_TYPE__ uint64_t
int remove(const char *pathname)
const char * strchr(const char *s, int c)
ALWAYS_INLINE T is_power_of_two(T value)
__INTPTR_TYPE__ intptr_t
signed __INT64_TYPE__ int64_t
WEAK int halide_host_cpu_count()
int ioctl(int fd, unsigned long request,...)
int fileno(void *)
WEAK void * halide_get_library_symbol(void *lib, const char *name)
WEAK char * halide_uint64_to_string(char *dst, char *end, uint64_t arg, int digits)
int strcmp(const char *s, const char *t)
#define WEAK_INLINE
void * halide_malloc(void *user_context, size_t x)
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)
void * memmove(void *dest, const void *src, size_t n)
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_load_library(const char *name)
WEAK void halide_device_free_as_destructor(void *user_context, void *obj)
WEAK void halide_sleep_ms(void *user_context, int ms)
size_t fwrite(const void *, size_t, size_t, void *)
__UINTPTR_TYPE__ uintptr_t
int fclose(void *)
int atoi(const char *)
void * malloc(size_t)
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 char * halide_type_to_string(char *dst, char *end, const halide_type_t *arg)
WEAK void halide_release_jit_module()
WEAK void * halide_get_symbol(const char *name)
signed __INT32_TYPE__ int32_t
WEAK int halide_profiler_pipeline_start(void *user_context, const char *pipeline_name, int num_funcs, const uint64_t *func_names)
unsigned __INT8_TYPE__ uint8_t
WEAK void halide_profiler_stack_peak_update(void *user_context, void *pipeline_state, uint64_t *f_values)
WEAK void halide_device_and_host_free_as_destructor(void *user_context, void *obj)
__PTRDIFF_TYPE__ ptrdiff_t
WEAK void(*)(void *, const char *) halide_set_custom_print(void(*print)(void *, const char *))
void halide_thread_yield()
char * strncpy(char *dst, const char *src, size_t n)
unsigned __INT16_TYPE__ uint16_t
WEAK char * halide_int64_to_string(char *dst, char *end, int64_t arg, int digits)
WEAK char * halide_pointer_to_string(char *dst, char *end, const void *arg)
void * memcpy(void *s1, const void *s2, size_t n)
ssize_t write(int fd, const void *buf, size_t bytes)
WEAK void halide_print(void *user_context, const char *msg)
int memcmp(const void *s1, const void *s2, size_t n)
#define ALWAYS_INLINE
__SIZE_TYPE__ size_t
WEAK_INLINE int halide_internal_malloc_alignment()
void * memset(void *s, int val, size_t n)
unsigned __INT32_TYPE__ uint32_t
ptrdiff_t ssize_t
WEAK char * halide_double_to_string(char *dst, char *end, double arg, int scientific)
WEAK void halide_profiler_memory_allocate(void *user_context, void *pipeline_state, int func_id, uint64_t incr)
WEAK int64_t halide_current_time_ns(void *user_context)
signed __INT16_TYPE__ int16_t
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_INLINE void * halide_fopen(const char *filename, const char *type)
const char * strstr(const char *, const char *)
signed __INT8_TYPE__ int8_t
#define WEAK
int close(int)
WEAK char * halide_buffer_to_string(char *dst, char *end, const halide_buffer_t *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)
char * getenv(const char *)
WEAK void halide_profiler_memory_free(void *user_context, void *pipeline_state, int func_id, uint64_t decr)
WEAK_INLINE void * halide_internal_aligned_alloc(size_t alignment, size_t size)
WEAK char * halide_string_to_string(char *dst, char *end, const char *arg)
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.