@@ -107,7 +107,7 @@ CLWProgram CLWProgram::CreateFromSource(char const* sourcecode,
107
107
CLWContext context)
108
108
{
109
109
cl_int status = CL_SUCCESS;
110
-
110
+
111
111
std::vector<cl_device_id> deviceIds (context.GetDeviceCount ());
112
112
for (unsigned int i = 0 ; i < context.GetDeviceCount (); ++i)
113
113
{
@@ -170,6 +170,61 @@ CLWProgram CLWProgram::CreateFromSource(char const* sourcecode,
170
170
return prg;
171
171
}
172
172
173
+ CLWProgram CLWProgram::CreateFromBinary (std::uint8_t ** binaries, std::size_t * binary_sizes, CLWContext context)
174
+ {
175
+ cl_int status = CL_SUCCESS;
176
+
177
+ std::vector<cl_device_id> deviceIds (context.GetDeviceCount ());
178
+ for (unsigned int i = 0 ; i < context.GetDeviceCount (); ++i)
179
+ {
180
+ deviceIds[i] = context.GetDevice (i);
181
+ }
182
+
183
+ cl_int binary_status = 0 ;
184
+ cl_program program = clCreateProgramWithBinary (context, context.GetDeviceCount (), &deviceIds[0 ], binary_sizes, (const unsigned char **)binaries, &binary_status, &status);
185
+
186
+ if (status != CL_SUCCESS)
187
+ {
188
+ std::vector<char > buildLog;
189
+ size_t logSize;
190
+ clGetProgramBuildInfo (program, deviceIds[0 ], CL_PROGRAM_BUILD_LOG, 0 , nullptr , &logSize);
191
+
192
+ buildLog.resize (logSize);
193
+ clGetProgramBuildInfo (program, deviceIds[0 ], CL_PROGRAM_BUILD_LOG, logSize, &buildLog[0 ], nullptr );
194
+
195
+ #ifdef _DEBUG
196
+ std::cout << &buildLog[0 ] << " \n " ;
197
+ #endif
198
+
199
+ throw CLWException (status, std::string (&buildLog[0 ]));
200
+ }
201
+
202
+ status = clBuildProgram (program, context.GetDeviceCount (), &deviceIds[0 ], nullptr , nullptr , nullptr );
203
+
204
+ if (status != CL_SUCCESS)
205
+ {
206
+ std::vector<char > buildLog;
207
+ size_t logSize;
208
+ clGetProgramBuildInfo (program, deviceIds[0 ], CL_PROGRAM_BUILD_LOG, 0 , nullptr , &logSize);
209
+
210
+ buildLog.resize (logSize);
211
+ clGetProgramBuildInfo (program, deviceIds[0 ], CL_PROGRAM_BUILD_LOG, logSize, &buildLog[0 ], nullptr );
212
+
213
+ #ifdef _DEBUG
214
+ std::cout << &buildLog[0 ] << " \n " ;
215
+ #endif
216
+
217
+ throw CLWException (status, std::string (&buildLog[0 ]));
218
+ }
219
+
220
+ CLWProgram prg (program);
221
+
222
+ clReleaseProgram (program);
223
+
224
+ return prg;
225
+
226
+ }
227
+
173
228
CLWProgram CLWProgram::CreateFromFile (char const * filename, char const * buildopts, CLWContext context)
174
229
{
175
230
std::vector<char > sourcecode;
@@ -218,24 +273,24 @@ CLWProgram::CLWProgram(cl_program program)
218
273
ThrowIf (numKernels == 0 , CL_BUILD_ERROR, " clCreateKernelsInProgram return 0 kernels" );
219
274
220
275
ThrowIf (status != CL_SUCCESS, status, " clCreateKernelsInProgram failed" );
221
-
276
+
222
277
std::vector<cl_kernel> kernels (numKernels);
223
278
status = clCreateKernelsInProgram (*this , numKernels, &kernels[0 ], nullptr );
224
-
279
+
225
280
ThrowIf (status != CL_SUCCESS, status, " clCreateKernelsInProgram failed" );
226
-
281
+
227
282
std::for_each (kernels.begin (), kernels.end (), [this ](cl_kernel k)
228
283
{
229
284
size_t size = 0 ;
230
285
cl_int res;
231
-
286
+
232
287
res = clGetKernelInfo (k, CL_KERNEL_FUNCTION_NAME, 0 , nullptr , &size);
233
288
ThrowIf (res != CL_SUCCESS, res, " clGetKernelInfo failed" );
234
-
289
+
235
290
std::vector<char > temp (size);
236
291
res = clGetKernelInfo (k, CL_KERNEL_FUNCTION_NAME, size, &temp[0 ], nullptr );
237
292
ThrowIf (res != CL_SUCCESS, res, " clGetKernelInfo failed" );
238
-
293
+
239
294
std::string funcName (temp.begin (), temp.end ()-1 );
240
295
kernels_[funcName] = CLWKernel::Create (k);
241
296
});
@@ -258,3 +313,55 @@ CLWKernel CLWProgram::GetKernel(std::string const& funcName) const
258
313
259
314
return iter->second ;
260
315
}
316
+
317
+ void CLWProgram::GetBinaries (int device, std::vector<std::uint8_t >& data) const
318
+ {
319
+ std::uint32_t num_devices;
320
+ auto status = clGetProgramInfo (*this , CL_PROGRAM_NUM_DEVICES,
321
+ sizeof (uint32_t ),
322
+ &num_devices,
323
+ nullptr );
324
+
325
+
326
+ std::vector<std::size_t > binary_sizes (num_devices);
327
+ status = clGetProgramInfo (*this , CL_PROGRAM_BINARY_SIZES,
328
+ sizeof (size_t ) * num_devices,
329
+ &binary_sizes[0 ],
330
+ nullptr );
331
+
332
+ ThrowIf (status != CL_SUCCESS, status, " clGetProgramInfo failed" );
333
+
334
+ data.resize (binary_sizes[device]);
335
+
336
+ char ** temp = new char *[num_devices];
337
+
338
+ for (auto i = 0u ; i < num_devices; ++i)
339
+ {
340
+ if (i == device)
341
+ {
342
+ temp[i] = (char *)&data[0 ];
343
+ }
344
+ else
345
+ {
346
+ temp[i] = new char [binary_sizes[i]];
347
+ }
348
+ }
349
+
350
+ status = clGetProgramInfo (*this , CL_PROGRAM_BINARIES,
351
+ binary_sizes[0 ],
352
+ temp,
353
+ nullptr );
354
+
355
+ // TODO: fix potential leak here
356
+ ThrowIf (status != CL_SUCCESS, status, " clGetProgramInfo failed" );
357
+
358
+ for (auto i = 0u ; i < num_devices; ++i)
359
+ {
360
+ if (i != device)
361
+ {
362
+ delete temp[i];
363
+ }
364
+ }
365
+
366
+ delete temp;
367
+ }
0 commit comments