Skip to content

Commit 00dcaaa

Browse files
committed
cl multi kernel
1 parent 02e6457 commit 00dcaaa

File tree

3 files changed

+69
-13
lines changed

3 files changed

+69
-13
lines changed

opencl/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
1. [clinfo](clinfo.c)
1212
1. [Preprocessor](matmul.c)
1313
1. [Write buffer](write_buffer.c)
14+
1. [Multi-kernel](multi_kernel.c)
1415
1. [Benchmark examples](benchmark-examples.md)
1516
1. [Matrix multiplication](matmul.c)
1617
1. Tools

opencl/common.h

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,26 +42,35 @@ char* common_read_file(const char *path) {
4242
return buffer;
4343
}
4444

45-
void common_create_kernel(
45+
void common_create_program(
4646
Common *common,
4747
const char *source,
48-
const char *options
48+
const char *options,
49+
cl_program *program
4950
) {
50-
cl_int ret;
5151
char *err;
52+
cl_int ret;
5253
size_t err_len;
5354

55+
*program = clCreateProgramWithSource(common->context, 1, &source, NULL, NULL);
56+
ret = clBuildProgram(*program, 1, &(common->device), options, NULL, NULL);
57+
if (CL_SUCCESS != ret) {
58+
clGetProgramBuildInfo(*program, common->device, CL_PROGRAM_BUILD_LOG, 0, NULL, &err_len);
59+
err = malloc(err_len);
60+
clGetProgramBuildInfo(*program, common->device, CL_PROGRAM_BUILD_LOG, err_len, err, NULL);
61+
fprintf(stderr, "error: kernel build:\n%s\n", err);
62+
free(err);
63+
exit(EXIT_FAILURE);
64+
}
65+
}
66+
67+
void common_create_kernel(
68+
Common *common,
69+
const char *source,
70+
const char *options
71+
) {
5472
if (NULL != source) {
55-
common->program = clCreateProgramWithSource(common->context, 1, &source, NULL, NULL);
56-
ret = clBuildProgram(common->program, 1, &(common->device), options, NULL, NULL);
57-
if (CL_SUCCESS != ret) {
58-
clGetProgramBuildInfo(common->program, common->device, CL_PROGRAM_BUILD_LOG, 0, NULL, &err_len);
59-
err = malloc(err_len);
60-
clGetProgramBuildInfo(common->program, common->device, CL_PROGRAM_BUILD_LOG, err_len, err, NULL);
61-
fprintf(stderr, "error: kernel build:\n%s\n", err);
62-
free(err);
63-
exit(EXIT_FAILURE);
64-
}
73+
common_create_program(common, source, options, &common->program);
6574
common->kernel = clCreateKernel(common->program, "main", NULL);
6675
} else {
6776
common->kernel = NULL;

opencl/multi_kernel.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
We can pass data through multiple kernels with multiple
3+
clEnqueueNDRangeKernel calls on a single command queue.
4+
*/
5+
6+
#include "common.h"
7+
8+
int main(void) {
9+
const char *source =
10+
"__kernel void add(__global int *out) {\n"
11+
" out[get_global_id(0)]++;\n"
12+
"}\n"
13+
"__kernel void mul(__global int *out) {\n"
14+
" out[get_global_id(0)] *= 2;\n"
15+
"}\n"
16+
;
17+
cl_int input[] = {1, 2};
18+
cl_kernel kernel_add, kernel_mul;
19+
cl_mem buffer;
20+
cl_program program;
21+
Common common;
22+
const size_t global_work_size = sizeof(input) / sizeof(input[0]);
23+
24+
/* Run kernel. */
25+
common_init(&common, NULL);
26+
common_create_program(&common, source, NULL, &program);
27+
kernel_add = clCreateKernel(program, "add", NULL);
28+
kernel_mul = clCreateKernel(program, "mul", NULL);
29+
buffer = clCreateBuffer(common.context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, sizeof(input), input, NULL);
30+
clSetKernelArg(kernel_add, 0, sizeof(buffer), &buffer);
31+
clSetKernelArg(kernel_mul, 0, sizeof(buffer), &buffer);
32+
clEnqueueNDRangeKernel(common.command_queue, kernel_add, 1, NULL, &global_work_size, NULL, 0, NULL, NULL);
33+
clEnqueueNDRangeKernel(common.command_queue, kernel_mul, 1, NULL, &global_work_size, NULL, 0, NULL, NULL);
34+
clFlush(common.command_queue);
35+
clFinish(common.command_queue);
36+
clEnqueueReadBuffer(common.command_queue, buffer, CL_TRUE, 0, sizeof(input), input, 0, NULL, NULL);
37+
38+
/* Assertions. */
39+
assert(input[0] == 4);
40+
assert(input[1] == 6);
41+
42+
/* Cleanup. */
43+
clReleaseMemObject(buffer);
44+
common_deinit(&common);
45+
return EXIT_SUCCESS;
46+
}

0 commit comments

Comments
 (0)