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

Comparing OpenCL/OpenCL.pm (file contents):
Revision 1.9 by root, Thu Nov 17 01:36:52 2011 UTC vs.
Revision 1.15 by root, Thu Nov 17 03:05:56 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 array) and OpenCL::Image objects (think 2d or 3d
34array) for bulk data and input and output for kernels. 34array) for bulk data and input and output for kernels.
35 35
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
57=head1 BASIC WORKFLOW 57=head1 BASIC WORKFLOW
58 58
59To get something done, you basically have to do this once: 59To get something done, you basically have to do this once (refer to the
60examples below for actual code, this is just a high-level description):
60 61
61Find some platform (e.g. the first one) and some device (e.g. the first 62Find 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. 63device of the platform), and create a context from those.
63 64
64Create a command queue from your context, and program objects from your 65Create program objects from your OpenCL source code, then build (compile)
65OpenCL source code, build the programs. 66the programs for each device you want to run them on.
66 67
67Create kernel objects for all kernels you want to use. 68Create kernel objects for all kernels you want to use (surprisingly, these
69are not device-specific).
68 70
69Then, to execute stuff, you repeat this: 71Then, to execute stuff, you repeat these steps, possibly resuing or
72sharing some buffers:
70 73
71Create some input and output buffers from your context. Initialise the 74Create some input and output buffers from your context. Set these as
72input buffers with data. Set these as arguments to your kernel. 75arguments to your kernel.
76
77Enqueue buffer writes to initialise your input buffers (when not
78initialised at creation time).
73 79
74Enqueue the kernel execution. 80Enqueue the kernel execution.
75 81
76Enqueue buffer reads for your output buffer to read results. 82Enqueue buffer reads for your output buffer to read results.
77 83
78The next section shows how this can be done.
79
80=head1 EXAMPLES 84=head1 EXAMPLES
81 85
82=head2 Enumerate all devices and get contexts for them. 86=head2 Enumerate all devices and get contexts for them.
83 87
88Best run this once to get a feel for the platforms and devices in your
89system.
90
84 for my $platform (OpenCL::platforms) { 91 for my $platform (OpenCL::platforms) {
85 warn $platform->info (OpenCL::PLATFORM_NAME); 92 printf "platform: %s\n", $platform->info (OpenCL::PLATFORM_NAME);
86 warn $platform->info (OpenCL::PLATFORM_EXTENSIONS); 93 printf "extensions: %s\n", $platform->info (OpenCL::PLATFORM_EXTENSIONS);
87 for my $device ($platform->devices) { 94 for my $device ($platform->devices) {
88 warn $device->info (OpenCL::DEVICE_NAME); 95 printf "+ device: %s\n", $device->info (OpenCL::DEVICE_NAME);
89 my $ctx = $device->context_simple; 96 my $ctx = $device->context;
90 # do stuff 97 # do stuff
91 } 98 }
92 } 99 }
93 100
94=head2 Get a useful context and a command queue. 101=head2 Get a useful context and a command queue.
95 102
96 my $dev = ((OpenCL::platforms)[0]->devices)[0]; 103This is a useful boilerplate for any OpenCL program that only wants to use
97 my $ctx = $dev->context_simple; 104one device,
98 my $queue = $ctx->queue ($dev); 105
106 my ($platform) = OpenCL::platforms; # find first platform
107 my ($dev) = $platform->devices; # find first device of platform
108 my $ctx = $platform->context (undef, [$dev]); # create context out of those
109 my $queue = $ctx->queue ($dev); # create a command queue for the device
99 110
100=head2 Print all supported image formats of a context. 111=head2 Print all supported image formats of a context.
101 112
113Best run this once for your context, to see whats available and how to
114gather information.
115
102 for my $type (OpenCL::MEM_OBJECT_IMAGE2D, OpenCL::MEM_OBJECT_IMAGE3D) { 116 for my $type (OpenCL::MEM_OBJECT_IMAGE2D, OpenCL::MEM_OBJECT_IMAGE3D) {
103 say "supported image formats for ", OpenCL::enum2str $type; 117 print "supported image formats for ", OpenCL::enum2str $type, "\n";
104 118
105 for my $f ($ctx->supported_image_formats (0, $type)) { 119 for my $f ($ctx->supported_image_formats (0, $type)) {
106 printf " %-10s %-20s\n", OpenCL::enum2str $f->[0], OpenCL::enum2str $f->[1]; 120 printf " %-10s %-20s\n", OpenCL::enum2str $f->[0], OpenCL::enum2str $f->[1];
107 } 121 }
108 } 122 }
111then asynchronously. 125then asynchronously.
112 126
113 my $buf = $ctx->buffer_sv (OpenCL::MEM_COPY_HOST_PTR, "helmut"); 127 my $buf = $ctx->buffer_sv (OpenCL::MEM_COPY_HOST_PTR, "helmut");
114 128
115 $queue->enqueue_read_buffer ($buf, 1, 1, 3, my $data); 129 $queue->enqueue_read_buffer ($buf, 1, 1, 3, my $data);
116 warn $data; 130 print "$data\n";
117 131
118 my $ev = $queue->enqueue_read_buffer ($buf, 0, 1, 3, my $data); 132 my $ev = $queue->enqueue_read_buffer ($buf, 0, 1, 3, my $data);
119 $ev->wait; 133 $ev->wait;
120 warn $data; 134 print "$data\n"; # prints "elm"
121 135
122=head2 Create and build a program, then create a kernel out of one of its 136=head2 Create and build a program, then create a kernel out of one of its
123functions. 137functions.
124 138
125 my $src = ' 139 my $src = '
126 __kernel void 140 __kernel void
127 squareit (__global float *input, __global float *output) 141 squareit (__global float *input, __global float *output)
128 { 142 {
129 size_t id = get_global_id (0); 143 $id = get_global_id (0);
130 output [id] = input [id] * input [id]; 144 output [id] = input [id] * input [id];
131 } 145 }
132 '; 146 ';
133 147
134 my $prog = $ctx->program_with_source ($src); 148 my $prog = $ctx->program_with_source ($src);
135 149
150 # build croaks on compile errors, so catch it and print the compile errors
136 eval { $prog->build ($dev); 1 } 151 eval { $prog->build ($dev); 1 }
137 or die $prog->build_info ($dev, OpenCL::PROGRAM_BUILD_LOG); 152 or die $prog->build_info ($dev, OpenCL::PROGRAM_BUILD_LOG);
138 153
139 my $kernel = $prog->kernel ("squareit"); 154 my $kernel = $prog->kernel ("squareit");
140 155
141=head2 Create some input and output float buffers, then call squareit on them. 156=head2 Create some input and output float buffers, then call the
157'squareit' kernel on them.
142 158
143 my $input = $ctx->buffer_sv (OpenCL::MEM_COPY_HOST_PTR, pack "f*", 1, 2, 3, 4.5); 159 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); 160 my $output = $ctx->buffer (0, OpenCL::SIZEOF_FLOAT * 5);
145 161
146 # set buffer 162 # set buffer
152 168
153 # enqueue a synchronous read 169 # enqueue a synchronous read
154 $queue->enqueue_read_buffer ($output, 1, 0, OpenCL::SIZEOF_FLOAT * 4, my $data); 170 $queue->enqueue_read_buffer ($output, 1, 0, OpenCL::SIZEOF_FLOAT * 4, my $data);
155 171
156 # print the results: 172 # print the results:
157 say join ", ", unpack "f*", $data; 173 printf "%s\n", join ", ", unpack "f*", $data;
158 174
159=head2 The same enqueue operations as before, but assuming an out-of-order queue, 175=head2 The same enqueue operations as before, but assuming an out-of-order queue,
160showing off barriers. 176showing off barriers.
161 177
162 # execute it for all 4 numbers 178 # execute it for all 4 numbers
185 201
186=head1 DOCUMENTATION 202=head1 DOCUMENTATION
187 203
188=head2 BASIC CONVENTIONS 204=head2 BASIC CONVENTIONS
189 205
190This is not a 1:1 C-style translation of OpenCL to Perl - instead I 206This 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 207I attempted to make the interface as type-safe as possible by introducing
192object syntax where it makes sense. There are a number of important 208object syntax where it makes sense. There are a number of important
193differences between the OpenCL C API and this module: 209differences between the OpenCL C API and this module:
194 210
195=over 4 211=over 4
196 212
201=item * OpenCL uses CamelCase for function names (C<clGetPlatformInfo>), 217=item * OpenCL uses CamelCase for function names (C<clGetPlatformInfo>),
202while this module uses underscores as word separator and often leaves out 218while this module uses underscores as word separator and often leaves out
203prefixes (C<< $platform->info >>). 219prefixes (C<< $platform->info >>).
204 220
205=item * OpenCL often specifies fixed vector function arguments as short 221=item * OpenCL often specifies fixed vector function arguments as short
206arrays (C<size_t origin[3]>), while this module explicitly expects the 222arrays (C<$origin[3]>), while this module explicitly expects the
207components as separate arguments- 223components as separate arguments-
224
225=item * Structures are often specified with their components, and returned
226as arrayrefs.
208 227
209=item * Where possible, one of the pitch values is calculated from the 228=item * Where possible, one of the pitch values is calculated from the
210perl scalar length and need not be specified. 229perl scalar length and need not be specified.
211 230
212=item * When enqueuing commands, the wait list is specified by adding 231=item * When enqueuing commands, the wait list is specified by adding
245 264
246=over 4 265=over 4
247 266
248=item $int = OpenCL::errno 267=item $int = OpenCL::errno
249 268
250The last error returned by a function - it's only changed on errors. 269The last error returned by a function - it's only valid after an error occured
270and before calling another OpenCL function.
251 271
252=item $str = OpenCL::err2str $errval 272=item $str = OpenCL::err2str $errval
253 273
254Comverts an error value into a human readable string. 274Comverts an error value into a human readable string.
255 275
265 285
266Returns all available OpenCL::Platform objects. 286Returns all available OpenCL::Platform objects.
267 287
268L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetPlatformIDs.html> 288L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetPlatformIDs.html>
269 289
270=item $ctx = OpenCL::context_from_type_simple $type = OpenCL::DEVICE_TYPE_DEFAULT 290=item $ctx = OpenCL::context_from_type $properties, $type = OpenCL::DEVICE_TYPE_DEFAULT, $notify = undef
271 291
272Tries to create a context from a default device and platform - never worked for me. 292Tries to create a context from a default device and platform - never worked for me.
273 293
274L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateContextFromType.html> 294L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateContextFromType.html>
275 295
295 315
296=item @devices = $platform->devices ($type = OpenCL::DEVICE_TYPE_ALL) 316=item @devices = $platform->devices ($type = OpenCL::DEVICE_TYPE_ALL)
297 317
298Returns a list of matching OpenCL::Device objects. 318Returns a list of matching OpenCL::Device objects.
299 319
300=item $ctx = $platform->context_from_type_simple ($type = OpenCL::DEVICE_TYPE_DEFAULT) 320=item $ctx = $platform->context_from_type ($properties, $type = OpenCL::DEVICE_TYPE_DEFAULT, $notify = undef)
301 321
302Tries to create a context. Never worked for me. 322Tries to create a context. Never worked for me, and you need devices explitly anyway.
303 323
304L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateContextFromType.html> 324L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateContextFromType.html>
305 325
326=item $ctx = $device->context ($properties = undef, @$devices, $notify = undef)
327
328Create a new OpenCL::Context object using the given device object(s)- a
329CL_CONTEXT_PLATFORM property is supplied automatically.
330
331L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateContext.html>
332
306=back 333=back
307 334
308=head2 THE OpenCL::Device CLASS 335=head2 THE OpenCL::Device CLASS
309 336
310=over 4 337=over 4
312=item $packed_value = $device->info ($name) 339=item $packed_value = $device->info ($name)
313 340
314See C<< $platform->info >> for details. 341See C<< $platform->info >> for details.
315 342
316L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetDeviceInfo.html> 343L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetDeviceInfo.html>
317
318=item $ctx = $device->context_simple
319
320Convenience function to create a new OpenCL::Context object.
321
322L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateContext.html>
323 344
324=back 345=back
325 346
326=head2 THE OpenCL::Context CLASS 347=head2 THE OpenCL::Context CLASS
327 348
436 457
437=item $ev = $queue->enqueue_write_image ($src, $blocking, $x, $y, $z, $width, $height, $depth, $row_pitch, $data, $wait_events...) 458=item $ev = $queue->enqueue_write_image ($src, $blocking, $x, $y, $z, $width, $height, $depth, $row_pitch, $data, $wait_events...)
438 459
439L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueWriteImage.html> 460L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueWriteImage.html>
440 461
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...) 462=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 463
443Yeah. 464Yeah.
444 465
445L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyBufferRect.html> 466L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyBufferRect.html>
446 467
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, ...) 468=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 469
449L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyBufferToImage.html>. 470L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyBufferToImage.html>.
450 471
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, ...) 472=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 473
453L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyImage.html> 474L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyImage.html>
454 475
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, ...) 476=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 477
457L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyImageToBuffer.html> 478L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyImageToBuffer.html>
458 479
459=item $ev = $queue->enqueue_task ($kernel, $wait_events...) 480=item $ev = $queue->enqueue_task ($kernel, $wait_events...)
460 481
625package OpenCL; 646package OpenCL;
626 647
627use common::sense; 648use common::sense;
628 649
629BEGIN { 650BEGIN {
630 our $VERSION = '0.03'; 651 our $VERSION = '0.14';
631 652
632 require XSLoader; 653 require XSLoader;
633 XSLoader::load (__PACKAGE__, $VERSION); 654 XSLoader::load (__PACKAGE__, $VERSION);
634 655
635 @OpenCL::Buffer::ISA = 656 @OpenCL::Buffer::ISA =

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines