pub trait TaskSystem {
// Required methods
unsafe fn alloc(
&self,
handle_ptr: *mut *mut c_void,
size: i64,
align: i32,
) -> *mut c_void;
unsafe fn launch(
&self,
handle_ptr: *mut *mut c_void,
f: extern "C" fn(*mut c_void, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32),
data: *mut c_void,
count0: i32,
count1: i32,
count2: i32,
);
unsafe fn sync(&self, handle: *mut c_void);
}
Expand description
Trait to be implemented to provide ISPC task execution functionality.
The runtime required functions for the ISPC task runtime will be forwarded directly to your struct, making this interface unsafe.
Required Methods§
Sourceunsafe fn alloc(
&self,
handle_ptr: *mut *mut c_void,
size: i64,
align: i32,
) -> *mut c_void
unsafe fn alloc( &self, handle_ptr: *mut *mut c_void, size: i64, align: i32, ) -> *mut c_void
Alloc is called when memory must be allocated to store parameters to pass to a task
and must return a pointer to an allocation of size
bytes aligned to align
.
The handle_ptr
will be NULL
if this is the first time launch has been called in
the function or is the first launch call after an explicit sync
statement. Both
situations should be treated equivalently as creating a new exeuction context for tasks.
The handle_ptr
should be set to some context tracking facility so that you can later
track task groups launched in the context and perform finer grained synchronization in
sync
.
§Safety
This function is unsafe as it is called directly from ISPC and must work with the raw pointers passed from ISPC to perform the allocation. Your implementation of the allocation operations can be safe internally depending on how you choose to implement it.
Sourceunsafe fn launch(
&self,
handle_ptr: *mut *mut c_void,
f: extern "C" fn(*mut c_void, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32),
data: *mut c_void,
count0: i32,
count1: i32,
count2: i32,
)
unsafe fn launch( &self, handle_ptr: *mut *mut c_void, f: extern "C" fn(*mut c_void, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32), data: *mut c_void, count0: i32, count1: i32, count2: i32, )
Launch is called when a new group of tasks is being launched and should schedule them to be executed in some way.
The handle_ptr
will point to the same handle you set up in alloc
and can be used to
associate groups of tasks with a context of execution as mentioned before. The function f
should be executed count0 * count1 * count2
times and indices passed to the function
should be as if running in a nested for loop, though no serial ordering is actually
required. The data
pointer points to the ISPC task specific parameter pointer and
should be passed through to the function.
For example, a serial task launcher could just run the tasks in a nested loop:
let total_tasks = count0 * count1 * count2;
for z in 0..count2 {
for y in 0..count1 {
for x in 0..count0 {
let task_id = x + y * count0 + z * count0 * count1;
f(data, thread_id, total_threads, task_id, total_tasks,
x, y, z, count0, count1, count2);
}
}
}
§Safety
This function is unsafe as it is called directly from ISPC and must operate on the raw pointers passed by ISPC.
Sourceunsafe fn sync(&self, handle: *mut c_void)
unsafe fn sync(&self, handle: *mut c_void)
Synchronize an execution context with the tasks it’s launched. Use handle
to determine
the task context that’s being synchronized.
This function should not return until all tasks launched within the context being
synchronized with have been completed. You can use the handle
to determine which context
is being synchronized with and thus which tasks must be completed before returning.
§Safety
This function is unsafe as it is called directly from ISPC and must operate on the raw pointers passed by ISPC.