1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <CL/cl.h>
5 #include "poclu.h"
6
7 #define MAX_PLATFORMS 32
8 #define MAX_DEVICES 32
9 #define MAX_BINARIES 32
10 char kernel[] = "__kernel void k() {\n return;\n}";
11
12 int
main(void)13 main(void){
14 cl_int err;
15 cl_platform_id platforms[MAX_PLATFORMS];
16 cl_uint nplatforms;
17 cl_device_id devices[MAX_DEVICES + 1]; // + 1 for duplicate test
18 cl_device_id device_id0;
19 cl_uint num_devices;
20 size_t i;
21 size_t num_binaries;
22 const unsigned char **binaries = NULL;
23 size_t *binary_sizes = NULL;
24 size_t num_bytes_copied;
25 cl_int binary_statuses[MAX_BINARIES];
26 cl_int binary_statuses2[MAX_BINARIES];
27 cl_program program = NULL;
28 cl_program program_with_binary = NULL;
29
30 err = clGetPlatformIDs(MAX_PLATFORMS, platforms, &nplatforms);
31 CHECK_OPENCL_ERROR_IN("clGetPlatformIDs");
32 if (!nplatforms)
33 return EXIT_FAILURE;
34
35 err = clGetDeviceIDs(platforms[0], CL_DEVICE_TYPE_ALL, MAX_DEVICES,
36 devices, &num_devices);
37 CHECK_OPENCL_ERROR_IN("clGetDeviceIDs");
38
39 cl_context context = clCreateContext(NULL, num_devices, devices, NULL, NULL, &err);
40 CHECK_OPENCL_ERROR_IN("clCreateContext");
41
42 size_t kernel_size = strlen(kernel);
43 char* kernel_buffer = kernel;
44
45 program = clCreateProgramWithSource(context, 1, (const char**)&kernel_buffer,
46 &kernel_size, &err);
47 CHECK_OPENCL_ERROR_IN("clCreateProgramWithSource");
48
49 err = clBuildProgram(program, num_devices, devices, NULL, NULL, NULL);
50 CHECK_OPENCL_ERROR_IN("clBuildProgram");
51
52 err = clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, 0, 0, &num_binaries);
53 CHECK_OPENCL_ERROR_IN("clGetProgramInfo");
54
55 num_binaries = num_binaries/sizeof(size_t);
56 binary_sizes = (size_t*)malloc(num_binaries * sizeof(size_t));
57 binaries = (const unsigned char**)calloc(num_binaries, sizeof(unsigned char*));
58
59 err = clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES,
60 num_binaries*sizeof(size_t), binary_sizes ,
61 &num_bytes_copied);
62 CHECK_OPENCL_ERROR_IN("clGetProgramInfo");
63
64 for (i = 0; i < num_binaries; ++i)
65 binaries[i] = (const unsigned char*) malloc(binary_sizes[i] *
66 sizeof(const unsigned char));
67
68 err = clGetProgramInfo(program, CL_PROGRAM_BINARIES,
69 num_binaries*sizeof(char*), binaries, &num_bytes_copied);
70 CHECK_OPENCL_ERROR_IN("clGetProgramInfo");
71
72 cl_uint num = num_binaries < num_devices ? num_binaries : num_devices;
73 if (num == 0)
74 {
75 err = !CL_SUCCESS;
76 goto FREE_AND_EXIT;
77 }
78
79 program_with_binary = clCreateProgramWithBinary(context, num, devices, binary_sizes,
80 binaries, binary_statuses, &err);
81 CHECK_OPENCL_ERROR_IN("clCreateProgramWithBinary");
82
83 for (i = 0; i < num; ++i) {
84 cl_program_binary_type bin_type = 0;
85 err = clGetProgramBuildInfo(program_with_binary, devices[i],
86 CL_PROGRAM_BINARY_TYPE,
87 sizeof(bin_type), (void *)&bin_type,
88 NULL);
89 CHECK_OPENCL_ERROR_IN("get program binary type");
90
91 /* cl_program_binary_type */
92 switch(bin_type) {
93 case CL_PROGRAM_BINARY_TYPE_NONE: /*0x0*/
94 fprintf(stderr, "program binary type: CL_PROGRAM_BINARY_TYPE_NONE\n");
95 break;
96 case CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT: /*0x1*/
97 fprintf(stderr, "program binary type: CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT\n");
98 break;
99 case CL_PROGRAM_BINARY_TYPE_LIBRARY: /*0x2*/
100 fprintf(stderr, "program binary type: CL_PROGRAM_BINARY_TYPE_LIBRARY\n");
101 break;
102 case CL_PROGRAM_BINARY_TYPE_EXECUTABLE: /*0x4*/
103 fprintf(stderr, "program binary type: CL_PROGRAM_BINARY_TYPE_EXECUTABLE\n");
104 break;
105 }
106 }
107 err = clReleaseProgram(program_with_binary);
108 CHECK_OPENCL_ERROR_IN("clReleaseProgram");
109
110 for (i = 0; i < num; i++)
111 {
112 if (binary_statuses[i] != CL_SUCCESS)
113 {
114 err = !CL_SUCCESS;
115 goto FREE_AND_EXIT;
116 }
117 }
118
119 // negative test1: invalid device
120 device_id0 = devices[0];
121 devices[0] = NULL; // invalid device
122 program_with_binary = clCreateProgramWithBinary(context, num, devices, binary_sizes,
123 binaries, binary_statuses, &err);
124
125 if (err != CL_INVALID_DEVICE || program_with_binary != NULL)
126 {
127 err = !CL_SUCCESS;
128 goto FREE_AND_EXIT;
129 }
130 err = CL_SUCCESS;
131
132 devices[0] = device_id0;
133 for (i = 0; i < num_binaries; ++i) free((void*)binaries[i]);
134 free(binary_sizes);
135 free(binaries);
136
137 // negative test2: duplicate device
138 num_binaries = 2;
139 devices[1] = devices[0]; // duplicate
140
141 binary_sizes = (size_t*)malloc(num_binaries * sizeof(size_t));
142 binaries = (const unsigned char**)calloc(num_binaries, sizeof(unsigned char*));
143
144 err = clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, 1*sizeof(size_t),
145 binary_sizes , &num_bytes_copied);
146 CHECK_OPENCL_ERROR_IN("clGetProgramInfo");
147
148 binary_sizes[1] = binary_sizes[0];
149
150 binaries[0] = (const unsigned char*) malloc(binary_sizes[0] *
151 sizeof(const unsigned char));
152 binaries[1] = (const unsigned char*) malloc(binary_sizes[1] *
153 sizeof(const unsigned char));
154
155 err = clGetProgramInfo(program, CL_PROGRAM_BINARIES, 1 * sizeof(char*),
156 binaries, &num_bytes_copied);
157 CHECK_OPENCL_ERROR_IN("clGetProgramInfo");
158
159 memcpy((void*)binaries[1], (void*)binaries[0], binary_sizes[0]);
160 program_with_binary = clCreateProgramWithBinary(context, 2, devices, binary_sizes,
161 binaries, binary_statuses2, &err);
162 if (err != CL_INVALID_DEVICE || program_with_binary != NULL)
163 {
164 err = !CL_SUCCESS;
165 goto FREE_AND_EXIT;
166 }
167 err = CL_SUCCESS;
168
169 FREE_AND_EXIT:
170 // Free resources
171 for (i = 0; i < num_binaries; ++i)
172 if (binaries)
173 if(binaries[i])
174 free((void*)binaries[i]);
175
176 if (binary_sizes)
177 free(binary_sizes);
178 if (binaries)
179 free(binaries);
180 if (program)
181 CHECK_CL_ERROR (clReleaseProgram (program));
182 if (program_with_binary)
183 CHECK_CL_ERROR (clReleaseProgram (program_with_binary));
184 if (context)
185 CHECK_CL_ERROR (clReleaseContext (context));
186
187 CHECK_CL_ERROR (clUnloadCompiler ());
188
189 return err == CL_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
190 }
191