Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions apps/hexagon_benchmarks/process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ int main(int argc, char **argv) {
std::vector<PipelineDescriptorBase *> pipelines = {&conv3x3a16_pipeline, &dilate3x3_pipeine, &median3x3_pipeline,
&gaussian5x5_pipeline, &sobel_pipeline, &conv3x3a32_pipeline};

#ifdef HALIDE_RUNTIME_HEXAGON
// Set thread_priority = 80 and stack_size = 32KB for dsp threads.
halide_hexagon_set_thread_params(NULL, 80, 32 * 1024);
#endif

for (PipelineDescriptorBase *p : pipelines) {
if (!p->defined()) {
continue;
Expand Down
16 changes: 9 additions & 7 deletions src/runtime/HalideRuntimeHexagonHost.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,16 +118,18 @@ extern int halide_hexagon_set_performance_mode(void *user_context, halide_hexago
extern int halide_hexagon_set_performance(void *user_context, halide_hexagon_power_t *perf);
// @}

/** Set the default priority for Halide Hexagon user threads:
* - Valid priority values range from 1 to 255
/** Set the default priority/stack_size for dsp threads:
* - Valid priority values range from 1 to 255. -1 to use default (100)
* - Stack size in bytes. Range: (16KB - 8MB). -1 to use default (16KB)
* - Smaller number for higher priority
* - The highest priority for a user thread is 1
* - Priority 0 is reserved for OS usage
* If this routine is not called, the priority will default to 100.
* This is intended to be called before dispatching any pipeline. */
// @{
extern int halide_hexagon_set_thread_priority(void *user_context, int priority);
// @}
* If halide_hexagon_set_thread_params routine is not called by the user,
* then it is called automatically during init_hexagon_runtime with
* priority=100 and stack size=16KB. It should be called before
* making any other FastRPC calls (because remote_session_control has to be
* the first fastRPC call made by the program). */
extern int halide_hexagon_set_thread_params(void *user_context, int priority, int stack_size);

/** These are forward declared here to allow clients to override the
* Halide Hexagon runtime. Do not call them. */
Expand Down
105 changes: 76 additions & 29 deletions src/runtime/hexagon_host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,20 @@ namespace Runtime {
namespace Internal {
namespace Hexagon {

#define FASTRPC_THREAD_PARAMS (1)
#define CDSP_DOMAIN_ID 3

static const int default_thread_priority = 100;
static const int default_stack_size = 16 * 1024; // 16KB
static int set_thread_params_called = false;

// Used with FASTRPC_THREAD_PARAMS req ID
struct remote_rpc_thread_params {
int domain; // Remote subsystem domain ID, pass -1 to set params for all domains
int prio; // user thread priority (1 to 255), pass -1 to use default
int stack_size; // user thread stack size, pass -1 to use default
};

struct ion_device_handle {
void *buffer;
size_t size;
Expand Down Expand Up @@ -39,7 +53,8 @@ typedef int (*remote_profiler_set_current_func_fn)(int);
typedef int (*remote_power_fn)();
typedef int (*remote_power_mode_fn)(int);
typedef int (*remote_power_perf_fn)(int, unsigned int, unsigned int, int, unsigned int, unsigned int, int, int);
typedef int (*remote_thread_priority_fn)(int);
typedef int (*remote_set_thread_params_fn)(int, int);
typedef int (*remote_session_control_fn)(uint32_t req, void *data, uint32_t datalen);

typedef void (*host_malloc_init_fn)();
typedef void *(*host_malloc_fn)(size_t);
Expand All @@ -56,7 +71,8 @@ WEAK remote_power_fn remote_power_hvx_on = nullptr;
WEAK remote_power_fn remote_power_hvx_off = nullptr;
WEAK remote_power_perf_fn remote_set_performance = nullptr;
WEAK remote_power_mode_fn remote_set_performance_mode = nullptr;
WEAK remote_thread_priority_fn remote_set_thread_priority = nullptr;
WEAK remote_set_thread_params_fn remote_set_thread_params = nullptr;
WEAK remote_session_control_fn remote_thread_session_control = nullptr;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should thread be included in the name here? According to the Hexagon SDK docs,remote_session_control can be used for more than just setting thread parameters. We may want to reuse this function for setting other non-thread parameters in the future.

In fact, I've been playing around with using "unsigned" execution mode (discussed here: #5200 (comment)). Using this branch, I was able to reuse remote_thread_session_control to enable said mode.


WEAK host_malloc_init_fn host_malloc_init = nullptr;
WEAK host_malloc_init_fn host_malloc_deinit = nullptr;
Expand Down Expand Up @@ -183,10 +199,17 @@ WEAK int init_hexagon_runtime(void *user_context) {
get_symbol(user_context, host_lib, "halide_hexagon_remote_power_hvx_off", remote_power_hvx_off, /* required */ false);
get_symbol(user_context, host_lib, "halide_hexagon_remote_set_performance", remote_set_performance, /* required */ false);
get_symbol(user_context, host_lib, "halide_hexagon_remote_set_performance_mode", remote_set_performance_mode, /* required */ false);
get_symbol(user_context, host_lib, "halide_hexagon_remote_set_thread_priority", remote_set_thread_priority, /* required */ false);
get_symbol(user_context, host_lib, "halide_hexagon_remote_set_thread_params", remote_set_thread_params, /* required */ false);
get_symbol(user_context, host_lib, "remote_session_control", remote_thread_session_control, /* required */ false);

host_malloc_init();

// Needs to be the first fastRPC call.
if (!set_thread_params_called) {
halide_hexagon_set_thread_params(nullptr, default_thread_priority,
default_stack_size);
}

return 0;
}

Expand Down Expand Up @@ -247,9 +270,9 @@ WEAK int halide_hexagon_initialize_kernels(void *user_context, void **state_ptr,
<< ", state_ptr: " << state_ptr
<< ", *state_ptr: " << *state_ptr
<< ", code: " << code
<< ", code_size: " << (int)code_size << ")\n"
<< ", code: " << runtime
<< ", code_size: " << (int)runtime_size << ")\n";
<< ", code_size: " << (int)code_size
<< ", runtime: " << runtime
<< ", runtime_size: " << (int)runtime_size << ")\n";
halide_assert(user_context, state_ptr != nullptr);

#ifdef DEBUG_RUNTIME
Expand Down Expand Up @@ -928,6 +951,53 @@ WEAK void halide_hexagon_power_hvx_off_as_destructor(void *user_context, void *
halide_hexagon_power_hvx_off(user_context);
}

// This function makes two fastrpc calls
// - remote_session_control for setting priority/stack_size for fastprc threads
// - remote_set_thread_params for setting priority/stack_size for user threads
// halide_hexagon_set_thread_params must be the first fastRPC call made
// by the program.
WEAK int halide_hexagon_set_thread_params(void *user_context, int priority, int stack_size) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed offline just now, renaming this to halide_hexagon_set_remote_thread_params makes more sense?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thanks

set_thread_params_called = true;
int result = init_hexagon_runtime(user_context);
if (result != 0) {
return result;
}

debug(user_context) << "halide_hexagon_set_thread_params\n";
if (!remote_thread_session_control) {
// This runtime doesn't support changing the thread params.
return 0;
}

// Change fastRPC default values to our default values
priority = (priority == -1) ? default_thread_priority : priority;
stack_size = (stack_size == -1) ? default_stack_size : stack_size;

// Set priority/stack-size of fastrpc created threads.
struct remote_rpc_thread_params th = {CDSP_DOMAIN_ID, priority, stack_size};
debug(user_context) << " remote_session_control("
<< "thread_priority: " << priority
<< ", thread_stack_size: " << stack_size << ") -> \n";
result = remote_thread_session_control(FASTRPC_THREAD_PARAMS,
(void *)&th, sizeof(th));
debug(user_context) << " " << result << "\n";
if (result != 0) {
error(user_context) << "remote_session_control failed.\n";
return -1;
}
// Set priority/stack-size of dsp user threads.
debug(user_context) << " remote_set_thread_params("
<< "thread_priority: " << priority
<< ", thread_stack_size: " << stack_size << ") -> \n";
result = remote_set_thread_params(priority, stack_size);
debug(user_context) << " " << result << "\n";
if (result != 0) {
error(user_context) << "remote_set_thread_params failed.\n";
return result;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this fastrcp error code not get conflated with a halide runtime error code?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it will, this should return -1 or some other halide error code.

}
return 0;
}

WEAK int halide_hexagon_set_performance_mode(void *user_context, halide_hexagon_power_mode_t mode) {
int result = init_hexagon_runtime(user_context);
if (result != 0) {
Expand Down Expand Up @@ -982,29 +1052,6 @@ WEAK int halide_hexagon_set_performance(void *user_context, halide_hexagon_power
return 0;
}

WEAK int halide_hexagon_set_thread_priority(void *user_context, int priority) {
int result = init_hexagon_runtime(user_context);
if (result != 0) {
return result;
}

debug(user_context) << "halide_hexagon_set_thread_priority\n";
if (!remote_set_thread_priority) {
// This runtime doesn't support changing the thread priority.
return 0;
}

debug(user_context) << " remote_set_thread_priority -> ";
result = remote_set_thread_priority(priority);
debug(user_context) << " " << result << "\n";
if (result != 0) {
error(user_context) << "remote_set_thread_priority failed.\n";
return result;
}

return 0;
}

WEAK const halide_device_interface_t *halide_hexagon_device_interface() {
return &hexagon_device_interface;
}
Expand Down
Binary file not shown.
Binary file not shown.
Binary file modified src/runtime/hexagon_remote/bin/host/libhalide_hexagon_host.so
Binary file not shown.
Binary file added src/runtime/hexagon_remote/bin/host/sim_host.o
Binary file not shown.
2 changes: 1 addition & 1 deletion src/runtime/hexagon_remote/bin/src/halide_hexagon_remote.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ __QAIC_HEADER_EXPORT int __QAIC_HEADER(halide_hexagon_remote_poll_profiler_state
__QAIC_HEADER_EXPORT int __QAIC_HEADER(halide_hexagon_remote_profiler_set_current_func)(int current_func) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(halide_hexagon_remote_set_performance_mode)(int mode) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(halide_hexagon_remote_set_performance)(int set_mips, unsigned int mipsPerThread, unsigned int mipsTotal, int set_bus_bw, unsigned int bwMegabytesPerSec, unsigned int busbwUsagePercentage, int set_latency, int latency) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(halide_hexagon_remote_set_thread_priority)(int priority) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(halide_hexagon_remote_set_thread_params)(int priority, int stack_size) __QAIC_HEADER_ATTRIBUTE;
#ifdef __cplusplus
}
#endif
Expand Down
Loading