1 #ifndef HALIDE_HALIDERUNTIMEHEXAGONHOST_H
2 #define HALIDE_HALIDERUNTIMEHEXAGONHOST_H
3 
4 // Don't include HalideRuntime.h if the contents of it were already pasted into a generated header above this one
5 #ifndef HALIDE_HALIDERUNTIME_H
6 
7 #include "HalideRuntime.h"
8 
9 #endif
10 
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14 
15 /** \file
16  *  Routines specific to the Halide Hexagon host-side runtime.
17  */
18 
19 #define HALIDE_RUNTIME_HEXAGON
20 
21 typedef int halide_hexagon_handle_t;
22 
23 extern const struct halide_device_interface_t *halide_hexagon_device_interface();
24 
25 /** Check if the Hexagon runtime (libhalide_hexagon_host.so) is
26  * available. If it is not, pipelines using Hexagon will fail. */
27 extern bool halide_is_hexagon_available(void *user_context);
28 
29 /** The device handle for Hexagon is simply a pointer and size, stored
30  * in the dev field of the halide_buffer_t. If the buffer is allocated in a
31  * particular way (ion_alloc), the buffer will be shared with Hexagon
32  * (not copied). The device field of the halide_buffer_t must be NULL when this
33  * routine is called. This call can fail due to running out of memory
34  * or being passed an invalid device handle. The device and host
35  * dirty bits are left unmodified. */
36 extern int halide_hexagon_wrap_device_handle(void *user_context, struct halide_buffer_t *buf,
37                                              void *ptr, uint64_t size);
38 
39 /** Disconnect this halide_buffer_t from the device handle it was
40  * previously wrapped around. Should only be called for a
41  * halide_buffer_t that halide_hexagon_wrap_device_handle was
42  * previously called on. Frees any storage associated with the binding
43  * of the halide_buffer_t and the device handle, but does not free the
44  * device handle. The device field of the halide_buffer_t will be NULL
45  * on return. */
46 extern int halide_hexagon_detach_device_handle(void *user_context, struct halide_buffer_t *buf);
47 
48 /** Return the underlying device handle for a halide_buffer_t. If there is
49  * no device memory (dev field is NULL), this returns 0. */
50 extern void *halide_hexagon_get_device_handle(void *user_context, struct halide_buffer_t *buf);
51 extern uint64_t halide_hexagon_get_device_size(void *user_context, struct halide_buffer_t *buf);
52 
53 /** Power HVX on and off. Calling a Halide pipeline will do this
54  * automatically on each pipeline invocation; however, it costs a
55  * small but possibly significant amount of time for short running
56  * pipelines. To avoid this cost, HVX can be powered on prior to
57  * running several pipelines, and powered off afterwards. If HVX is
58  * powered on, subsequent calls to power HVX on will be cheap. */
59 // @{
60 extern int halide_hexagon_power_hvx_on(void *user_context);
61 extern int halide_hexagon_power_hvx_off(void *user_context);
62 extern void halide_hexagon_power_hvx_off_as_destructor(void *user_context, void * /* obj */);
63 // @}
64 
65 /** Power modes for Hexagon. */
66 typedef enum halide_hexagon_power_mode_t {
67     halide_hexagon_power_low = 0,
68     halide_hexagon_power_nominal = 1,
69     halide_hexagon_power_turbo = 2,
70     halide_hexagon_power_default = 3,  /// Resets power to its default state.
71     halide_hexagon_power_low_plus = 4,
72     halide_hexagon_power_low_2 = 5,
73     halide_hexagon_power_nominal_plus = 6,
74 
75     // These are deprecated.
76     halide_hvx_power_low = halide_hexagon_power_low,
77     halide_hvx_power_nominal = halide_hexagon_power_nominal,
78     halide_hvx_power_turbo = halide_hexagon_power_turbo,
79     halide_hvx_power_default = halide_hexagon_power_default,
80 } halide_hexagon_power_mode_t;
81 
82 /** More detailed power settings to control Hexagon.
83  * @param set_mips - Set to TRUE to requst MIPS
84  * @param mipsPerThread - mips requested per thread, to establish a minimal clock frequency per HW thread
85  * @param mipsTotal - Total mips requested, to establish total number of MIPS required across all HW threads
86  * @param set_bus_bw - Set to TRUE to request bus_bw
87  * @param bwMeagabytesPerSec - Max bus BW requested (megabytes per second)
88  * @param busbwUsagePercentage - Percentage of time during which bwBytesPerSec BW is required from the bus (0..100)
89  * @param set_latency - Set to TRUE to set latency
90  * @param latency - maximum hardware wakeup latency in microseconds.  The
91  *                  higher the value the deeper state of sleep
92  *                  that can be entered but the longer it may
93  *                  take to awaken. Only values > 0 are supported (1 microsecond is the smallest valid value)
94  */
95 typedef struct {
96     bool set_mips;
97     unsigned int mipsPerThread;
98     unsigned int mipsTotal;
99     bool set_bus_bw;
100     unsigned int bwMegabytesPerSec;
101     unsigned short busbwUsagePercentage;
102     bool set_latency;
103     int latency;
104 } halide_hexagon_power_t;
105 
106 // This is deprecated.
107 typedef halide_hexagon_power_t halide_hvx_power_perf_t;
108 
109 /** Set a performance target for Hexagon. Hexagon applications can
110  * vote for the performance levels they want, which may or may not be
111  * respected by Hexagon. Applications should be careful not to leave
112  * Hexagon in a high power state for too long. These functions can
113  * significantly increase standby power consumption. Use
114  * halide_hexagon_power_default to reset performance to the default
115  * power state. */
116 // @{
117 extern int halide_hexagon_set_performance_mode(void *user_context, halide_hexagon_power_mode_t mode);
118 extern int halide_hexagon_set_performance(void *user_context, halide_hexagon_power_t *perf);
119 // @}
120 
121 /** Set the default priority for Halide Hexagon user threads:
122  *   - Valid priority values range from 1 to 255
123  *   - Smaller number for higher priority
124  *   - The highest priority for a user thread is 1
125  *   - Priority 0 is reserved for OS usage
126  * If this routine is not called, the priority will default to 100.
127  * This is intended to be called before dispatching any pipeline. */
128 // @{
129 extern int halide_hexagon_set_thread_priority(void *user_context, int priority);
130 // @}
131 
132 /** These are forward declared here to allow clients to override the
133  *  Halide Hexagon runtime. Do not call them. */
134 // @{
135 extern int halide_hexagon_initialize_kernels(void *user_context,
136                                              void **module_ptr,
137                                              const uint8_t *code, uint64_t code_size,
138                                              const uint8_t *runtime, uint64_t runtime_size);
139 extern int halide_hexagon_run(void *user_context,
140                               void *module_ptr,
141                               const char *name,
142                               halide_hexagon_handle_t *function,
143                               uint64_t arg_sizes[],
144                               void *args[],
145                               int arg_flags[]);
146 extern int halide_hexagon_device_release(void *user_context);
147 // @}
148 
149 #ifdef __cplusplus
150 }  // End extern "C"
151 #endif
152 
153 #endif  // HALIDE_HALIDERUNTIMEHEXAGONHOST_H
154