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

Comparing OpenCL/OpenCL.pm (file contents):
Revision 1.6 by root, Wed Nov 16 00:36:40 2011 UTC vs.
Revision 1.14 by root, Thu Nov 17 03:02:25 2011 UTC

6 6
7 use OpenCL; 7 use OpenCL;
8 8
9=head1 DESCRIPTION 9=head1 DESCRIPTION
10 10
11This is an early release which might be useful, but hasn't seen any testing. 11This is an early release which might be useful, but hasn't seen much testing.
12 12
13=head2 OpenCL FROM 10000 FEET HEIGHT
14
15Here is a high level overview of OpenCL:
16
17First you need to find one or more OpenCL::Platforms (kind of like
18vendors) - usually there is only one.
19
20Each platform gives you access to a number of OpenCL::Device objects, e.g.
21your graphics card.
22
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
25most other objects:
26
27OpenCL::Program objects, which store source code and, after building for a
28specific device ("compiling and linking"), also binary programs. For each
29kernel function in a program you can then create an OpenCL::Kernel object
30which represents basically a function call with argument values.
31
32OpenCL::Memory objects of various flavours: OpenCL::Buffers objects (flat
33memory areas, think array) and OpenCL::Image objects (think 2d or 3d
34array) for bulk data and input and output for kernels.
35
36OpenCL::Sampler objects, which are kind of like texture filter modes in
37OpenGL.
38
39OpenCL::Queue objects - command queues, which allow you to submit memory
40reads, writes and copies, as well as kernel calls to your devices. They
41also offer a variety of methods to synchronise request execution, for
42example with barriers or OpenCL::Event objects.
43
44OpenCL::Event objects are used to signal when something is complete.
45
13=head1 HELPFUL RESOURCES 46=head2 HELPFUL RESOURCES
14 47
15The OpenCL spec used to develop this module (1.2 spec was available, but 48The OpenCL spec used to develop this module (1.2 spec was available, but
16no implementation was available to me :). 49no implementation was available to me :).
17 50
18 http://www.khronos.org/registry/cl/specs/opencl-1.1.pdf 51 http://www.khronos.org/registry/cl/specs/opencl-1.1.pdf
19 52
20OpenCL manpages: 53OpenCL manpages:
21 54
22 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/
23 56
57=head1 BASIC WORKFLOW
58
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):
61
62Find some platform (e.g. the first one) and some device(s) (e.g. the first
63device of the platform), and create a context from those.
64
65Create program objects from your OpenCL source code, then build (compile)
66the programs for each device you want to run them on.
67
68Create kernel objects for all kernels you want to use (surprisingly, these
69are not device-specific).
70
71Then, to execute stuff, you repeat these steps, possibly resuing or
72sharing some buffers:
73
74Create some input and output buffers from your context. Set these as
75arguments to your kernel.
76
77Enqueue buffer writes to initialise your input buffers (when not
78initialised at creation time).
79
80Enqueue the kernel execution.
81
82Enqueue buffer reads for your output buffer to read results.
83
24=head1 EXAMPLES 84=head1 EXAMPLES
25 85
26=head2 Enumerate all devices and get contexts for them. 86=head2 Enumerate all devices and get contexts for them.
27 87
88Best run this once to get a feel for the platforms and devices in your
89system.
90
28 for my $platform (OpenCL::platforms) { 91 for my $platform (OpenCL::platforms) {
29 warn $platform->info (OpenCL::PLATFORM_NAME); 92 printf "platform: %s\n", $platform->info (OpenCL::PLATFORM_NAME);
30 warn $platform->info (OpenCL::PLATFORM_EXTENSIONS); 93 printf "extensions: %s\n", $platform->info (OpenCL::PLATFORM_EXTENSIONS);
31 for my $device ($platform->devices) { 94 for my $device ($platform->devices) {
32 warn $device->info (OpenCL::DEVICE_NAME); 95 printf "+ device: %s\n", $device->info (OpenCL::DEVICE_NAME);
33 my $ctx = $device->context_simple; 96 my $ctx = $device->context;
34 # do stuff 97 # do stuff
35 } 98 }
36 } 99 }
37 100
38=head2 Get a useful context and a command queue. 101=head2 Get a useful context and a command queue.
39 102
40 my $dev = ((OpenCL::platforms)[0]->devices)[0]; 103This is a useful boilerplate for any OpenCL program that only wants to use
41 my $ctx = $dev->context_simple; 104one device,
42 my $queue = $ctx->command_queue_simple ($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
43 110
44=head2 Print all supported image formats of a context. 111=head2 Print all supported image formats of a context.
45 112
113Best run this once for your context, to see whats available and how to
114gather information.
115
46 for my $type (OpenCL::MEM_OBJECT_IMAGE2D, OpenCL::MEM_OBJECT_IMAGE3D) { 116 for my $type (OpenCL::MEM_OBJECT_IMAGE2D, OpenCL::MEM_OBJECT_IMAGE3D) {
47 say "supported image formats for ", OpenCL::enum2str $type; 117 print "supported image formats for ", OpenCL::enum2str $type, "\n";
48 118
49 for my $f ($ctx->supported_image_formats (0, $type)) { 119 for my $f ($ctx->supported_image_formats (0, $type)) {
50 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];
51 } 121 }
52 } 122 }
55then asynchronously. 125then asynchronously.
56 126
57 my $buf = $ctx->buffer_sv (OpenCL::MEM_COPY_HOST_PTR, "helmut"); 127 my $buf = $ctx->buffer_sv (OpenCL::MEM_COPY_HOST_PTR, "helmut");
58 128
59 $queue->enqueue_read_buffer ($buf, 1, 1, 3, my $data); 129 $queue->enqueue_read_buffer ($buf, 1, 1, 3, my $data);
60 warn $data; 130 print "$data\n";
61 131
62 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);
63 $ev->wait; 133 $ev->wait;
64 warn $data; 134 print "$data\n"; # prints "elm"
65 135
66=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
67functions. 137functions.
68 138
69 my $src = ' 139 my $src = '
75 } 145 }
76 '; 146 ';
77 147
78 my $prog = $ctx->program_with_source ($src); 148 my $prog = $ctx->program_with_source ($src);
79 149
150 # build croaks on compile errors, so catch it and print the compile errors
80 eval { $prog->build ($dev); 1 } 151 eval { $prog->build ($dev); 1 }
81 or die $prog->build_info ($dev, OpenCL::PROGRAM_BUILD_LOG); 152 or die $prog->build_info ($dev, OpenCL::PROGRAM_BUILD_LOG);
82 153
83 my $kernel = $prog->kernel ("squareit"); 154 my $kernel = $prog->kernel ("squareit");
84 155
85=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.
86 158
87 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);
88 my $output = $ctx->buffer (0, OpenCL::SIZEOF_FLOAT * 5); 160 my $output = $ctx->buffer (0, OpenCL::SIZEOF_FLOAT * 5);
89 161
90 # set buffer 162 # set buffer
96 168
97 # enqueue a synchronous read 169 # enqueue a synchronous read
98 $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);
99 171
100 # print the results: 172 # print the results:
101 say join ", ", unpack "f*", $data; 173 printf "%s\n", join ", ", unpack "f*", $data;
102 174
103=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,
104showing off barriers. 176showing off barriers.
105 177
106 # execute it for all 4 numbers 178 # execute it for all 4 numbers
129 201
130=head1 DOCUMENTATION 202=head1 DOCUMENTATION
131 203
132=head2 BASIC CONVENTIONS 204=head2 BASIC CONVENTIONS
133 205
134This 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
135attempted to make the interface as type-safe as possible and introducing 207I attempted to make the interface as type-safe as possible by introducing
136object syntax where it makes sense. There are a number of important 208object syntax where it makes sense. There are a number of important
137differences between the OpenCL C API and this module: 209differences between the OpenCL C API and this module:
138 210
139=over 4 211=over 4
140 212
148 220
149=item * OpenCL often specifies fixed vector function arguments as short 221=item * OpenCL often specifies fixed vector function arguments as short
150arrays (C<size_t origin[3]>), while this module explicitly expects the 222arrays (C<size_t origin[3]>), while this module explicitly expects the
151components as separate arguments- 223components as separate arguments-
152 224
225=item * Structures are often specified with their components, and returned
226as arrayrefs.
227
153=item * Where possible, the row_pitch value is calculated from the perl 228=item * Where possible, one of the pitch values is calculated from the
154scalar length and need not be specified. 229perl scalar length and need not be specified.
155 230
156=item * When enqueuing commands, the wait list is specified by adding 231=item * When enqueuing commands, the wait list is specified by adding
157extra arguments to the function - everywhere a C<$wait_events...> argument 232extra arguments to the function - anywhere a C<$wait_events...> argument
158is documented this can be any number of event objects. 233is documented this can be any number of event objects.
159 234
160=item * When enqueuing commands, if the enqueue method is called in void 235=item * When enqueuing commands, if the enqueue method is called in void
161context, no event is created. In all other contexts an event is returned 236context, no event is created. In all other contexts an event is returned
162by the method. 237by the method.
165other status is returned the function will throw an exception, so you 240other status is returned the function will throw an exception, so you
166don't normally have to to any error checking. 241don't normally have to to any error checking.
167 242
168=back 243=back
169 244
245=head2 PERL AND OPENCL TYPES
246
247This handy(?) table lists OpenCL types and their perl, PDL and pack/unpack
248format equivalents:
249
250 OpenCL perl PDL pack/unpack
251 char IV - c
252 uchar IV byte C
253 short IV short s
254 ushort IV ushort S
255 int IV long? l
256 uint IV - L
257 long IV longlong q
258 ulong IV - Q
259 float NV float f
260 half IV ushort S
261 double NV double d
262
170=head2 THE OpenCL PACKAGE 263=head2 THE OpenCL PACKAGE
171 264
172=over 4 265=over 4
173 266
174=item $int = OpenCL::errno 267=item $int = OpenCL::errno
175 268
176The 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.
177 271
178=item $str = OpenCL::err2str $errval 272=item $str = OpenCL::err2str $errval
179 273
180Comverts an error value into a human readable string. 274Comverts an error value into a human readable string.
181 275
182=item $str = OpenCL::err2str $enum 276=item $str = OpenCL::enum2str $enum
183 277
184Converts most enum values (inof parameter names, image format constants, 278Converts most enum values (inof parameter names, image format constants,
185object types, addressing and filter modes, command types etc.) into a 279object types, addressing and filter modes, command types etc.) into a
186human readbale string. When confronted with some random integer it can be 280human readbale string. When confronted with some random integer it can be
187very helpful to pass it through this function to maybe get some readable 281very helpful to pass it through this function to maybe get some readable
191 285
192Returns all available OpenCL::Platform objects. 286Returns all available OpenCL::Platform objects.
193 287
194L<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>
195 289
196=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
197 291
198Tries 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.
199 293
200L<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>
201 295
221 315
222=item @devices = $platform->devices ($type = OpenCL::DEVICE_TYPE_ALL) 316=item @devices = $platform->devices ($type = OpenCL::DEVICE_TYPE_ALL)
223 317
224Returns a list of matching OpenCL::Device objects. 318Returns a list of matching OpenCL::Device objects.
225 319
226=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)
227 321
228Tries to create a context. Never worked for me. 322Tries to create a context. Never worked for me, and you need devices explitly anyway.
229 323
230L<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>
231 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
232=back 333=back
233 334
234=head2 THE OpenCL::Device CLASS 335=head2 THE OpenCL::Device CLASS
235 336
236=over 4 337=over 4
239 340
240See C<< $platform->info >> for details. 341See C<< $platform->info >> for details.
241 342
242L<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>
243 344
244=item $ctx = $device->context_simple
245
246Convenience function to create a new OpenCL::Context object.
247
248L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateContext.html>
249
250=back 345=back
251 346
252=head2 THE OpenCL::Context CLASS 347=head2 THE OpenCL::Context CLASS
253 348
254=over 4 349=over 4
257 352
258See C<< $platform->info >> for details. 353See C<< $platform->info >> for details.
259 354
260L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetContextInfo.html> 355L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetContextInfo.html>
261 356
262=item $queue = $ctx->command_queue_simple ($device) 357=item $queue = $ctx->queue ($device, $properties)
263 358
264Convenience function to create a new OpenCL::Queue object from the context and the given device. 359Create a new OpenCL::Queue object from the context and the given device.
265 360
266L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateCommandQueue.html> 361L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateCommandQueue.html>
267 362
268=item $ev = $ctx->user_event 363=item $ev = $ctx->user_event
269 364
551package OpenCL; 646package OpenCL;
552 647
553use common::sense; 648use common::sense;
554 649
555BEGIN { 650BEGIN {
556 our $VERSION = '0.03'; 651 our $VERSION = '0.14';
557 652
558 require XSLoader; 653 require XSLoader;
559 XSLoader::load (__PACKAGE__, $VERSION); 654 XSLoader::load (__PACKAGE__, $VERSION);
560 655
561 @OpenCL::Buffer::ISA = 656 @OpenCL::Buffer::ISA =

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines