ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/OpenCL/OpenCL.xs
(Generate patch)

Comparing OpenCL/OpenCL.xs (file contents):
Revision 1.64 by root, Thu May 3 23:30:08 2012 UTC vs.
Revision 1.65 by root, Fri May 4 14:29:35 2012 UTC

40 #define PREFER_1_1 1 40 #define PREFER_1_1 1
41#endif 41#endif
42 42
43typedef cl_platform_id OpenCL__Platform; 43typedef cl_platform_id OpenCL__Platform;
44typedef cl_device_id OpenCL__Device; 44typedef cl_device_id OpenCL__Device;
45typedef cl_device_id OpenCL__SubDevice;
45typedef cl_context OpenCL__Context; 46typedef cl_context OpenCL__Context;
46typedef cl_command_queue OpenCL__Queue; 47typedef cl_command_queue OpenCL__Queue;
47typedef cl_mem OpenCL__Memory; 48typedef cl_mem OpenCL__Memory;
48typedef cl_mem OpenCL__Buffer; 49typedef cl_mem OpenCL__Buffer;
49typedef cl_mem OpenCL__BufferObj; 50typedef cl_mem OpenCL__BufferObj;
62typedef SV *FUTURE; 63typedef SV *FUTURE;
63 64
64static HV 65static HV
65 *stash_platform, 66 *stash_platform,
66 *stash_device, 67 *stash_device,
68 *stash_subdevice,
67 *stash_context, 69 *stash_context,
68 *stash_queue, 70 *stash_queue,
69 *stash_program, 71 *stash_program,
70 *stash_kernel, 72 *stash_kernel,
71 *stash_sampler, 73 *stash_sampler,
217 if (res) \ 219 if (res) \
218 FAIL (name); 220 FAIL (name);
219 221
220/*****************************************************************************/ 222/*****************************************************************************/
221 223
224static SV *
225new_clobj (HV *stash, IV id)
226{
227 return sv_2mortal (sv_bless (newRV_noinc (newSViv (id)), stash));
228}
229
230#define PUSH_CLOBJ(stash,id) PUSHs (new_clobj ((stash), (IV)(id)))
231#define XPUSH_CLOBJ(stash,id) XPUSHs (new_clobj ((stash), (IV)(id)))
232
233/* cl objects are either \$iv, or [$iv, ...] */
234/* they can be upgraded at runtime to the array form */
235static void * ecb_noinline
236SvCLOBJ (const char *func, const char *svname, SV *sv, const char *pkg)
237{
238 // sv_derived_from is quite slow :(
239 if (SvROK (sv) && sv_derived_from (sv, pkg))
240 return (void *)SvIV (SvRV (sv));
241
242 croak ("%s: %s is not of type %s", func, svname, pkg);
243}
244
245// the "no-inherit" version of the above
246static void * ecb_noinline
247SvCLOBJ_ni (const char *func, const char *svname, SV *sv, HV *stash)
248{
249 if (SvROK (sv) && SvSTASH (SvRV (sv)) == stash)
250 return (void *)SvIV (SvRV (sv));
251
252 croak ("%s: %s is not of type %s", func, svname, HvNAME (stash));
253}
254
255/*****************************************************************************/
256
222static cl_context_properties * ecb_noinline 257static cl_context_properties * ecb_noinline
223SvCONTEXTPROPERTIES (const char *func, const char *svname, SV *sv, cl_context_properties *extra, int extracount) 258SvCONTEXTPROPERTIES (const char *func, const char *svname, SV *sv, cl_context_properties *extra, int extracount)
224{ 259{
225 if (!sv || !SvOK (sv)) 260 if (!sv || !SvOK (sv))
226 if (extra) 261 if (extra)
234 int i, len = av_len (av) + 1; 269 int i, len = av_len (av) + 1;
235 cl_context_properties *p = tmpbuf (sizeof (cl_context_properties) * (len + extracount + 1)); 270 cl_context_properties *p = tmpbuf (sizeof (cl_context_properties) * (len + extracount + 1));
236 cl_context_properties *l = p; 271 cl_context_properties *l = p;
237 272
238 if (len & 1) 273 if (len & 1)
239 croak ("%s: %s is not a property list (must be even number of elements)", func, svname); 274 croak ("%s: %s is not a property list (must contain an even number of elements)", func, svname);
240 275
241 while (extracount--) 276 while (extracount--)
242 *l++ = *extra++; 277 *l++ = *extra++;
243 278
244 for (i = 0; i < len; i += 2) 279 for (i = 0; i < len; i += 2)
247 SV *p_sv = *av_fetch (av, i + 1, 0); 282 SV *p_sv = *av_fetch (av, i + 1, 0);
248 cl_context_properties v = SvIV (p_sv); // code below can override 283 cl_context_properties v = SvIV (p_sv); // code below can override
249 284
250 switch (t) 285 switch (t)
251 { 286 {
287 case CL_CONTEXT_PLATFORM:
288 if (SvROK (p_sv))
289 v = (cl_context_properties)SvCLOBJ (func, svname, p_sv, "OpenCL::Platform");
290 break;
291
252 case CL_GLX_DISPLAY_KHR: 292 case CL_GLX_DISPLAY_KHR:
253 if (!SvOK (p_sv)) 293 if (!SvOK (p_sv))
254 { 294 {
255 void *func = glsym ("_glXGetCurrentDisplay"); 295 void *func = glsym ("_glXGetCurrentDisplay");
256 if (func) 296 if (func)
280 320
281 return p; 321 return p;
282 } 322 }
283 323
284 croak ("%s: %s is not a property list (either undef or [type => value, ...])", func, svname); 324 croak ("%s: %s is not a property list (either undef or [type => value, ...])", func, svname);
285}
286
287/*****************************************************************************/
288
289static SV *
290new_clobj (HV *stash, IV id)
291{
292 return sv_2mortal (sv_bless (newRV_noinc (newSViv (id)), stash));
293}
294
295#define PUSH_CLOBJ(stash,id) PUSHs (new_clobj ((stash), (IV)(id)))
296#define XPUSH_CLOBJ(stash,id) XPUSHs (new_clobj ((stash), (IV)(id)))
297
298/* cl objects are either \$iv, or [$iv, ...] */
299/* they can be upgraded at runtime to the array form */
300static void * ecb_noinline
301SvCLOBJ (const char *func, const char *svname, SV *sv, const char *pkg)
302{
303 // sv_derived_from is quite slow :(
304 if (SvROK (sv) && sv_derived_from (sv, pkg))
305 return (void *)SvIV (SvRV (sv));
306
307 croak ("%s: %s is not of type %s", func, svname, pkg);
308}
309
310// the "no-inherit" version of the above
311static void * ecb_noinline
312SvCLOBJ_ni (const char *func, const char *svname, SV *sv, HV *stash)
313{
314 if (SvROK (sv) && SvSTASH (SvRV (sv)) == stash)
315 return (void *)SvIV (SvRV (sv));
316
317 croak ("%s: %s is not of type %s", func, svname, HvNAME (stash));
318} 325}
319 326
320/*****************************************************************************/ 327/*****************************************************************************/
321/* callback stuff */ 328/* callback stuff */
322 329
730 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--) 737 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
731 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv)); 738 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
732 739
733 stash_platform = gv_stashpv ("OpenCL::Platform", GV_ADD); 740 stash_platform = gv_stashpv ("OpenCL::Platform", GV_ADD);
734 stash_device = gv_stashpv ("OpenCL::Device", GV_ADD); 741 stash_device = gv_stashpv ("OpenCL::Device", GV_ADD);
742 stash_subdevice = gv_stashpv ("OpenCL::SubDevice", GV_ADD);
735 stash_context = gv_stashpv ("OpenCL::Context", GV_ADD); 743 stash_context = gv_stashpv ("OpenCL::Context", GV_ADD);
736 stash_queue = gv_stashpv ("OpenCL::Queue", GV_ADD); 744 stash_queue = gv_stashpv ("OpenCL::Queue", GV_ADD);
737 stash_program = gv_stashpv ("OpenCL::Program", GV_ADD); 745 stash_program = gv_stashpv ("OpenCL::Program", GV_ADD);
738 stash_kernel = gv_stashpv ("OpenCL::Kernel", GV_ADD); 746 stash_kernel = gv_stashpv ("OpenCL::Kernel", GV_ADD);
739 stash_sampler = gv_stashpv ("OpenCL::Sampler", GV_ADD); 747 stash_sampler = gv_stashpv ("OpenCL::Sampler", GV_ADD);
780 list = tmpbuf (sizeof (*list) * count); 788 list = tmpbuf (sizeof (*list) * count);
781 NEED_SUCCESS (GetPlatformIDs, (count, list, 0)); 789 NEED_SUCCESS (GetPlatformIDs, (count, list, 0));
782 790
783 EXTEND (SP, count); 791 EXTEND (SP, count);
784 for (i = 0; i < count; ++i) 792 for (i = 0; i < count; ++i)
785 PUSH_CLOBJ (stash_platform, (IV)list [i]); 793 PUSH_CLOBJ (stash_platform, list [i]);
786 794
787void 795void
788context_from_type (cl_context_properties *properties = 0, cl_device_type type = CL_DEVICE_TYPE_DEFAULT, SV *notify = &PL_sv_undef) 796context_from_type (cl_context_properties *properties = 0, cl_device_type type = CL_DEVICE_TYPE_DEFAULT, SV *notify = &PL_sv_undef)
789 PPCODE: 797 PPCODE:
790 CONTEXT_NOTIFY_CALLBACK; 798 CONTEXT_NOTIFY_CALLBACK;
889 897
890void 898void
891info (OpenCL::Device self, cl_device_info name) 899info (OpenCL::Device self, cl_device_info name)
892 PPCODE: 900 PPCODE:
893 INFO (Device) 901 INFO (Device)
902
903#if CL_VERSION_1_2
904
905void
906sub_devices (OpenCL::Device self, SV *properties)
907 PPCODE:
908 if (!SvROK (properties) || SvTYPE (SvRV (properties)) != SVt_PVAV)
909 croak ("OpenCL::Device::sub_devices: properties must be specified as reference to an array of property-value pairs");
910
911 properties = SvRV (properties);
912
913 cl_uint count = av_len ((AV *)properties) + 1;
914 cl_device_partition_property *props = tmpbuf (sizeof (*props) * count + 1);
915
916 int i;
917 for (i = 0; i < count; ++i)
918 props [i] = (cl_device_partition_property)SvIV (*av_fetch ((AV *)properties, i, 0));
919
920 props [count] = 0;
921
922 cl_uint num_devices;
923 NEED_SUCCESS (CreateSubDevices, (self, props, 0, 0, &num_devices));
924 cl_device_id *list = tmpbuf (sizeof (*list) * num_devices);
925 NEED_SUCCESS (CreateSubDevices, (self, props, num_devices, list, 0));
926
927 EXTEND (SP, num_devices);
928 for (i = 0; i < count; ++i)
929 PUSH_CLOBJ (stash_subdevice, list [i]);
930
931#endif
894 932
895#BEGIN:device 933#BEGIN:device
896 934
897void 935void
898type (OpenCL::Device self) 936type (OpenCL::Device self)
1114 for (i = 0; i < n; ++i) 1152 for (i = 0; i < n; ++i)
1115 PUSHs (sv_2mortal (newSVuv (value [i]))); 1153 PUSHs (sv_2mortal (newSVuv (value [i])));
1116 1154
1117#END:device 1155#END:device
1118 1156
1157MODULE = OpenCL PACKAGE = OpenCL::SubDevice
1158
1159#if CL_VERSION_1_2
1160
1161void
1162DESTROY (OpenCL::SubDevice self)
1163 CODE:
1164 clReleaseDevice (self);
1165
1166#endif
1167
1119MODULE = OpenCL PACKAGE = OpenCL::Context 1168MODULE = OpenCL PACKAGE = OpenCL::Context
1120 1169
1121void 1170void
1122DESTROY (OpenCL::Context context) 1171DESTROY (OpenCL::Context self)
1123 CODE: 1172 CODE:
1124 clReleaseContext (context); 1173 clReleaseContext (self);
1125 1174
1126void 1175void
1127info (OpenCL::Context self, cl_context_info name) 1176info (OpenCL::Context self, cl_context_info name)
1128 PPCODE: 1177 PPCODE:
1129 INFO (Context) 1178 INFO (Context)
1358 1407
1359 for (i = count; i--; ) 1408 for (i = count; i--; )
1360 av_store (av, i, newSViv (status_list [i])); 1409 av_store (av, i, newSViv (status_list [i]));
1361 } 1410 }
1362 1411
1412#if CL_VERSION_1_2
1413
1414void
1415program_with_built_in_kernels (OpenCL::Context self, SV *devices, SV *kernel_names)
1416 PPCODE:
1417 if (!SvROK (devices) || SvTYPE (SvRV (devices)) != SVt_PVAV)
1418 croak ("OpenCL::Context::program_with_built_in_kernels: devices must be specified as reference to an array of device objects");
1419
1420 devices = SvRV (devices);
1421
1422 int count = av_len ((AV *)devices) + 1;
1423 cl_device_id *device_list = tmpbuf (sizeof (*device_list) * count);
1424
1425 int i;
1426 for (i = 0; i < count; ++i)
1427 device_list [i] = SvCLOBJ ("OpenCL::Context::program_with_built_in_kernels", "devices", *av_fetch ((AV *)devices, i, 0), "OpenCL::Device");
1428
1429 NEED_SUCCESS_ARG (cl_program prog, CreateProgramWithBuiltInKernels, (self, count, device_list, SvPVbyte_nolen (kernel_names), &res));
1430
1431 XPUSH_CLOBJ (stash_program, prog);
1432
1433#endif
1434
1363#BEGIN:context 1435#BEGIN:context
1364 1436
1365void 1437void
1366reference_count (OpenCL::Context self) 1438reference_count (OpenCL::Context self)
1367 ALIAS: 1439 ALIAS:
1833 NEED_SUCCESS (EnqueueNDRangeKernel, (self, kernel, gws_len, gwo, gws, lws, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0)); 1905 NEED_SUCCESS (EnqueueNDRangeKernel, (self, kernel, gws_len, gwo, gws, lws, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0));
1834 1906
1835 if (ev) 1907 if (ev)
1836 XPUSH_CLOBJ (stash_event, ev); 1908 XPUSH_CLOBJ (stash_event, ev);
1837 1909
1910#if CL_VERSION_1_2
1911
1912void
1913migrate_mem_objects (OpenCL::Queue self, SV *objects, cl_mem_migration_flags flags, ...)
1914 ALIAS:
1915 enqueue_migrate_mem_objects = 0
1916 PPCODE:
1917 EVENT_LIST (3);
1918
1919 if (!SvROK (objects) || SvTYPE (SvRV (objects)) != SVt_PVAV)
1920 croak ("OpenCL::Queue::migrate_mem_objects: objects must be an array reference with OpenCL::Memory objects");
1921
1922 objects = SvRV (objects);
1923
1924 cl_uint object_count = av_len ((AV *)objects) + 1;
1925 cl_mem *object_list = tmpbuf (sizeof (*object_list) * object_count);
1926
1927 int i;
1928 for (i = object_count; i--; )
1929 object_list [i] = SvCLOBJ ("OpenCL::Queue::migrate_mem_objects", "objects", *av_fetch ((AV *)objects, i, 0), "OpenCL::Memory");
1930
1931 cl_event ev = 0;
1932 NEED_SUCCESS (EnqueueMigrateMemObjects, (self, object_count, object_list, flags, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0));
1933
1934 if (ev)
1935 XPUSH_CLOBJ (stash_event, ev);
1936
1937#endif
1938
1838#if cl_apple_gl_sharing || cl_khr_gl_sharing 1939#if cl_apple_gl_sharing || cl_khr_gl_sharing
1839 1940
1840void 1941void
1841acquire_gl_objects (OpenCL::Queue self, SV *objects, ...) 1942acquire_gl_objects (OpenCL::Queue self, SV *objects, ...)
1842 ALIAS: 1943 ALIAS:
1850 cl_event ev = 0; 1951 cl_event ev = 0;
1851 EVENT_LIST (2); 1952 EVENT_LIST (2);
1852 AV *av = (AV *)SvRV (objects); 1953 AV *av = (AV *)SvRV (objects);
1853 cl_uint num_objects = av_len (av) + 1; 1954 cl_uint num_objects = av_len (av) + 1;
1854 cl_mem *object_list = tmpbuf (sizeof (cl_mem) * num_objects); 1955 cl_mem *object_list = tmpbuf (sizeof (cl_mem) * num_objects);
1956
1855 int i; 1957 int i;
1856
1857 for (i = num_objects; i--; ) 1958 for (i = num_objects; i--; )
1858 object_list [i] = SvCLOBJ ("OpenCL::Queue::enqueue_acquire/release_gl_objects", "objects", *av_fetch (av, i, 0), "OpenCL::Memory"); 1959 object_list [i] = SvCLOBJ ("OpenCL::Queue::acquire/release_gl_objects", "objects", *av_fetch (av, i, 0), "OpenCL::Memory");
1859 1960
1860 if (ix) 1961 if (ix)
1861 NEED_SUCCESS (EnqueueReleaseGLObjects, (self, num_objects, object_list, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0)); 1962 NEED_SUCCESS (EnqueueReleaseGLObjects, (self, num_objects, object_list, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0));
1862 else 1963 else
1863 NEED_SUCCESS (EnqueueAcquireGLObjects, (self, num_objects, object_list, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0)); 1964 NEED_SUCCESS (EnqueueAcquireGLObjects, (self, num_objects, object_list, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0));

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines