1 #include "b3LauncherCL.h"
3 bool gDebugLauncherCL = false;
5 b3LauncherCL::b3LauncherCL(cl_command_queue queue, cl_kernel kernel, const char* name)
6 : m_commandQueue(queue),
9 m_enableSerialization(false),
14 static int counter = 0;
15 printf("[%d] Prepare to launch OpenCL kernel %s\n", counter++, name);
18 m_serializationSizeInBytes = sizeof(int);
21 b3LauncherCL::~b3LauncherCL()
23 for (int i = 0; i < m_arrays.size(); i++)
31 static int counter = 0;
32 printf("[%d] Finished launching OpenCL kernel %s\n", counter++, m_name);
36 void b3LauncherCL::setBuffer(cl_mem clBuffer)
38 if (m_enableSerialization)
40 b3KernelArgData kernelArg;
41 kernelArg.m_argIndex = m_idx;
42 kernelArg.m_isBuffer = 1;
43 kernelArg.m_clBuffer = clBuffer;
45 cl_mem_info param_name = CL_MEM_SIZE;
47 size_t sizeInBytes = sizeof(size_t);
48 size_t actualSizeInBytes;
50 err = clGetMemObjectInfo(kernelArg.m_clBuffer,
56 b3Assert(err == CL_SUCCESS);
57 kernelArg.m_argSizeInBytes = param_value;
59 m_kernelArguments.push_back(kernelArg);
60 m_serializationSizeInBytes += sizeof(b3KernelArgData);
61 m_serializationSizeInBytes += param_value;
63 cl_int status = clSetKernelArg(m_kernel, m_idx++, sizeof(cl_mem), &clBuffer);
64 b3Assert(status == CL_SUCCESS);
67 void b3LauncherCL::setBuffers(b3BufferInfoCL* buffInfo, int n)
69 for (int i = 0; i < n; i++)
71 if (m_enableSerialization)
73 b3KernelArgData kernelArg;
74 kernelArg.m_argIndex = m_idx;
75 kernelArg.m_isBuffer = 1;
76 kernelArg.m_clBuffer = buffInfo[i].m_clBuffer;
78 cl_mem_info param_name = CL_MEM_SIZE;
80 size_t sizeInBytes = sizeof(size_t);
81 size_t actualSizeInBytes;
83 err = clGetMemObjectInfo(kernelArg.m_clBuffer,
89 b3Assert(err == CL_SUCCESS);
90 kernelArg.m_argSizeInBytes = param_value;
92 m_kernelArguments.push_back(kernelArg);
93 m_serializationSizeInBytes += sizeof(b3KernelArgData);
94 m_serializationSizeInBytes += param_value;
96 cl_int status = clSetKernelArg(m_kernel, m_idx++, sizeof(cl_mem), &buffInfo[i].m_clBuffer);
97 b3Assert(status == CL_SUCCESS);
101 struct b3KernelArgDataUnaligned
105 int m_argSizeInBytes;
109 unsigned char m_argData[B3_CL_MAX_ARG_SIZE];
114 int b3LauncherCL::deserializeArgs(unsigned char* buf, int bufSize, cl_context ctx)
118 int numArguments = *(int*)&buf[index];
119 index += sizeof(int);
121 for (int i = 0; i < numArguments; i++)
123 b3KernelArgDataUnaligned* arg = (b3KernelArgDataUnaligned*)&buf[index];
125 index += sizeof(b3KernelArgData);
128 b3OpenCLArray<unsigned char>* clData = new b3OpenCLArray<unsigned char>(ctx, m_commandQueue, arg->m_argSizeInBytes);
129 clData->resize(arg->m_argSizeInBytes);
131 clData->copyFromHostPointer(&buf[index], arg->m_argSizeInBytes);
133 arg->m_clBuffer = clData->getBufferCL();
135 m_arrays.push_back(clData);
137 cl_int status = clSetKernelArg(m_kernel, m_idx++, sizeof(cl_mem), &arg->m_clBuffer);
138 b3Assert(status == CL_SUCCESS);
139 index += arg->m_argSizeInBytes;
143 cl_int status = clSetKernelArg(m_kernel, m_idx++, arg->m_argSizeInBytes, &arg->m_argData);
144 b3Assert(status == CL_SUCCESS);
147 memcpy(&b, arg, sizeof(b3KernelArgDataUnaligned));
148 m_kernelArguments.push_back(b);
150 m_serializationSizeInBytes = index;
154 int b3LauncherCL::validateResults(unsigned char* goldBuffer, int goldBufferCapacity, cl_context ctx)
158 int numArguments = *(int*)&goldBuffer[index];
159 index += sizeof(int);
161 if (numArguments != m_kernelArguments.size())
163 printf("failed validation: expected %d arguments, found %d\n", numArguments, m_kernelArguments.size());
167 for (int ii = 0; ii < numArguments; ii++)
169 b3KernelArgData* argGold = (b3KernelArgData*)&goldBuffer[index];
171 if (m_kernelArguments[ii].m_argSizeInBytes != argGold->m_argSizeInBytes)
173 printf("failed validation: argument %d sizeInBytes expected: %d, found %d\n", ii, argGold->m_argSizeInBytes, m_kernelArguments[ii].m_argSizeInBytes);
178 int expected = argGold->m_isBuffer;
179 int found = m_kernelArguments[ii].m_isBuffer;
181 if (expected != found)
183 printf("failed validation: argument %d isBuffer expected: %d, found %d\n", ii, expected, found);
187 index += sizeof(b3KernelArgData);
189 if (argGold->m_isBuffer)
191 unsigned char* memBuf = (unsigned char*)malloc(m_kernelArguments[ii].m_argSizeInBytes);
192 unsigned char* goldBuf = &goldBuffer[index];
193 for (int j = 0; j < m_kernelArguments[j].m_argSizeInBytes; j++)
199 status = clEnqueueReadBuffer(m_commandQueue, m_kernelArguments[ii].m_clBuffer, CL_TRUE, 0, m_kernelArguments[ii].m_argSizeInBytes,
201 b3Assert(status == CL_SUCCESS);
202 clFinish(m_commandQueue);
204 for (int b = 0; b < m_kernelArguments[ii].m_argSizeInBytes; b++)
206 int expected = goldBuf[b];
207 int found = memBuf[b];
208 if (expected != found)
210 printf("failed validation: argument %d OpenCL data at byte position %d expected: %d, found %d\n",
211 ii, b, expected, found);
216 index += argGold->m_argSizeInBytes;
221 for (int b = 0; b < m_kernelArguments[ii].m_argSizeInBytes; b++)
223 int expected = argGold->m_argData[b];
224 int found = m_kernelArguments[ii].m_argData[b];
225 if (expected != found)
227 printf("failed validation: argument %d const data at byte position %d expected: %d, found %d\n",
228 ii, b, expected, found);
237 int b3LauncherCL::serializeArguments(unsigned char* destBuffer, int destBufferCapacity)
239 //initialize to known values
240 for (int i = 0; i < destBufferCapacity; i++)
241 destBuffer[i] = 0xec;
243 assert(destBufferCapacity >= m_serializationSizeInBytes);
245 //todo: use the b3Serializer for this to allow for 32/64bit, endianness etc
246 int numArguments = m_kernelArguments.size();
247 int curBufferSize = 0;
248 int* dest = (int*)&destBuffer[curBufferSize];
249 *dest = numArguments;
250 curBufferSize += sizeof(int);
252 for (int i = 0; i < this->m_kernelArguments.size(); i++)
254 b3KernelArgData* arg = (b3KernelArgData*)&destBuffer[curBufferSize];
255 *arg = m_kernelArguments[i];
256 curBufferSize += sizeof(b3KernelArgData);
257 if (arg->m_isBuffer == 1)
259 //copy the OpenCL buffer content
261 status = clEnqueueReadBuffer(m_commandQueue, arg->m_clBuffer, 0, 0, arg->m_argSizeInBytes,
262 &destBuffer[curBufferSize], 0, 0, 0);
263 b3Assert(status == CL_SUCCESS);
264 clFinish(m_commandQueue);
265 curBufferSize += arg->m_argSizeInBytes;
268 return curBufferSize;
271 void b3LauncherCL::serializeToFile(const char* fileName, int numWorkItems)
273 int num = numWorkItems;
274 int buffSize = getSerializationBufferSize();
275 unsigned char* buf = new unsigned char[buffSize + sizeof(int)];
276 for (int i = 0; i < buffSize + 1; i++)
278 unsigned char* ptr = (unsigned char*)&buf[i];
281 // int actualWrite = serializeArguments(buf,buffSize);
283 // unsigned char* cptr = (unsigned char*)&buf[buffSize];
284 // printf("buf[buffSize] = %d\n",*cptr);
286 assert(buf[buffSize] == 0xff); //check for buffer overrun
287 int* ptr = (int*)&buf[buffSize];
291 FILE* f = fopen(fileName, "wb");
292 fwrite(buf, buffSize + sizeof(int), 1, f);