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

# User Rev Content
1 root 1.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 root 1.2 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 root 1.1
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 root 1.2 croak ("cl" # name ": %s", clstrerror (res));
42 root 1.1
43     #define NEED_SUCCESS(name,args) \
44     do { \
45 root 1.2 cl_int res = cl ## name args; \
46 root 1.1 \
47     if (res) \
48     FAIL (name, res); \
49     } while (0)
50    
51 root 1.2 #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 root 1.1 MODULE = OpenCL PACKAGE = OpenCL
72    
73 root 1.2 PROTOTYPES: ENABLE
74    
75 root 1.1 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 root 1.2 NEED_SUCCESS (GetPlatformIDs, (0, 0, &count));
98 root 1.1 Newx (list, count, cl_platform_id);
99 root 1.2 NEED_SUCCESS (GetPlatformIDs, (count, list, 0));
100 root 1.1
101     EXTEND (SP, count);
102     for (i = 0; i < count; ++i)
103 root 1.2 PUSHs (NEW_MORTAL_OBJ ("OpenCL::Platform", list [i]));
104 root 1.1
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 root 1.2 FAIL (CreateContextFromType, res);
117 root 1.1
118 root 1.2 XPUSH_NEW_OBJ ("OpenCL::Context", ctx);
119 root 1.1 }
120    
121 root 1.2 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 root 1.1 MODULE = OpenCL PACKAGE = OpenCL::Platform
132    
133     void
134     info (OpenCL::Platform this, cl_platform_info name)
135     PPCODE:
136 root 1.2 INFO (Platform)
137 root 1.1
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 root 1.2 NEED_SUCCESS (GetDeviceIDs, (this, type, 0, 0, &count));
147 root 1.1 Newx (list, count, cl_device_id);
148 root 1.2 NEED_SUCCESS (GetDeviceIDs, (this, type, count, list, 0));
149 root 1.1
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 root 1.2 FAIL (CreateContextFromType, res);
167 root 1.1
168 root 1.2 XPUSH_NEW_OBJ ("OpenCL::Context", ctx);
169 root 1.1 }
170    
171 root 1.2 void
172     unload_compiler ()
173     CODE:
174     NEED_SUCCESS (UnloadCompiler, ());
175    
176 root 1.1 MODULE = OpenCL PACKAGE = OpenCL::Device
177    
178     void
179     info (OpenCL::Device this, cl_device_info name)
180     PPCODE:
181 root 1.2 INFO (Device)
182 root 1.1
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 root 1.2 FAIL (CreateContext, res);
192 root 1.1
193 root 1.2 XPUSH_NEW_OBJ ("OpenCL::Context", ctx);
194 root 1.1 }
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 root 1.2 INFO (Context)
207    
208     void
209     command_queue_simple (OpenCL::Context this, OpenCL::Device device)
210     PPCODE:
211 root 1.1 {
212 root 1.2 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 root 1.1
259 root 1.2 XPUSH_NEW_OBJ ("OpenCL::Sampler", sampler);
260 root 1.1 }
261    
262     void
263 root 1.2 program_with_source (OpenCL::Context this, SV *program)
264 root 1.1 PPCODE:
265     {
266 root 1.2 STRLEN len;
267     size_t len2;
268     const char *ptr = SvPVbyte (program, len);
269 root 1.1 cl_int res;
270 root 1.2 cl_program prog;
271    
272     len2 = len;
273     prog = clCreateProgramWithSource (this, 1, &ptr, &len2, &res);
274 root 1.1
275     if (res)
276 root 1.2 FAIL (CreateProgramWithSource, res);
277 root 1.1
278 root 1.2 XPUSH_NEW_OBJ ("OpenCL::Program", prog);
279 root 1.1 }
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 root 1.2 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 root 1.1 {
405     size_t size;
406     SV *sv;
407 root 1.2
408     NEED_SUCCESS (GetProgramBuildInfo, (this, device, name, 0, 0, &size));
409 root 1.1 sv = sv_2mortal (newSV (size));
410     SvUPGRADE (sv, SVt_PV);
411     SvPOK_only (sv);
412     SvCUR_set (sv, size);
413 root 1.2 NEED_SUCCESS (GetProgramBuildInfo, (this, device, name, size, SvPVX (sv), 0));
414 root 1.1 XPUSHs (sv);
415     }
416    
417 root 1.2 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