|
1 | | -/* |
| 1 | +/*Let's play with clCreateProgramWithBinary. |
| 2 | +
|
| 3 | +Compile the "inc.cl" CL C shader to binary, save the binary to a file, and load the shader from the binary: |
| 4 | +
|
| 5 | + ./prog |
| 6 | +
|
| 7 | +Ignore the CL C shader, load binary from a file, and run it: |
| 8 | +
|
| 9 | + ./prog 0 |
| 10 | +
|
| 11 | +Use another shader instead: |
| 12 | +
|
| 13 | + ./prog 1 dec.cl |
| 14 | +
|
| 15 | +The name "binary" is a possible lie: NVIDIA Linux driver 375.39 |
| 16 | +just dumps PTX human readable assembly, which we can modify without |
| 17 | +reverse engineering. Hurray! |
2 | 18 | */ |
3 | 19 |
|
| 20 | +#define BIN_PATH __FILE__ ".bin.tmp" |
| 21 | + |
4 | 22 | #include "common.h" |
5 | 23 |
|
6 | | -int main(void) { |
7 | | - const char *source = |
8 | | - "__kernel void kmain(__global int *out) {\n" |
9 | | - " out[get_global_id(0)]++;\n" |
10 | | - "}\n" |
11 | | - ; |
12 | | - cl_int input[] = {1, 2}; |
| 24 | +int main(int argc, char **argv) { |
| 25 | + Common common; |
| 26 | + FILE *f; |
| 27 | + char *binary, *source_path; |
| 28 | + cl_int input[] = {1, 2}, errcode_ret, binary_status; |
13 | 29 | cl_kernel kernel; |
14 | 30 | cl_mem buffer; |
15 | 31 | cl_program program; |
16 | | - Common common; |
17 | 32 | const size_t global_work_size = sizeof(input) / sizeof(input[0]); |
18 | | - |
19 | | - /* Run kernel. */ |
20 | | - common_init(&common, source); |
21 | | - |
22 | | - unsigned char *binary; |
| 33 | + int use_cache; |
| 34 | + long lenght; |
23 | 35 | size_t binary_size; |
24 | | - FILE *f; |
25 | 36 |
|
26 | | - clGetProgramInfo(common.program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &binary_size, NULL); |
27 | | - binary = malloc(binary_size); |
28 | | - clGetProgramInfo(common.program, CL_PROGRAM_BINARIES, binary_size, binary, NULL); |
| 37 | + if (argc > 1) { |
| 38 | + use_cache = !strcmp(argv[1], "0"); |
| 39 | + } else { |
| 40 | + use_cache = 0; |
| 41 | + } |
| 42 | + if (argc > 2) { |
| 43 | + source_path = argv[2]; |
| 44 | + } else { |
| 45 | + source_path = "inc.cl"; |
| 46 | + } |
29 | 47 |
|
30 | | - /* Not mandatory, but fun to reverse engineer their format later on. */ |
31 | | - f = fopen("a.bin.tmp", "w"); |
32 | | - fwrite(binary, binary_size, 1, f); |
33 | | - fclose(f); |
34 | | - |
35 | | - program = clCreateProgramWithBinary(common.context, 1, &common.device, &binary_size, (const unsigned char **)&binary, NULL, NULL); |
36 | | - kernel = clCreateKernel(program, "kmain", NULL); |
| 48 | + /* Get the binary, and create a kernel with it. */ |
| 49 | + if (use_cache) { |
| 50 | + common_init(&common, NULL); |
| 51 | + binary = common_read_file(BIN_PATH, &lenght); |
| 52 | + binary_size = lenght; |
| 53 | + } else { |
| 54 | + common_init_file(&common, source_path); |
| 55 | + clGetProgramInfo(common.program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &binary_size, NULL); |
| 56 | + binary = malloc(binary_size); |
| 57 | + clGetProgramInfo(common.program, CL_PROGRAM_BINARIES, binary_size, &binary, NULL); |
| 58 | + f = fopen(BIN_PATH, "w"); |
| 59 | + fwrite(binary, binary_size, 1, f); |
| 60 | + fclose(f); |
| 61 | + } |
| 62 | + program = clCreateProgramWithBinary( |
| 63 | + common.context, 1, &common.device, &binary_size, |
| 64 | + (const unsigned char **)&binary, &binary_status, &errcode_ret |
| 65 | + ); |
| 66 | + assert(NULL != program); |
| 67 | + common_assert_success(binary_status); |
| 68 | + common_assert_success(errcode_ret); |
37 | 69 | free(binary); |
| 70 | + common_build_program(&common, NULL, &program); |
| 71 | + kernel = clCreateKernel(program, "kmain", &errcode_ret); |
| 72 | + assert(NULL != kernel); |
| 73 | + common_assert_success(errcode_ret); |
38 | 74 |
|
39 | | - |
| 75 | + /* Run the kernel created from the binary. */ |
40 | 76 | buffer = clCreateBuffer(common.context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, sizeof(input), input, NULL); |
41 | 77 | clSetKernelArg(kernel, 0, sizeof(buffer), &buffer); |
42 | 78 | clEnqueueNDRangeKernel(common.command_queue, kernel, 1, NULL, &global_work_size, NULL, 0, NULL, NULL); |
|
0 commit comments