kupl::queue_submit(kernel)
Submit kernels to be executed to a queue. Compared with kupl::queue_submit(item), this interface submits kernels to a queue. A kernel refers to a parallel computing task submitted to a queue for execution. The primary distinction is found in the input parameters. This interface relies on C++ function overloading.
This interface requires the C++ compiler. Currently, the range supports only 1D.
Interface Definition
int kupl::queue_submit(kupl_queue_h queue, kupl_queue_kernel_desc_t *desc, const std::function<void(const kupl_nd_range_t *)> &kernel);
Parameters
Parameter |
Type |
Description |
Input/Output |
|---|---|---|---|
queue |
kupl_queue_h |
Queue for executing kernels |
Input |
desc |
kupl_queue_kernel_desc_t |
Kernel description |
Input |
kernel |
const std::function<void(const kupl_nd_range_t *)> |
Kernel content, which is usually a lambda expression. |
Input |
Parameter |
Type |
Description |
|---|---|---|
field_mask |
uint64_t |
(Mandatory) Mask of the kernel description, which is used to indicate which parameters are enabled. If there is no need to enable parameters, set the value to 0. Available option: KUPL_QUEUE_KERNEL_DESC_FIELD_NAME |
range |
kupl_nd_range_t * |
(Mandatory) Range information of the kernel. |
egroup |
kupl_egroup_h |
(Mandatory) Information about the executor available to the kernel. |
name |
const char * |
(Optional) Kernel name. |
Return Value
Success: KUPL_OK
Failure: KUPL_ERROR
Examples
#include <atomic>
#include <assert.h>
#include "kupl.h"
int main() {
auto queue = kupl_queue_create();
const int num_executors = 10;
kupl_nd_range_t range;
KUPL_1D_RANGE_INIT(range, 0, num_executors);
int exe[num_executors];
for (int i = 0; i < num_executors; i++) {
exe[i] = i;
}
kupl_egroup_h egroup = kupl_egroup_create(exe, num_executors);
kupl_queue_kernel_desc_t desc = {
.range = &range,
.egroup = egroup,
.field_mask = 0,
};
std::atomic<size_t> sum(0);
const size_t count = 1000000;
size_t sum_cal = (1 + count) * count / 2;
size_t *data = (size_t *)malloc(count * sizeof(count));
for (size_t i = 0; i < count; i++) {
data[i] = i + 1;
}
int ret = kupl::queue_submit(queue, &desc, [&](const kupl_nd_range_t *nd_range) {
int start_index = nd_range->nd_range[0].lower * (count / num_executors);
for (size_t i = 0; i < count / num_executors; i++) {
sum += data[start_index + i];
}
});
assert(ret == KUPL_OK);
kupl_queue_wait(queue);
assert(sum.load() == sum_cal);
printf("sum: %lu\n", sum.load());
kupl_egroup_destroy(egroup);
kupl_queue_destroy(queue);
}
The execution result is as follows:
sum: 500000500000
The preceding example demonstrates the process of submitting kernels to a queue, calculating the sum of an array with a length of 1000000 across 10 threads, waiting until all kernels in the queue are executed, comparing the result with the direct calculation result, and outputting the result.