… | |
… | |
28 | specific device ("compiling and linking"), also binary programs. For each |
28 | specific device ("compiling and linking"), also binary programs. For each |
29 | kernel function in a program you can then create an OpenCL::Kernel object |
29 | kernel function in a program you can then create an OpenCL::Kernel object |
30 | which represents basically a function call with argument values. |
30 | which represents basically a function call with argument values. |
31 | |
31 | |
32 | OpenCL::Memory objects of various flavours: OpenCL::Buffers objects (flat |
32 | OpenCL::Memory objects of various flavours: OpenCL::Buffers objects (flat |
33 | memory areas, think array) and OpenCL::Image objects (think 2d or 3d |
33 | memory areas, think arrays or structs) and OpenCL::Image objects (think 2d |
34 | array) for bulk data and input and output for kernels. |
34 | or 3d array) for bulk data and input and output for kernels. |
35 | |
35 | |
36 | OpenCL::Sampler objects, which are kind of like texture filter modes in |
36 | OpenCL::Sampler objects, which are kind of like texture filter modes in |
37 | OpenGL. |
37 | OpenGL. |
38 | |
38 | |
39 | OpenCL::Queue objects - command queues, which allow you to submit memory |
39 | OpenCL::Queue objects - command queues, which allow you to submit memory |
… | |
… | |
51 | http://www.khronos.org/registry/cl/specs/opencl-1.1.pdf |
51 | http://www.khronos.org/registry/cl/specs/opencl-1.1.pdf |
52 | |
52 | |
53 | OpenCL manpages: |
53 | OpenCL manpages: |
54 | |
54 | |
55 | http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/ |
55 | http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/ |
|
|
56 | |
|
|
57 | If you are into UML class diagrams, the following diagram might help - if |
|
|
58 | not, it will be mildly cobfusing: |
|
|
59 | |
|
|
60 | http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/classDiagram.html |
|
|
61 | |
|
|
62 | Here's a tutorial from AMD (very AMD-centric, too), not sure how useful it |
|
|
63 | is, but at least it's free of charge: |
|
|
64 | |
|
|
65 | http://developer.amd.com/zones/OpenCLZone/courses/Documents/Introduction_to_OpenCL_Programming%20Training_Guide%20%28201005%29.pdf |
|
|
66 | |
|
|
67 | And here's NVIDIA's OpenCL Best Practises Guide: |
|
|
68 | |
|
|
69 | http://developer.download.nvidia.com/compute/cuda/3_2/toolkit/docs/OpenCL_Best_Practices_Guide.pdf |
56 | |
70 | |
57 | =head1 BASIC WORKFLOW |
71 | =head1 BASIC WORKFLOW |
58 | |
72 | |
59 | To get something done, you basically have to do this once (refer to the |
73 | To get something done, you basically have to do this once (refer to the |
60 | examples below for actual code, this is just a high-level description): |
74 | examples below for actual code, this is just a high-level description): |
… | |
… | |
138 | |
152 | |
139 | my $src = ' |
153 | my $src = ' |
140 | __kernel void |
154 | __kernel void |
141 | squareit (__global float *input, __global float *output) |
155 | squareit (__global float *input, __global float *output) |
142 | { |
156 | { |
143 | size_t id = get_global_id (0); |
157 | $id = get_global_id (0); |
144 | output [id] = input [id] * input [id]; |
158 | output [id] = input [id] * input [id]; |
145 | } |
159 | } |
146 | '; |
160 | '; |
147 | |
161 | |
148 | my $prog = $ctx->program_with_source ($src); |
162 | my $prog = $ctx->program_with_source ($src); |
… | |
… | |
201 | |
215 | |
202 | =head1 DOCUMENTATION |
216 | =head1 DOCUMENTATION |
203 | |
217 | |
204 | =head2 BASIC CONVENTIONS |
218 | =head2 BASIC CONVENTIONS |
205 | |
219 | |
206 | This is not a 1:1 C-style translation of OpenCL to Perl - instead I |
220 | This is not a one-to-one C-style translation of OpenCL to Perl - instead |
207 | attempted to make the interface as type-safe as possible and introducing |
221 | I attempted to make the interface as type-safe as possible by introducing |
208 | object syntax where it makes sense. There are a number of important |
222 | object syntax where it makes sense. There are a number of important |
209 | differences between the OpenCL C API and this module: |
223 | differences between the OpenCL C API and this module: |
210 | |
224 | |
211 | =over 4 |
225 | =over 4 |
212 | |
226 | |
… | |
… | |
217 | =item * OpenCL uses CamelCase for function names (C<clGetPlatformInfo>), |
231 | =item * OpenCL uses CamelCase for function names (C<clGetPlatformInfo>), |
218 | while this module uses underscores as word separator and often leaves out |
232 | while this module uses underscores as word separator and often leaves out |
219 | prefixes (C<< $platform->info >>). |
233 | prefixes (C<< $platform->info >>). |
220 | |
234 | |
221 | =item * OpenCL often specifies fixed vector function arguments as short |
235 | =item * OpenCL often specifies fixed vector function arguments as short |
222 | arrays (C<size_t origin[3]>), while this module explicitly expects the |
236 | arrays (C<$origin[3]>), while this module explicitly expects the |
223 | components as separate arguments- |
237 | components as separate arguments- |
|
|
238 | |
|
|
239 | =item * Structures are often specified with their components, and returned |
|
|
240 | as arrayrefs. |
224 | |
241 | |
225 | =item * Where possible, one of the pitch values is calculated from the |
242 | =item * Where possible, one of the pitch values is calculated from the |
226 | perl scalar length and need not be specified. |
243 | perl scalar length and need not be specified. |
227 | |
244 | |
228 | =item * When enqueuing commands, the wait list is specified by adding |
245 | =item * When enqueuing commands, the wait list is specified by adding |
… | |
… | |
371 | |
388 | |
372 | =item $buf = $ctx->buffer_sv ($flags, $data) |
389 | =item $buf = $ctx->buffer_sv ($flags, $data) |
373 | |
390 | |
374 | Creates a new OpenCL::Buffer object and initialise it with the given data values. |
391 | Creates a new OpenCL::Buffer object and initialise it with the given data values. |
375 | |
392 | |
376 | =item $img = $ctx->image2d ($flags, $channel_order, $channel_type, $width, $height, $data) |
393 | =item $img = $ctx->image2d ($flags, $channel_order, $channel_type, $width, $height, $row_pitch = 0, $data = undef) |
377 | |
394 | |
378 | Creates a new OpenCL::Image2D object and optionally initialises it with the given data values. |
395 | Creates a new OpenCL::Image2D object and optionally initialises it with the given data values. |
379 | |
396 | |
380 | L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateImage2D.html> |
397 | L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateImage2D.html> |
381 | |
398 | |
382 | =item $img = $ctx->image3d ($flags, $channel_order, $channel_type, $width, $height, $depth, $slice_pitch, $data) |
399 | =item $img = $ctx->image3d ($flags, $channel_order, $channel_type, $width, $height, $depth, $row_pitch = 0, $slice_pitch = 0, $data = undef) |
383 | |
400 | |
384 | Creates a new OpenCL::Image3D object and optionally initialises it with the given data values. |
401 | Creates a new OpenCL::Image3D object and optionally initialises it with the given data values. |
385 | |
402 | |
386 | L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateImage3D.html> |
403 | L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateImage3D.html> |
387 | |
404 | |
… | |
… | |
450 | |
467 | |
451 | =item $ev = $queue->enqueue_read_image ($src, $blocking, $x, $y, $z, $width, $height, $depth, $row_pitch, $slice_pitch, $data, $wait_events...) |
468 | =item $ev = $queue->enqueue_read_image ($src, $blocking, $x, $y, $z, $width, $height, $depth, $row_pitch, $slice_pitch, $data, $wait_events...) |
452 | |
469 | |
453 | L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueReadImage.html> |
470 | L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueReadImage.html> |
454 | |
471 | |
455 | =item $ev = $queue->enqueue_write_image ($src, $blocking, $x, $y, $z, $width, $height, $depth, $row_pitch, $data, $wait_events...) |
472 | =item $ev = $queue->enqueue_write_image ($src, $blocking, $x, $y, $z, $width, $height, $depth, $row_pitch, $slice_pitch, $data, $wait_events...) |
456 | |
473 | |
457 | L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueWriteImage.html> |
474 | L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueWriteImage.html> |
458 | |
475 | |
459 | =item $ev = $queue->enqueue_copy_buffer_rect ($src, $dst, $src_x, $src_y, $src_z, $dst_x, $dst_y, $dst_z, $width, $height, $depth, $src_row_pitch, $src_slice_pitch, 4dst_row_pitch, $dst_slice_pitch, $ait_event...) |
476 | =item $ev = $queue->enqueue_copy_buffer_rect ($src, $dst, $src_x, $src_y, $src_z, $dst_x, $dst_y, $dst_z, $width, $height, $depth, $src_row_pitch, $src_slice_pitch, $dst_row_pitch, $dst_slice_pitch, $wait_event...) |
460 | |
477 | |
461 | Yeah. |
478 | Yeah. |
462 | |
479 | |
463 | L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyBufferRect.html> |
480 | L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyBufferRect.html> |
464 | |
481 | |
465 | =item $ev = $queue->enqueue_copy_buffer_to_image (OpenCL::Buffer src, OpenCL::Image dst, size_t src_offset, size_t dst_x, size_t dst_y, size_t dst_z, size_t width, size_t height, size_t depth, ...) |
482 | =item $ev = $queue->enqueue_copy_buffer_to_image ($src_buffer, $dst_image, $src_offset, $dst_x, $dst_y, $dst_z, $width, $height, $depth, $wait_events...) |
466 | |
483 | |
467 | L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyBufferToImage.html>. |
484 | L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyBufferToImage.html>. |
468 | |
485 | |
469 | =item $ev = $queue->enqueue_copy_image (OpenCL::Image src, OpenCL::Buffer dst, size_t src_x, size_t src_y, size_t src_z, size_t dst_x, size_t dst_y, size_t dst_z, size_t width, size_t height, size_t depth, ...) |
486 | =item $ev = $queue->enqueue_copy_image ($src_image, $dst_image, $src_x, $src_y, $src_z, $dst_x, $dst_y, $dst_z, $width, $height, $depth, $wait_events...) |
470 | |
487 | |
471 | L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyImage.html> |
488 | L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyImage.html> |
472 | |
489 | |
473 | =item $ev = $queue->enqueue_copy_image_to_buffer (OpenCL::Image src, OpenCL::Buffer dst, size_t src_x, size_t src_y, size_t src_z, size_t width, size_t height, size_t depth, size_t dst_offset, ...) |
490 | =item $ev = $queue->enqueue_copy_image_to_buffer ($src_image, $dst_image, $src_x, $src_y, $src_z, $width, $height, $depth, $dst_offset, $wait_events...) |
474 | |
491 | |
475 | L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyImageToBuffer.html> |
492 | L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyImageToBuffer.html> |
476 | |
493 | |
477 | =item $ev = $queue->enqueue_task ($kernel, $wait_events...) |
494 | =item $ev = $queue->enqueue_task ($kernel, $wait_events...) |
478 | |
495 | |
… | |
… | |
643 | package OpenCL; |
660 | package OpenCL; |
644 | |
661 | |
645 | use common::sense; |
662 | use common::sense; |
646 | |
663 | |
647 | BEGIN { |
664 | BEGIN { |
648 | our $VERSION = '0.14'; |
665 | our $VERSION = '0.15'; |
649 | |
666 | |
650 | require XSLoader; |
667 | require XSLoader; |
651 | XSLoader::load (__PACKAGE__, $VERSION); |
668 | XSLoader::load (__PACKAGE__, $VERSION); |
652 | |
669 | |
653 | @OpenCL::Buffer::ISA = |
670 | @OpenCL::Buffer::ISA = |