ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/OpenCL/OpenCL.xs
Revision: 1.2
Committed: Tue Nov 15 09:24:40 2011 UTC (12 years, 6 months ago) by root
Branch: MAIN
Changes since 1.1: +282 -53 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4
5 #include <CL/opencl.h>
6
7 typedef cl_platform_id OpenCL__Platform;
8 typedef cl_device_id OpenCL__Device;
9 typedef cl_context OpenCL__Context;
10 typedef cl_command_queue OpenCL__Queue;
11 typedef cl_mem OpenCL__Memory;
12 typedef cl_sampler OpenCL__Sampler;
13 typedef cl_program OpenCL__Program;
14 typedef cl_kernel OpenCL__Kernel;
15 typedef cl_event OpenCL__Event;
16
17 static const struct {
18 IV iv;
19 const char *name;
20 } cl_error[] = {
21 #define def_error(name) { (IV)CL_ ## name, # name },
22 #include "invalid.h"
23 };
24
25 static const char *
26 clstrerror (cl_int res)
27 {
28 int i;
29 static char numbuf [32];
30
31 for (i = sizeof (cl_error) / sizeof (cl_error [0]); i--; )
32 if (cl_error [i].iv == res)
33 return cl_error [i].name;
34
35 snprintf (numbuf, sizeof (numbuf), "ERROR(%d)", res);
36
37 return numbuf;
38 }
39
40 #define FAIL(name,res) \
41 croak ("cl" # name ": %s", clstrerror (res));
42
43 #define NEED_SUCCESS(name,args) \
44 do { \
45 cl_int res = cl ## name args; \
46 \
47 if (res) \
48 FAIL (name, res); \
49 } while (0)
50
51 #define NEW_MORTAL_OBJ(class,ptr) sv_setref_pv (sv_newmortal (), class, ptr)
52 #define XPUSH_NEW_OBJ(class,ptr) XPUSHs (NEW_MORTAL_OBJ (class, ptr))
53
54 /*TODO*/
55 #define EVENT_LIST(items,count) cl_uint event_list_count = 0; cl_event *event_list_ptr = 0
56
57 #define INFO(class) \
58 { \
59 size_t size; \
60 SV *sv; \
61 \
62 NEED_SUCCESS (Get ## class ## Info, (this, name, 0, 0, &size)); \
63 sv = sv_2mortal (newSV (size)); \
64 SvUPGRADE (sv, SVt_PV); \
65 SvPOK_only (sv); \
66 SvCUR_set (sv, size); \
67 NEED_SUCCESS (Get ## class ## Info, (this, name, size, SvPVX (sv), 0)); \
68 XPUSHs (sv); \
69 }
70
71 MODULE = OpenCL PACKAGE = OpenCL
72
73 PROTOTYPES: ENABLE
74
75 BOOT:
76 {
77 HV *stash = gv_stashpv ("OpenCL", 1);
78 static const struct {
79 const char *name;
80 IV iv;
81 } *civ, const_iv[] = {
82 #define const_iv(name) { # name, (IV)CL_ ## name },
83 #include "constiv.h"
84 };
85 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
86 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
87 }
88
89 void
90 platforms ()
91 PPCODE:
92 {
93 cl_platform_id *list;
94 cl_uint count;
95 int i;
96
97 NEED_SUCCESS (GetPlatformIDs, (0, 0, &count));
98 Newx (list, count, cl_platform_id);
99 NEED_SUCCESS (GetPlatformIDs, (count, list, 0));
100
101 EXTEND (SP, count);
102 for (i = 0; i < count; ++i)
103 PUSHs (NEW_MORTAL_OBJ ("OpenCL::Platform", list [i]));
104
105 Safefree (list);
106 }
107
108 void
109 context_from_type_simple (cl_device_type type = CL_DEVICE_TYPE_DEFAULT)
110 PPCODE:
111 {
112 cl_int res;
113 cl_context ctx = clCreateContextFromType (0, type, 0, 0, &res);
114
115 if (res)
116 FAIL (CreateContextFromType, res);
117
118 XPUSH_NEW_OBJ ("OpenCL::Context", ctx);
119 }
120
121 void
122 wait_for_events (...)
123 CODE:
124 {
125 EVENT_LIST (0, items);
126 NEED_SUCCESS (WaitForEvents, (event_list_count, event_list_ptr));
127 }
128
129 PROTOTYPES: DISABLE
130
131 MODULE = OpenCL PACKAGE = OpenCL::Platform
132
133 void
134 info (OpenCL::Platform this, cl_platform_info name)
135 PPCODE:
136 INFO (Platform)
137
138 void
139 devices (OpenCL::Platform this, cl_device_type type = CL_DEVICE_TYPE_ALL)
140 PPCODE:
141 {
142 cl_device_id *list;
143 cl_uint count;
144 int i;
145
146 NEED_SUCCESS (GetDeviceIDs, (this, type, 0, 0, &count));
147 Newx (list, count, cl_device_id);
148 NEED_SUCCESS (GetDeviceIDs, (this, type, count, list, 0));
149
150 EXTEND (SP, count);
151 for (i = 0; i < count; ++i)
152 PUSHs (sv_setref_pv (sv_newmortal (), "OpenCL::Device", list [i]));
153
154 Safefree (list);
155 }
156
157 void
158 context_from_type_simple (OpenCL::Platform this, cl_device_type type = CL_DEVICE_TYPE_DEFAULT)
159 PPCODE:
160 {
161 cl_int res;
162 cl_context_properties props[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)this, 0 };
163 cl_context ctx = clCreateContextFromType (props, type, 0, 0, &res);
164
165 if (res)
166 FAIL (CreateContextFromType, res);
167
168 XPUSH_NEW_OBJ ("OpenCL::Context", ctx);
169 }
170
171 void
172 unload_compiler ()
173 CODE:
174 NEED_SUCCESS (UnloadCompiler, ());
175
176 MODULE = OpenCL PACKAGE = OpenCL::Device
177
178 void
179 info (OpenCL::Device this, cl_device_info name)
180 PPCODE:
181 INFO (Device)
182
183 void
184 context_simple (OpenCL::Device this)
185 PPCODE:
186 {
187 cl_int res;
188 cl_context ctx = clCreateContext (0, 1, &this, 0, 0, &res);
189
190 if (res)
191 FAIL (CreateContext, res);
192
193 XPUSH_NEW_OBJ ("OpenCL::Context", ctx);
194 }
195
196 MODULE = OpenCL PACKAGE = OpenCL::Context
197
198 void
199 DESTROY (OpenCL::Context context)
200 CODE:
201 clReleaseContext (context);
202
203 void
204 info (OpenCL::Context this, cl_context_info name)
205 PPCODE:
206 INFO (Context)
207
208 void
209 command_queue_simple (OpenCL::Context this, OpenCL::Device device)
210 PPCODE:
211 {
212 cl_int res;
213 cl_command_queue queue = clCreateCommandQueue (this, device, 0, &res);
214
215 if (res)
216 FAIL (CreateCommandQueue, res);
217
218 XPUSH_NEW_OBJ ("OpenCL::Queue", queue);
219 }
220
221 void
222 buffer (OpenCL::Context this, cl_mem_flags flags, size_t len)
223 PPCODE:
224 {
225 cl_int res;
226 cl_mem mem = clCreateBuffer (this, flags, len, 0, &res);
227
228 if (res)
229 FAIL (CreateBuffer, res);
230
231 XPUSH_NEW_OBJ ("OpenCL::Memory", mem);
232 }
233
234 void
235 buffer_sv (OpenCL::Context this, cl_mem_flags flags, SV *data)
236 PPCODE:
237 {
238 STRLEN len;
239 char *ptr = SvPVbyte (data, len);
240 cl_int res;
241 cl_mem mem = clCreateBuffer (this, flags, len, ptr, &res);
242
243 if (res)
244 FAIL (CreateBuffer, res);
245
246 XPUSH_NEW_OBJ ("OpenCL::Memory", mem);
247 }
248
249 void
250 sampler (OpenCL::Context this, cl_bool normalized_coords, cl_addressing_mode addressing_mode, cl_filter_mode filter_mode)
251 PPCODE:
252 {
253 cl_int res;
254 cl_sampler sampler = clCreateSampler (this, normalized_coords, addressing_mode, filter_mode, &res);
255
256 if (res)
257 FAIL (CreateSampler, res);
258
259 XPUSH_NEW_OBJ ("OpenCL::Sampler", sampler);
260 }
261
262 void
263 program_with_source (OpenCL::Context this, SV *program)
264 PPCODE:
265 {
266 STRLEN len;
267 size_t len2;
268 const char *ptr = SvPVbyte (program, len);
269 cl_int res;
270 cl_program prog;
271
272 len2 = len;
273 prog = clCreateProgramWithSource (this, 1, &ptr, &len2, &res);
274
275 if (res)
276 FAIL (CreateProgramWithSource, res);
277
278 XPUSH_NEW_OBJ ("OpenCL::Program", prog);
279 }
280
281 MODULE = OpenCL PACKAGE = OpenCL::Queue
282
283 void
284 DESTROY (OpenCL::Queue this)
285 CODE:
286 clReleaseCommandQueue (this);
287
288 void
289 info (OpenCL::Queue this, cl_command_queue_info name)
290 PPCODE:
291 INFO (CommandQueue)
292
293 void
294 enqueue_read_buffer (OpenCL::Queue this, OpenCL::Memory mem, cl_bool blocking, size_t offset, size_t len, SV *data, ...)
295 PPCODE:
296 {
297 cl_event ev = 0;
298 EVENT_LIST (6, items - 6);
299
300 SvUPGRADE (data, SVt_PV);
301 SvGROW (data, len);
302 SvPOK_only (data);
303 SvCUR_set (data, len);
304 NEED_SUCCESS (EnqueueReadBuffer, (this, mem, blocking, offset, len, SvPVX (data), event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0));
305
306 if (ev)
307 XPUSH_NEW_OBJ ("OpenCL::Event", ev);
308 }
309
310 void
311 enqueue_write_buffer (OpenCL::Queue this, OpenCL::Memory mem, cl_bool blocking, size_t offset, SV *data, ...)
312 PPCODE:
313 {
314 cl_event ev = 0;
315 STRLEN len;
316 char *ptr = SvPVbyte (data, len);
317 EVENT_LIST (5, items - 5);
318
319 NEED_SUCCESS (EnqueueReadBuffer, (this, mem, blocking, offset, len, ptr, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0));
320
321 if (ev)
322 XPUSH_NEW_OBJ ("OpenCL::Event", ev);
323 }
324
325 void
326 enqueue_copy_buffer (OpenCL::Queue this, OpenCL::Memory src, OpenCL::Memory dst, size_t src_offset, size_t dst_offset, size_t len, ...)
327 PPCODE:
328 {
329 cl_event ev = 0;
330 EVENT_LIST (6, items - 6);
331
332 NEED_SUCCESS (EnqueueCopyBuffer, (this, src, dst, src_offset, dst_offset, len, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0));
333
334 if (ev)
335 XPUSH_NEW_OBJ ("OpenCL::Event", ev);
336 }
337
338 void
339 enqueue_marker (OpenCL::Queue this)
340 PPCODE:
341 {
342 cl_event ev;
343 NEED_SUCCESS (EnqueueMarker, (this, &ev));
344 XPUSH_NEW_OBJ ("OpenCL::Event", ev);
345 }
346
347 void
348 enqueue_wait_for_events (OpenCL::Queue this, ...)
349 CODE:
350 {
351 EVENT_LIST (1, items - 1);
352 NEED_SUCCESS (EnqueueWaitForEvents, (this, event_list_count, event_list_ptr));
353 }
354
355 void
356 enqueue_barrier (OpenCL::Queue this)
357 CODE:
358 NEED_SUCCESS (EnqueueBarrier, (this));
359
360 MODULE = OpenCL PACKAGE = OpenCL::Memory
361
362 void
363 DESTROY (OpenCL::Memory this)
364 CODE:
365 clReleaseMemObject (this);
366
367 void
368 info (OpenCL::Memory this, cl_mem_info name)
369 PPCODE:
370 INFO (MemObject)
371
372 MODULE = OpenCL PACKAGE = OpenCL::Sampler
373
374 void
375 DESTROY (OpenCL::Sampler this)
376 CODE:
377 clReleaseSampler (this);
378
379 void
380 info (OpenCL::Sampler this, cl_sampler_info name)
381 PPCODE:
382 INFO (Sampler)
383
384 MODULE = OpenCL PACKAGE = OpenCL::Program
385
386 void
387 DESTROY (OpenCL::Program this)
388 CODE:
389 clReleaseProgram (this);
390
391 void
392 info (OpenCL::Program this, cl_program_info name)
393 PPCODE:
394 INFO (Program)
395
396 void
397 build (OpenCL::Program this, OpenCL::Device device, SV *options = &PL_sv_undef)
398 CODE:
399 NEED_SUCCESS (BuildProgram, (this, 1, &device, SvPVbyte_nolen (options), 0, 0));
400
401 void
402 build_info (OpenCL::Program this, OpenCL::Device device, cl_program_build_info name)
403 PPCODE:
404 {
405 size_t size;
406 SV *sv;
407
408 NEED_SUCCESS (GetProgramBuildInfo, (this, device, name, 0, 0, &size));
409 sv = sv_2mortal (newSV (size));
410 SvUPGRADE (sv, SVt_PV);
411 SvPOK_only (sv);
412 SvCUR_set (sv, size);
413 NEED_SUCCESS (GetProgramBuildInfo, (this, device, name, size, SvPVX (sv), 0));
414 XPUSHs (sv);
415 }
416
417 void
418 kernel (OpenCL::Program program, SV *function)
419 PPCODE:
420 {
421 cl_int res;
422 cl_kernel kernel = clCreateKernel (program, SvPVbyte_nolen (function), &res);
423
424 if (res)
425 FAIL (CreateKernel, res);
426
427 XPUSH_NEW_OBJ ("OpenCL::Kernel", kernel);
428 }
429
430 MODULE = OpenCL PACKAGE = OpenCL::Kernel
431
432 void
433 DESTROY (OpenCL::Kernel this)
434 CODE:
435 clReleaseKernel (this);
436
437 void
438 info (OpenCL::Kernel this, cl_kernel_info name)
439 PPCODE:
440 INFO (Kernel)
441
442 void
443 set_bool (OpenCL::Kernel this, cl_uint idx, cl_bool value)
444 CODE:
445 clKernelSetArg (this, idx, sizeof (value), &value);
446
447 MODULE = OpenCL PACKAGE = OpenCL::Event
448
449 void
450 DESTROY (OpenCL::Event this)
451 CODE:
452 clReleaseEvent (this);
453
454 void
455 info (OpenCL::Event this, cl_event_info name)
456 PPCODE:
457 INFO (Event)
458
459 void
460 wait (OpenCL::Event this)
461 CODE:
462 clWaitForEvents (1, &this);
463