--- OpenCL/OpenCL.xs 2011/11/15 06:50:30 1.1 +++ OpenCL/OpenCL.xs 2011/11/15 09:24:40 1.2 @@ -8,6 +8,11 @@ typedef cl_device_id OpenCL__Device; typedef cl_context OpenCL__Context; typedef cl_command_queue OpenCL__Queue; +typedef cl_mem OpenCL__Memory; +typedef cl_sampler OpenCL__Sampler; +typedef cl_program OpenCL__Program; +typedef cl_kernel OpenCL__Kernel; +typedef cl_event OpenCL__Event; static const struct { IV iv; @@ -33,18 +38,40 @@ } #define FAIL(name,res) \ - croak (# name ": %s", clstrerror (res)); + croak ("cl" # name ": %s", clstrerror (res)); #define NEED_SUCCESS(name,args) \ do { \ - cl_int res = name args; \ + cl_int res = cl ## name args; \ \ if (res) \ FAIL (name, res); \ } while (0) +#define NEW_MORTAL_OBJ(class,ptr) sv_setref_pv (sv_newmortal (), class, ptr) +#define XPUSH_NEW_OBJ(class,ptr) XPUSHs (NEW_MORTAL_OBJ (class, ptr)) + +/*TODO*/ +#define EVENT_LIST(items,count) cl_uint event_list_count = 0; cl_event *event_list_ptr = 0 + +#define INFO(class) \ +{ \ + size_t size; \ + SV *sv; \ + \ + NEED_SUCCESS (Get ## class ## Info, (this, name, 0, 0, &size)); \ + sv = sv_2mortal (newSV (size)); \ + SvUPGRADE (sv, SVt_PV); \ + SvPOK_only (sv); \ + SvCUR_set (sv, size); \ + NEED_SUCCESS (Get ## class ## Info, (this, name, size, SvPVX (sv), 0)); \ + XPUSHs (sv); \ +} + MODULE = OpenCL PACKAGE = OpenCL +PROTOTYPES: ENABLE + BOOT: { HV *stash = gv_stashpv ("OpenCL", 1); @@ -67,13 +94,13 @@ cl_uint count; int i; - NEED_SUCCESS (clGetPlatformIDs, (0, 0, &count)); + NEED_SUCCESS (GetPlatformIDs, (0, 0, &count)); Newx (list, count, cl_platform_id); - NEED_SUCCESS (clGetPlatformIDs, (count, list, 0)); + NEED_SUCCESS (GetPlatformIDs, (count, list, 0)); EXTEND (SP, count); for (i = 0; i < count; ++i) - PUSHs (sv_setref_pv (sv_newmortal (), "OpenCL::Platform", list [i])); + PUSHs (NEW_MORTAL_OBJ ("OpenCL::Platform", list [i])); Safefree (list); } @@ -86,28 +113,27 @@ cl_context ctx = clCreateContextFromType (0, type, 0, 0, &res); if (res) - FAIL (clCreateContextFromType, res); + FAIL (CreateContextFromType, res); - XPUSHs (sv_setref_pv (sv_newmortal (), "OpenCL::Context", ctx)); + XPUSH_NEW_OBJ ("OpenCL::Context", ctx); } +void +wait_for_events (...) + CODE: +{ + EVENT_LIST (0, items); + NEED_SUCCESS (WaitForEvents, (event_list_count, event_list_ptr)); +} + +PROTOTYPES: DISABLE + MODULE = OpenCL PACKAGE = OpenCL::Platform void info (OpenCL::Platform this, cl_platform_info name) PPCODE: -{ - size_t size; - SV *sv; - - NEED_SUCCESS (clGetPlatformInfo, (this, name, 0, 0, &size)); - sv = sv_2mortal (newSV (size)); - SvUPGRADE (sv, SVt_PV); - SvPOK_only (sv); - SvCUR_set (sv, size); - NEED_SUCCESS (clGetPlatformInfo, (this, name, size, SvPVX (sv), 0)); - XPUSHs (sv); -} + INFO (Platform) void devices (OpenCL::Platform this, cl_device_type type = CL_DEVICE_TYPE_ALL) @@ -117,9 +143,9 @@ cl_uint count; int i; - NEED_SUCCESS (clGetDeviceIDs, (this, type, 0, 0, &count)); + NEED_SUCCESS (GetDeviceIDs, (this, type, 0, 0, &count)); Newx (list, count, cl_device_id); - NEED_SUCCESS (clGetDeviceIDs, (this, type, count, list, 0)); + NEED_SUCCESS (GetDeviceIDs, (this, type, count, list, 0)); EXTEND (SP, count); for (i = 0; i < count; ++i) @@ -137,28 +163,22 @@ cl_context ctx = clCreateContextFromType (props, type, 0, 0, &res); if (res) - FAIL (clCreateContextFromType, res); + FAIL (CreateContextFromType, res); - XPUSHs (sv_setref_pv (sv_newmortal (), "OpenCL::Context", ctx)); + XPUSH_NEW_OBJ ("OpenCL::Context", ctx); } +void +unload_compiler () + CODE: + NEED_SUCCESS (UnloadCompiler, ()); + MODULE = OpenCL PACKAGE = OpenCL::Device void info (OpenCL::Device this, cl_device_info name) PPCODE: -{ - size_t size; - SV *sv; - - NEED_SUCCESS (clGetDeviceInfo, (this, name, 0, 0, &size)); - sv = sv_2mortal (newSV (size)); - SvUPGRADE (sv, SVt_PV); - SvPOK_only (sv); - SvCUR_set (sv, size); - NEED_SUCCESS (clGetDeviceInfo, (this, name, size, SvPVX (sv), 0)); - XPUSHs (sv); -} + INFO (Device) void context_simple (OpenCL::Device this) @@ -168,9 +188,9 @@ cl_context ctx = clCreateContext (0, 1, &this, 0, 0, &res); if (res) - FAIL (clCreateContext, res); + FAIL (CreateContext, res); - XPUSHs (sv_setref_pv (sv_newmortal (), "OpenCL::Context", ctx)); + XPUSH_NEW_OBJ ("OpenCL::Context", ctx); } MODULE = OpenCL PACKAGE = OpenCL::Context @@ -183,30 +203,79 @@ void info (OpenCL::Context this, cl_context_info name) PPCODE: + INFO (Context) + +void +command_queue_simple (OpenCL::Context this, OpenCL::Device device) + PPCODE: { - size_t size; - SV *sv; + cl_int res; + cl_command_queue queue = clCreateCommandQueue (this, device, 0, &res); - NEED_SUCCESS (clGetContextInfo, (this, name, 0, 0, &size)); - sv = sv_2mortal (newSV (size)); - SvUPGRADE (sv, SVt_PV); - SvPOK_only (sv); - SvCUR_set (sv, size); - NEED_SUCCESS (clGetContextInfo, (this, name, size, SvPVX (sv), 0)); - XPUSHs (sv); + if (res) + FAIL (CreateCommandQueue, res); + + XPUSH_NEW_OBJ ("OpenCL::Queue", queue); } void -command_queue_simple (OpenCL::Context this, OpenCL::Device device) +buffer (OpenCL::Context this, cl_mem_flags flags, size_t len) PPCODE: { cl_int res; - cl_command_queue queue = clCreateCommandQueue (this, device, 0, &res); + cl_mem mem = clCreateBuffer (this, flags, len, 0, &res); + + if (res) + FAIL (CreateBuffer, res); + + XPUSH_NEW_OBJ ("OpenCL::Memory", mem); +} + +void +buffer_sv (OpenCL::Context this, cl_mem_flags flags, SV *data) + PPCODE: +{ + STRLEN len; + char *ptr = SvPVbyte (data, len); + cl_int res; + cl_mem mem = clCreateBuffer (this, flags, len, ptr, &res); + + if (res) + FAIL (CreateBuffer, res); + + XPUSH_NEW_OBJ ("OpenCL::Memory", mem); +} + +void +sampler (OpenCL::Context this, cl_bool normalized_coords, cl_addressing_mode addressing_mode, cl_filter_mode filter_mode) + PPCODE: +{ + cl_int res; + cl_sampler sampler = clCreateSampler (this, normalized_coords, addressing_mode, filter_mode, &res); if (res) - FAIL (clCreateCommandQueue, res); + FAIL (CreateSampler, res); - XPUSHs (sv_setref_pv (sv_newmortal (), "OpenCL::Queue", queue)); + XPUSH_NEW_OBJ ("OpenCL::Sampler", sampler); +} + +void +program_with_source (OpenCL::Context this, SV *program) + PPCODE: +{ + STRLEN len; + size_t len2; + const char *ptr = SvPVbyte (program, len); + cl_int res; + cl_program prog; + + len2 = len; + prog = clCreateProgramWithSource (this, 1, &ptr, &len2, &res); + + if (res) + FAIL (CreateProgramWithSource, res); + + XPUSH_NEW_OBJ ("OpenCL::Program", prog); } MODULE = OpenCL PACKAGE = OpenCL::Queue @@ -219,16 +288,176 @@ void info (OpenCL::Queue this, cl_command_queue_info name) PPCODE: + INFO (CommandQueue) + +void +enqueue_read_buffer (OpenCL::Queue this, OpenCL::Memory mem, cl_bool blocking, size_t offset, size_t len, SV *data, ...) + PPCODE: +{ + cl_event ev = 0; + EVENT_LIST (6, items - 6); + + SvUPGRADE (data, SVt_PV); + SvGROW (data, len); + SvPOK_only (data); + SvCUR_set (data, len); + NEED_SUCCESS (EnqueueReadBuffer, (this, mem, blocking, offset, len, SvPVX (data), event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0)); + + if (ev) + XPUSH_NEW_OBJ ("OpenCL::Event", ev); +} + +void +enqueue_write_buffer (OpenCL::Queue this, OpenCL::Memory mem, cl_bool blocking, size_t offset, SV *data, ...) + PPCODE: +{ + cl_event ev = 0; + STRLEN len; + char *ptr = SvPVbyte (data, len); + EVENT_LIST (5, items - 5); + + NEED_SUCCESS (EnqueueReadBuffer, (this, mem, blocking, offset, len, ptr, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0)); + + if (ev) + XPUSH_NEW_OBJ ("OpenCL::Event", ev); +} + +void +enqueue_copy_buffer (OpenCL::Queue this, OpenCL::Memory src, OpenCL::Memory dst, size_t src_offset, size_t dst_offset, size_t len, ...) + PPCODE: +{ + cl_event ev = 0; + EVENT_LIST (6, items - 6); + + NEED_SUCCESS (EnqueueCopyBuffer, (this, src, dst, src_offset, dst_offset, len, event_list_count, event_list_ptr, GIMME_V != G_VOID ? &ev : 0)); + + if (ev) + XPUSH_NEW_OBJ ("OpenCL::Event", ev); +} + +void +enqueue_marker (OpenCL::Queue this) + PPCODE: +{ + cl_event ev; + NEED_SUCCESS (EnqueueMarker, (this, &ev)); + XPUSH_NEW_OBJ ("OpenCL::Event", ev); +} + +void +enqueue_wait_for_events (OpenCL::Queue this, ...) + CODE: +{ + EVENT_LIST (1, items - 1); + NEED_SUCCESS (EnqueueWaitForEvents, (this, event_list_count, event_list_ptr)); +} + +void +enqueue_barrier (OpenCL::Queue this) + CODE: + NEED_SUCCESS (EnqueueBarrier, (this)); + +MODULE = OpenCL PACKAGE = OpenCL::Memory + +void +DESTROY (OpenCL::Memory this) + CODE: + clReleaseMemObject (this); + +void +info (OpenCL::Memory this, cl_mem_info name) + PPCODE: + INFO (MemObject) + +MODULE = OpenCL PACKAGE = OpenCL::Sampler + +void +DESTROY (OpenCL::Sampler this) + CODE: + clReleaseSampler (this); + +void +info (OpenCL::Sampler this, cl_sampler_info name) + PPCODE: + INFO (Sampler) + +MODULE = OpenCL PACKAGE = OpenCL::Program + +void +DESTROY (OpenCL::Program this) + CODE: + clReleaseProgram (this); + +void +info (OpenCL::Program this, cl_program_info name) + PPCODE: + INFO (Program) + +void +build (OpenCL::Program this, OpenCL::Device device, SV *options = &PL_sv_undef) + CODE: + NEED_SUCCESS (BuildProgram, (this, 1, &device, SvPVbyte_nolen (options), 0, 0)); + +void +build_info (OpenCL::Program this, OpenCL::Device device, cl_program_build_info name) + PPCODE: { size_t size; SV *sv; - - NEED_SUCCESS (clGetCommandQueueInfo, (this, name, 0, 0, &size)); + + NEED_SUCCESS (GetProgramBuildInfo, (this, device, name, 0, 0, &size)); sv = sv_2mortal (newSV (size)); SvUPGRADE (sv, SVt_PV); SvPOK_only (sv); SvCUR_set (sv, size); - NEED_SUCCESS (clGetCommandQueueInfo, (this, name, size, SvPVX (sv), 0)); + NEED_SUCCESS (GetProgramBuildInfo, (this, device, name, size, SvPVX (sv), 0)); XPUSHs (sv); } +void +kernel (OpenCL::Program program, SV *function) + PPCODE: +{ + cl_int res; + cl_kernel kernel = clCreateKernel (program, SvPVbyte_nolen (function), &res); + + if (res) + FAIL (CreateKernel, res); + + XPUSH_NEW_OBJ ("OpenCL::Kernel", kernel); +} + +MODULE = OpenCL PACKAGE = OpenCL::Kernel + +void +DESTROY (OpenCL::Kernel this) + CODE: + clReleaseKernel (this); + +void +info (OpenCL::Kernel this, cl_kernel_info name) + PPCODE: + INFO (Kernel) + +void +set_bool (OpenCL::Kernel this, cl_uint idx, cl_bool value) + CODE: + clKernelSetArg (this, idx, sizeof (value), &value); + +MODULE = OpenCL PACKAGE = OpenCL::Event + +void +DESTROY (OpenCL::Event this) + CODE: + clReleaseEvent (this); + +void +info (OpenCL::Event this, cl_event_info name) + PPCODE: + INFO (Event) + +void +wait (OpenCL::Event this) + CODE: + clWaitForEvents (1, &this); +