[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-physics / third-party / bullet3 / src / Bullet3OpenCL / ParallelPrimitives / b3LauncherCL.cpp
1 #include "b3LauncherCL.h"
2
3 bool gDebugLauncherCL = false;
4
5 b3LauncherCL::b3LauncherCL(cl_command_queue queue, cl_kernel kernel, const char* name)
6         : m_commandQueue(queue),
7           m_kernel(kernel),
8           m_idx(0),
9           m_enableSerialization(false),
10           m_name(name)
11 {
12         if (gDebugLauncherCL)
13         {
14                 static int counter = 0;
15                 printf("[%d] Prepare to launch OpenCL kernel %s\n", counter++, name);
16         }
17
18         m_serializationSizeInBytes = sizeof(int);
19 }
20
21 b3LauncherCL::~b3LauncherCL()
22 {
23         for (int i = 0; i < m_arrays.size(); i++)
24         {
25                 delete (m_arrays[i]);
26         }
27
28         m_arrays.clear();
29         if (gDebugLauncherCL)
30         {
31                 static int counter = 0;
32                 printf("[%d] Finished launching OpenCL kernel %s\n", counter++, m_name);
33         }
34 }
35
36 void b3LauncherCL::setBuffer(cl_mem clBuffer)
37 {
38         if (m_enableSerialization)
39         {
40                 b3KernelArgData kernelArg;
41                 kernelArg.m_argIndex = m_idx;
42                 kernelArg.m_isBuffer = 1;
43                 kernelArg.m_clBuffer = clBuffer;
44
45                 cl_mem_info param_name = CL_MEM_SIZE;
46                 size_t param_value;
47                 size_t sizeInBytes = sizeof(size_t);
48                 size_t actualSizeInBytes;
49                 cl_int err;
50                 err = clGetMemObjectInfo(kernelArg.m_clBuffer,
51                                                                  param_name,
52                                                                  sizeInBytes,
53                                                                  &param_value,
54                                                                  &actualSizeInBytes);
55
56                 b3Assert(err == CL_SUCCESS);
57                 kernelArg.m_argSizeInBytes = param_value;
58
59                 m_kernelArguments.push_back(kernelArg);
60                 m_serializationSizeInBytes += sizeof(b3KernelArgData);
61                 m_serializationSizeInBytes += param_value;
62         }
63         cl_int status = clSetKernelArg(m_kernel, m_idx++, sizeof(cl_mem), &clBuffer);
64         b3Assert(status == CL_SUCCESS);
65 }
66
67 void b3LauncherCL::setBuffers(b3BufferInfoCL* buffInfo, int n)
68 {
69         for (int i = 0; i < n; i++)
70         {
71                 if (m_enableSerialization)
72                 {
73                         b3KernelArgData kernelArg;
74                         kernelArg.m_argIndex = m_idx;
75                         kernelArg.m_isBuffer = 1;
76                         kernelArg.m_clBuffer = buffInfo[i].m_clBuffer;
77
78                         cl_mem_info param_name = CL_MEM_SIZE;
79                         size_t param_value;
80                         size_t sizeInBytes = sizeof(size_t);
81                         size_t actualSizeInBytes;
82                         cl_int err;
83                         err = clGetMemObjectInfo(kernelArg.m_clBuffer,
84                                                                          param_name,
85                                                                          sizeInBytes,
86                                                                          &param_value,
87                                                                          &actualSizeInBytes);
88
89                         b3Assert(err == CL_SUCCESS);
90                         kernelArg.m_argSizeInBytes = param_value;
91
92                         m_kernelArguments.push_back(kernelArg);
93                         m_serializationSizeInBytes += sizeof(b3KernelArgData);
94                         m_serializationSizeInBytes += param_value;
95                 }
96                 cl_int status = clSetKernelArg(m_kernel, m_idx++, sizeof(cl_mem), &buffInfo[i].m_clBuffer);
97                 b3Assert(status == CL_SUCCESS);
98         }
99 }
100
101 struct b3KernelArgDataUnaligned
102 {
103         int m_isBuffer;
104         int m_argIndex;
105         int m_argSizeInBytes;
106         int m_unusedPadding;
107         union {
108                 cl_mem m_clBuffer;
109                 unsigned char m_argData[B3_CL_MAX_ARG_SIZE];
110         };
111 };
112 #include <string.h>
113
114 int b3LauncherCL::deserializeArgs(unsigned char* buf, int bufSize, cl_context ctx)
115 {
116         int index = 0;
117
118         int numArguments = *(int*)&buf[index];
119         index += sizeof(int);
120
121         for (int i = 0; i < numArguments; i++)
122         {
123                 b3KernelArgDataUnaligned* arg = (b3KernelArgDataUnaligned*)&buf[index];
124
125                 index += sizeof(b3KernelArgData);
126                 if (arg->m_isBuffer)
127                 {
128                         b3OpenCLArray<unsigned char>* clData = new b3OpenCLArray<unsigned char>(ctx, m_commandQueue, arg->m_argSizeInBytes);
129                         clData->resize(arg->m_argSizeInBytes);
130
131                         clData->copyFromHostPointer(&buf[index], arg->m_argSizeInBytes);
132
133                         arg->m_clBuffer = clData->getBufferCL();
134
135                         m_arrays.push_back(clData);
136
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;
140                 }
141                 else
142                 {
143                         cl_int status = clSetKernelArg(m_kernel, m_idx++, arg->m_argSizeInBytes, &arg->m_argData);
144                         b3Assert(status == CL_SUCCESS);
145                 }
146                 b3KernelArgData b;
147                 memcpy(&b, arg, sizeof(b3KernelArgDataUnaligned));
148                 m_kernelArguments.push_back(b);
149         }
150         m_serializationSizeInBytes = index;
151         return index;
152 }
153
154 int b3LauncherCL::validateResults(unsigned char* goldBuffer, int goldBufferCapacity, cl_context ctx)
155 {
156         int index = 0;
157
158         int numArguments = *(int*)&goldBuffer[index];
159         index += sizeof(int);
160
161         if (numArguments != m_kernelArguments.size())
162         {
163                 printf("failed validation: expected %d arguments, found %d\n", numArguments, m_kernelArguments.size());
164                 return -1;
165         }
166
167         for (int ii = 0; ii < numArguments; ii++)
168         {
169                 b3KernelArgData* argGold = (b3KernelArgData*)&goldBuffer[index];
170
171                 if (m_kernelArguments[ii].m_argSizeInBytes != argGold->m_argSizeInBytes)
172                 {
173                         printf("failed validation: argument %d sizeInBytes expected: %d, found %d\n", ii, argGold->m_argSizeInBytes, m_kernelArguments[ii].m_argSizeInBytes);
174                         return -2;
175                 }
176
177                 {
178                         int expected = argGold->m_isBuffer;
179                         int found = m_kernelArguments[ii].m_isBuffer;
180
181                         if (expected != found)
182                         {
183                                 printf("failed validation: argument %d isBuffer expected: %d, found %d\n", ii, expected, found);
184                                 return -3;
185                         }
186                 }
187                 index += sizeof(b3KernelArgData);
188
189                 if (argGold->m_isBuffer)
190                 {
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++)
194                         {
195                                 memBuf[j] = 0xaa;
196                         }
197
198                         cl_int status = 0;
199                         status = clEnqueueReadBuffer(m_commandQueue, m_kernelArguments[ii].m_clBuffer, CL_TRUE, 0, m_kernelArguments[ii].m_argSizeInBytes,
200                                                                                  memBuf, 0, 0, 0);
201                         b3Assert(status == CL_SUCCESS);
202                         clFinish(m_commandQueue);
203
204                         for (int b = 0; b < m_kernelArguments[ii].m_argSizeInBytes; b++)
205                         {
206                                 int expected = goldBuf[b];
207                                 int found = memBuf[b];
208                                 if (expected != found)
209                                 {
210                                         printf("failed validation: argument %d OpenCL data at byte position %d expected: %d, found %d\n",
211                                                    ii, b, expected, found);
212                                         return -4;
213                                 }
214                         }
215
216                         index += argGold->m_argSizeInBytes;
217                 }
218                 else
219                 {
220                         //compare content
221                         for (int b = 0; b < m_kernelArguments[ii].m_argSizeInBytes; b++)
222                         {
223                                 int expected = argGold->m_argData[b];
224                                 int found = m_kernelArguments[ii].m_argData[b];
225                                 if (expected != found)
226                                 {
227                                         printf("failed validation: argument %d const data at byte position %d expected: %d, found %d\n",
228                                                    ii, b, expected, found);
229                                         return -5;
230                                 }
231                         }
232                 }
233         }
234         return index;
235 }
236
237 int b3LauncherCL::serializeArguments(unsigned char* destBuffer, int destBufferCapacity)
238 {
239         //initialize to known values
240         for (int i = 0; i < destBufferCapacity; i++)
241                 destBuffer[i] = 0xec;
242
243         assert(destBufferCapacity >= m_serializationSizeInBytes);
244
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);
251
252         for (int i = 0; i < this->m_kernelArguments.size(); i++)
253         {
254                 b3KernelArgData* arg = (b3KernelArgData*)&destBuffer[curBufferSize];
255                 *arg = m_kernelArguments[i];
256                 curBufferSize += sizeof(b3KernelArgData);
257                 if (arg->m_isBuffer == 1)
258                 {
259                         //copy the OpenCL buffer content
260                         cl_int status = 0;
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;
266                 }
267         }
268         return curBufferSize;
269 }
270
271 void b3LauncherCL::serializeToFile(const char* fileName, int numWorkItems)
272 {
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++)
277         {
278                 unsigned char* ptr = (unsigned char*)&buf[i];
279                 *ptr = 0xff;
280         }
281         //      int actualWrite = serializeArguments(buf,buffSize);
282
283         //      unsigned char* cptr = (unsigned char*)&buf[buffSize];
284         //            printf("buf[buffSize] = %d\n",*cptr);
285
286         assert(buf[buffSize] == 0xff);  //check for buffer overrun
287         int* ptr = (int*)&buf[buffSize];
288
289         *ptr = num;
290
291         FILE* f = fopen(fileName, "wb");
292         fwrite(buf, buffSize + sizeof(int), 1, f);
293         fclose(f);
294
295         delete[] buf;
296 }