Skip to content

Commit a432446

Browse files
committed
Add support for kernel binaries
1 parent 41c391f commit a432446

File tree

3 files changed

+121
-9
lines changed

3 files changed

+121
-9
lines changed

CLW/CLWDevice.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ CLWDevice::CLWDevice(cl_device_id id) : ReferenceCounter<cl_device_id, clRetainD
3232
GetDeviceInfoParameter(*this, CL_DEVICE_NAME, name_);
3333
GetDeviceInfoParameter(*this, CL_DEVICE_EXTENSIONS, extensions_);
3434
GetDeviceInfoParameter(*this, CL_DEVICE_VENDOR, vendor_);
35-
GetDeviceInfoParameter(*this, CL_DEVICE_VERSION, version_);
35+
GetDeviceInfoParameter(*this, CL_DRIVER_VERSION, version_);
3636
GetDeviceInfoParameter(*this, CL_DEVICE_PROFILE, profile_);
3737
GetDeviceInfoParameter(*this, CL_DEVICE_TYPE, type_);
3838

CLW/CLWProgram.cpp

Lines changed: 114 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ CLWProgram CLWProgram::CreateFromSource(char const* sourcecode,
107107
CLWContext context)
108108
{
109109
cl_int status = CL_SUCCESS;
110-
110+
111111
std::vector<cl_device_id> deviceIds(context.GetDeviceCount());
112112
for(unsigned int i = 0; i < context.GetDeviceCount(); ++i)
113113
{
@@ -170,6 +170,61 @@ CLWProgram CLWProgram::CreateFromSource(char const* sourcecode,
170170
return prg;
171171
}
172172

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+
173228
CLWProgram CLWProgram::CreateFromFile(char const* filename, char const* buildopts, CLWContext context)
174229
{
175230
std::vector<char> sourcecode;
@@ -218,24 +273,24 @@ CLWProgram::CLWProgram(cl_program program)
218273
ThrowIf(numKernels == 0, CL_BUILD_ERROR, "clCreateKernelsInProgram return 0 kernels");
219274

220275
ThrowIf(status != CL_SUCCESS, status, "clCreateKernelsInProgram failed");
221-
276+
222277
std::vector<cl_kernel> kernels(numKernels);
223278
status = clCreateKernelsInProgram(*this, numKernels, &kernels[0], nullptr);
224-
279+
225280
ThrowIf(status != CL_SUCCESS, status, "clCreateKernelsInProgram failed");
226-
281+
227282
std::for_each(kernels.begin(), kernels.end(), [this](cl_kernel k)
228283
{
229284
size_t size = 0;
230285
cl_int res;
231-
286+
232287
res = clGetKernelInfo(k, CL_KERNEL_FUNCTION_NAME, 0, nullptr, &size);
233288
ThrowIf(res != CL_SUCCESS, res, "clGetKernelInfo failed");
234-
289+
235290
std::vector<char> temp(size);
236291
res = clGetKernelInfo(k, CL_KERNEL_FUNCTION_NAME, size, &temp[0], nullptr);
237292
ThrowIf(res != CL_SUCCESS, res, "clGetKernelInfo failed");
238-
293+
239294
std::string funcName(temp.begin(), temp.end()-1);
240295
kernels_[funcName] = CLWKernel::Create(k);
241296
});
@@ -258,3 +313,55 @@ CLWKernel CLWProgram::GetKernel(std::string const& funcName) const
258313

259314
return iter->second;
260315
}
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+
}

CLW/CLWProgram.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ THE SOFTWARE.
2727
#include <vector>
2828
#include <map>
2929
#include <string>
30+
#include <cstdint>
3031

3132
#ifdef __APPLE__
3233
#include <OpenCL/OpenCL.h>
@@ -62,12 +63,16 @@ class CLWProgram : public ReferenceCounter<cl_program, clRetainProgram, clReleas
6263
char const* buildopts,
6364
CLWContext context);
6465

66+
static CLWProgram CreateFromBinary(std::uint8_t** binaries, std::size_t* binary_sizes, CLWContext context);
67+
6568
CLWProgram() {}
6669
virtual ~CLWProgram();
6770

6871
unsigned int GetKernelCount() const;
6972
CLWKernel GetKernel(std::string const& funcName) const;
70-
73+
74+
void GetBinaries(int device, std::vector<std::uint8_t>& data) const;
75+
7176
private:
7277
CLWProgram(cl_program program);
7378
std::map<std::string, CLWKernel> kernels_;

0 commit comments

Comments
 (0)