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

Comparing OpenCL/OpenCL.pm (file contents):
Revision 1.10 by root, Thu Nov 17 02:10:39 2011 UTC vs.
Revision 1.16 by root, Thu Nov 17 03:42:03 2011 UTC

18vendors) - usually there is only one. 18vendors) - usually there is only one.
19 19
20Each platform gives you access to a number of OpenCL::Device objects, e.g. 20Each platform gives you access to a number of OpenCL::Device objects, e.g.
21your graphics card. 21your graphics card.
22 22
23From a platform and some devices, you create an OpenCL::Context, which is 23From a platform and some device(s), you create an OpenCL::Context, which is
24a very central object in OpenCL: Once you have a context you can create 24a very central object in OpenCL: Once you have a context you can create
25most other objects: 25most other objects:
26 26
27OpenCL::Program objects, which store source code and, after building 27OpenCL::Program objects, which store source code and, after building for a
28("compiling and linking"), also binary programs. For each kernel function 28specific device ("compiling and linking"), also binary programs. For each
29in a program you can then create an OpenCL::Kernel object which represents 29kernel function in a program you can then create an OpenCL::Kernel object
30basically a function call with argument values. 30which represents basically a function call with argument values.
31 31
32OpenCL::Memory objects of various flavours: OpenCL::Buffers objects (flat 32OpenCL::Memory objects of various flavours: OpenCL::Buffers objects (flat
33memory areas, think array) and OpenCL::Image objects (think 2d or 3d 33memory areas, think arrays or structs) and OpenCL::Image objects (think 2d
34array) for bulk data and input and output for kernels. 34or 3d array) for bulk data and input and output for kernels.
35 35
36OpenCL::Sampler objects, which are kind of like texture filter modes in 36OpenCL::Sampler objects, which are kind of like texture filter modes in
37OpenGL. 37OpenGL.
38 38
39OpenCL::Queue objects - command queues, which allow you to submit memory 39OpenCL::Queue objects - command queues, which allow you to submit memory
52 52
53OpenCL manpages: 53OpenCL 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 56
57Here's a tutorial from AMD (very AMD-centric, too), not sure how useful it
58is, but at least it's free of charge:
59
60 http://developer.amd.com/zones/OpenCLZone/courses/Documents/Introduction_to_OpenCL_Programming%20Training_Guide%20%28201005%29.pdf
61
62If you are into UML class diagrams, the following diagram might help - if
63not, it will be mildly cofusing:
64
65 http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/classDiagram.html
66
57=head1 BASIC WORKFLOW 67=head1 BASIC WORKFLOW
58 68
59To get something done, you basically have to do this once: 69To get something done, you basically have to do this once (refer to the
70examples below for actual code, this is just a high-level description):
60 71
61Find some platform (e.g. the first one) and some device (e.g. the first 72Find some platform (e.g. the first one) and some device(s) (e.g. the first
62device you can find), and create a context from those. 73device of the platform), and create a context from those.
63 74
64Create a command queue from your context, and program objects from your 75Create program objects from your OpenCL source code, then build (compile)
65OpenCL source code, build the programs. 76the programs for each device you want to run them on.
66 77
67Create kernel objects for all kernels you want to use. 78Create kernel objects for all kernels you want to use (surprisingly, these
79are not device-specific).
68 80
69Then, to execute stuff, you repeat this: 81Then, to execute stuff, you repeat these steps, possibly resuing or
82sharing some buffers:
70 83
71Create some input and output buffers from your context. Initialise the 84Create some input and output buffers from your context. Set these as
72input buffers with data. Set these as arguments to your kernel. 85arguments to your kernel.
86
87Enqueue buffer writes to initialise your input buffers (when not
88initialised at creation time).
73 89
74Enqueue the kernel execution. 90Enqueue the kernel execution.
75 91
76Enqueue buffer reads for your output buffer to read results. 92Enqueue buffer reads for your output buffer to read results.
77 93
78The next section shows how this can be done.
79
80=head1 EXAMPLES 94=head1 EXAMPLES
81 95
82=head2 Enumerate all devices and get contexts for them. 96=head2 Enumerate all devices and get contexts for them.
97
98Best run this once to get a feel for the platforms and devices in your
99system.
83 100
84 for my $platform (OpenCL::platforms) { 101 for my $platform (OpenCL::platforms) {
85 printf "platform: %s\n", $platform->info (OpenCL::PLATFORM_NAME); 102 printf "platform: %s\n", $platform->info (OpenCL::PLATFORM_NAME);
86 printf "extensions: %s\n", $platform->info (OpenCL::PLATFORM_EXTENSIONS); 103 printf "extensions: %s\n", $platform->info (OpenCL::PLATFORM_EXTENSIONS);
87 for my $device ($platform->devices) { 104 for my $device ($platform->devices) {
91 } 108 }
92 } 109 }
93 110
94=head2 Get a useful context and a command queue. 111=head2 Get a useful context and a command queue.
95 112
96 my $dev = ((OpenCL::platforms)[0]->devices)[0]; 113This is a useful boilerplate for any OpenCL program that only wants to use
97 my $ctx = $dev->context; 114one device,
98 my $queue = $ctx->queue ($dev); 115
116 my ($platform) = OpenCL::platforms; # find first platform
117 my ($dev) = $platform->devices; # find first device of platform
118 my $ctx = $platform->context (undef, [$dev]); # create context out of those
119 my $queue = $ctx->queue ($dev); # create a command queue for the device
99 120
100=head2 Print all supported image formats of a context. 121=head2 Print all supported image formats of a context.
122
123Best run this once for your context, to see whats available and how to
124gather information.
101 125
102 for my $type (OpenCL::MEM_OBJECT_IMAGE2D, OpenCL::MEM_OBJECT_IMAGE3D) { 126 for my $type (OpenCL::MEM_OBJECT_IMAGE2D, OpenCL::MEM_OBJECT_IMAGE3D) {
103 print "supported image formats for ", OpenCL::enum2str $type, "\n"; 127 print "supported image formats for ", OpenCL::enum2str $type, "\n";
104 128
105 for my $f ($ctx->supported_image_formats (0, $type)) { 129 for my $f ($ctx->supported_image_formats (0, $type)) {
124 148
125 my $src = ' 149 my $src = '
126 __kernel void 150 __kernel void
127 squareit (__global float *input, __global float *output) 151 squareit (__global float *input, __global float *output)
128 { 152 {
129 size_t id = get_global_id (0); 153 $id = get_global_id (0);
130 output [id] = input [id] * input [id]; 154 output [id] = input [id] * input [id];
131 } 155 }
132 '; 156 ';
133 157
134 my $prog = $ctx->program_with_source ($src); 158 my $prog = $ctx->program_with_source ($src);
135 159
160 # build croaks on compile errors, so catch it and print the compile errors
136 eval { $prog->build ($dev); 1 } 161 eval { $prog->build ($dev); 1 }
137 or die $prog->build_info ($dev, OpenCL::PROGRAM_BUILD_LOG); 162 or die $prog->build_info ($dev, OpenCL::PROGRAM_BUILD_LOG);
138 163
139 my $kernel = $prog->kernel ("squareit"); 164 my $kernel = $prog->kernel ("squareit");
140 165
141=head2 Create some input and output float buffers, then call squareit on them. 166=head2 Create some input and output float buffers, then call the
167'squareit' kernel on them.
142 168
143 my $input = $ctx->buffer_sv (OpenCL::MEM_COPY_HOST_PTR, pack "f*", 1, 2, 3, 4.5); 169 my $input = $ctx->buffer_sv (OpenCL::MEM_COPY_HOST_PTR, pack "f*", 1, 2, 3, 4.5);
144 my $output = $ctx->buffer (0, OpenCL::SIZEOF_FLOAT * 5); 170 my $output = $ctx->buffer (0, OpenCL::SIZEOF_FLOAT * 5);
145 171
146 # set buffer 172 # set buffer
185 211
186=head1 DOCUMENTATION 212=head1 DOCUMENTATION
187 213
188=head2 BASIC CONVENTIONS 214=head2 BASIC CONVENTIONS
189 215
190This is not a 1:1 C-style translation of OpenCL to Perl - instead I 216This is not a one-to-one C-style translation of OpenCL to Perl - instead
191attempted to make the interface as type-safe as possible and introducing 217I attempted to make the interface as type-safe as possible by introducing
192object syntax where it makes sense. There are a number of important 218object syntax where it makes sense. There are a number of important
193differences between the OpenCL C API and this module: 219differences between the OpenCL C API and this module:
194 220
195=over 4 221=over 4
196 222
201=item * OpenCL uses CamelCase for function names (C<clGetPlatformInfo>), 227=item * OpenCL uses CamelCase for function names (C<clGetPlatformInfo>),
202while this module uses underscores as word separator and often leaves out 228while this module uses underscores as word separator and often leaves out
203prefixes (C<< $platform->info >>). 229prefixes (C<< $platform->info >>).
204 230
205=item * OpenCL often specifies fixed vector function arguments as short 231=item * OpenCL often specifies fixed vector function arguments as short
206arrays (C<size_t origin[3]>), while this module explicitly expects the 232arrays (C<$origin[3]>), while this module explicitly expects the
207components as separate arguments- 233components as separate arguments-
234
235=item * Structures are often specified with their components, and returned
236as arrayrefs.
208 237
209=item * Where possible, one of the pitch values is calculated from the 238=item * Where possible, one of the pitch values is calculated from the
210perl scalar length and need not be specified. 239perl scalar length and need not be specified.
211 240
212=item * When enqueuing commands, the wait list is specified by adding 241=item * When enqueuing commands, the wait list is specified by adding
245 274
246=over 4 275=over 4
247 276
248=item $int = OpenCL::errno 277=item $int = OpenCL::errno
249 278
250The last error returned by a function - it's only changed on errors. 279The last error returned by a function - it's only valid after an error occured
280and before calling another OpenCL function.
251 281
252=item $str = OpenCL::err2str $errval 282=item $str = OpenCL::err2str $errval
253 283
254Comverts an error value into a human readable string. 284Comverts an error value into a human readable string.
255 285
297 327
298Returns a list of matching OpenCL::Device objects. 328Returns a list of matching OpenCL::Device objects.
299 329
300=item $ctx = $platform->context_from_type ($properties, $type = OpenCL::DEVICE_TYPE_DEFAULT, $notify = undef) 330=item $ctx = $platform->context_from_type ($properties, $type = OpenCL::DEVICE_TYPE_DEFAULT, $notify = undef)
301 331
302Tries to create a context. Never worked for me. 332Tries to create a context. Never worked for me, and you need devices explitly anyway.
303 333
304L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateContextFromType.html> 334L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateContextFromType.html>
305 335
336=item $ctx = $device->context ($properties = undef, @$devices, $notify = undef)
337
338Create a new OpenCL::Context object using the given device object(s)- a
339CL_CONTEXT_PLATFORM property is supplied automatically.
340
341L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateContext.html>
342
306=back 343=back
307 344
308=head2 THE OpenCL::Device CLASS 345=head2 THE OpenCL::Device CLASS
309 346
310=over 4 347=over 4
312=item $packed_value = $device->info ($name) 349=item $packed_value = $device->info ($name)
313 350
314See C<< $platform->info >> for details. 351See C<< $platform->info >> for details.
315 352
316L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetDeviceInfo.html> 353L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetDeviceInfo.html>
317
318=item $ctx = $device->context ($properties = undef, $notify = undef)
319
320Create a new OpenCL::Context object.
321
322L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateContext.html>
323 354
324=back 355=back
325 356
326=head2 THE OpenCL::Context CLASS 357=head2 THE OpenCL::Context CLASS
327 358
436 467
437=item $ev = $queue->enqueue_write_image ($src, $blocking, $x, $y, $z, $width, $height, $depth, $row_pitch, $data, $wait_events...) 468=item $ev = $queue->enqueue_write_image ($src, $blocking, $x, $y, $z, $width, $height, $depth, $row_pitch, $data, $wait_events...)
438 469
439L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueWriteImage.html> 470L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueWriteImage.html>
440 471
441=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...) 472=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, $wait_event...)
442 473
443Yeah. 474Yeah.
444 475
445L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyBufferRect.html> 476L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyBufferRect.html>
446 477
447=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, ...) 478=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...)
448 479
449L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyBufferToImage.html>. 480L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyBufferToImage.html>.
450 481
451=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, ...) 482=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...)
452 483
453L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyImage.html> 484L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyImage.html>
454 485
455=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, ...) 486=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...)
456 487
457L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyImageToBuffer.html> 488L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyImageToBuffer.html>
458 489
459=item $ev = $queue->enqueue_task ($kernel, $wait_events...) 490=item $ev = $queue->enqueue_task ($kernel, $wait_events...)
460 491
625package OpenCL; 656package OpenCL;
626 657
627use common::sense; 658use common::sense;
628 659
629BEGIN { 660BEGIN {
630 our $VERSION = '0.03'; 661 our $VERSION = '0.14';
631 662
632 require XSLoader; 663 require XSLoader;
633 XSLoader::load (__PACKAGE__, $VERSION); 664 XSLoader::load (__PACKAGE__, $VERSION);
634 665
635 @OpenCL::Buffer::ISA = 666 @OpenCL::Buffer::ISA =

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines