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

Comparing OpenCL/OpenCL.pm (file contents):
Revision 1.7 by root, Wed Nov 16 00:44:41 2011 UTC vs.
Revision 1.18 by root, Thu Nov 17 06:22:29 2011 UTC

8 8
9=head1 DESCRIPTION 9=head1 DESCRIPTION
10 10
11This is an early release which might be useful, but hasn't seen much 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 arrays or structs) and OpenCL::Image objects (think 2d
34or 3d array) 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
57If you are into UML class diagrams, the following diagram might help - if
58not, it will be mildly cobfusing:
59
60 http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/classDiagram.html
61
62Here's a tutorial from AMD (very AMD-centric, too), not sure how useful it
63is, 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
67And 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
70
71=head1 BASIC WORKFLOW
72
73To get something done, you basically have to do this once (refer to the
74examples below for actual code, this is just a high-level description):
75
76Find some platform (e.g. the first one) and some device(s) (e.g. the first
77device of the platform), and create a context from those.
78
79Create program objects from your OpenCL source code, then build (compile)
80the programs for each device you want to run them on.
81
82Create kernel objects for all kernels you want to use (surprisingly, these
83are not device-specific).
84
85Then, to execute stuff, you repeat these steps, possibly resuing or
86sharing some buffers:
87
88Create some input and output buffers from your context. Set these as
89arguments to your kernel.
90
91Enqueue buffer writes to initialise your input buffers (when not
92initialised at creation time).
93
94Enqueue the kernel execution.
95
96Enqueue buffer reads for your output buffer to read results.
97
24=head1 EXAMPLES 98=head1 EXAMPLES
25 99
26=head2 Enumerate all devices and get contexts for them. 100=head2 Enumerate all devices and get contexts for them.
27 101
102Best run this once to get a feel for the platforms and devices in your
103system.
104
28 for my $platform (OpenCL::platforms) { 105 for my $platform (OpenCL::platforms) {
29 warn $platform->info (OpenCL::PLATFORM_NAME); 106 printf "platform: %s\n", $platform->info (OpenCL::PLATFORM_NAME);
30 warn $platform->info (OpenCL::PLATFORM_EXTENSIONS); 107 printf "extensions: %s\n", $platform->info (OpenCL::PLATFORM_EXTENSIONS);
31 for my $device ($platform->devices) { 108 for my $device ($platform->devices) {
32 warn $device->info (OpenCL::DEVICE_NAME); 109 printf "+ device: %s\n", $device->info (OpenCL::DEVICE_NAME);
33 my $ctx = $device->context_simple; 110 my $ctx = $device->context;
34 # do stuff 111 # do stuff
35 } 112 }
36 } 113 }
37 114
38=head2 Get a useful context and a command queue. 115=head2 Get a useful context and a command queue.
39 116
40 my $dev = ((OpenCL::platforms)[0]->devices)[0]; 117This is a useful boilerplate for any OpenCL program that only wants to use
41 my $ctx = $dev->context_simple; 118one device,
42 my $queue = $ctx->command_queue_simple ($dev); 119
120 my ($platform) = OpenCL::platforms; # find first platform
121 my ($dev) = $platform->devices; # find first device of platform
122 my $ctx = $platform->context (undef, [$dev]); # create context out of those
123 my $queue = $ctx->queue ($dev); # create a command queue for the device
43 124
44=head2 Print all supported image formats of a context. 125=head2 Print all supported image formats of a context.
45 126
127Best run this once for your context, to see whats available and how to
128gather information.
129
46 for my $type (OpenCL::MEM_OBJECT_IMAGE2D, OpenCL::MEM_OBJECT_IMAGE3D) { 130 for my $type (OpenCL::MEM_OBJECT_IMAGE2D, OpenCL::MEM_OBJECT_IMAGE3D) {
47 say "supported image formats for ", OpenCL::enum2str $type; 131 print "supported image formats for ", OpenCL::enum2str $type, "\n";
48 132
49 for my $f ($ctx->supported_image_formats (0, $type)) { 133 for my $f ($ctx->supported_image_formats (0, $type)) {
50 printf " %-10s %-20s\n", OpenCL::enum2str $f->[0], OpenCL::enum2str $f->[1]; 134 printf " %-10s %-20s\n", OpenCL::enum2str $f->[0], OpenCL::enum2str $f->[1];
51 } 135 }
52 } 136 }
55then asynchronously. 139then asynchronously.
56 140
57 my $buf = $ctx->buffer_sv (OpenCL::MEM_COPY_HOST_PTR, "helmut"); 141 my $buf = $ctx->buffer_sv (OpenCL::MEM_COPY_HOST_PTR, "helmut");
58 142
59 $queue->enqueue_read_buffer ($buf, 1, 1, 3, my $data); 143 $queue->enqueue_read_buffer ($buf, 1, 1, 3, my $data);
60 warn $data; 144 print "$data\n";
61 145
62 my $ev = $queue->enqueue_read_buffer ($buf, 0, 1, 3, my $data); 146 my $ev = $queue->enqueue_read_buffer ($buf, 0, 1, 3, my $data);
63 $ev->wait; 147 $ev->wait;
64 warn $data; 148 print "$data\n"; # prints "elm"
65 149
66=head2 Create and build a program, then create a kernel out of one of its 150=head2 Create and build a program, then create a kernel out of one of its
67functions. 151functions.
68 152
69 my $src = ' 153 my $src = '
70 __kernel void 154 __kernel void
71 squareit (__global float *input, __global float *output) 155 squareit (__global float *input, __global float *output)
72 { 156 {
73 size_t id = get_global_id (0); 157 $id = get_global_id (0);
74 output [id] = input [id] * input [id]; 158 output [id] = input [id] * input [id];
75 } 159 }
76 '; 160 ';
77 161
78 my $prog = $ctx->program_with_source ($src); 162 my $prog = $ctx->program_with_source ($src);
79 163
164 # build croaks on compile errors, so catch it and print the compile errors
80 eval { $prog->build ($dev); 1 } 165 eval { $prog->build ($dev); 1 }
81 or die $prog->build_info ($dev, OpenCL::PROGRAM_BUILD_LOG); 166 or die $prog->build_info ($dev, OpenCL::PROGRAM_BUILD_LOG);
82 167
83 my $kernel = $prog->kernel ("squareit"); 168 my $kernel = $prog->kernel ("squareit");
84 169
85=head2 Create some input and output float buffers, then call squareit on them. 170=head2 Create some input and output float buffers, then call the
171'squareit' kernel on them.
86 172
87 my $input = $ctx->buffer_sv (OpenCL::MEM_COPY_HOST_PTR, pack "f*", 1, 2, 3, 4.5); 173 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); 174 my $output = $ctx->buffer (0, OpenCL::SIZEOF_FLOAT * 5);
89 175
90 # set buffer 176 # set buffer
96 182
97 # enqueue a synchronous read 183 # enqueue a synchronous read
98 $queue->enqueue_read_buffer ($output, 1, 0, OpenCL::SIZEOF_FLOAT * 4, my $data); 184 $queue->enqueue_read_buffer ($output, 1, 0, OpenCL::SIZEOF_FLOAT * 4, my $data);
99 185
100 # print the results: 186 # print the results:
101 say join ", ", unpack "f*", $data; 187 printf "%s\n", join ", ", unpack "f*", $data;
102 188
103=head2 The same enqueue operations as before, but assuming an out-of-order queue, 189=head2 The same enqueue operations as before, but assuming an out-of-order queue,
104showing off barriers. 190showing off barriers.
105 191
106 # execute it for all 4 numbers 192 # execute it for all 4 numbers
129 215
130=head1 DOCUMENTATION 216=head1 DOCUMENTATION
131 217
132=head2 BASIC CONVENTIONS 218=head2 BASIC CONVENTIONS
133 219
134This is not a 1:1 C-style translation of OpenCL to Perl - instead I 220This 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 221I attempted to make the interface as type-safe as possible by introducing
136object syntax where it makes sense. There are a number of important 222object syntax where it makes sense. There are a number of important
137differences between the OpenCL C API and this module: 223differences between the OpenCL C API and this module:
138 224
139=over 4 225=over 4
140 226
145=item * OpenCL uses CamelCase for function names (C<clGetPlatformInfo>), 231=item * OpenCL uses CamelCase for function names (C<clGetPlatformInfo>),
146while this module uses underscores as word separator and often leaves out 232while this module uses underscores as word separator and often leaves out
147prefixes (C<< $platform->info >>). 233prefixes (C<< $platform->info >>).
148 234
149=item * OpenCL often specifies fixed vector function arguments as short 235=item * OpenCL often specifies fixed vector function arguments as short
150arrays (C<size_t origin[3]>), while this module explicitly expects the 236arrays (C<$origin[3]>), while this module explicitly expects the
151components as separate arguments- 237components as separate arguments-
152 238
239=item * Structures are often specified with their components, and returned
240as arrayrefs.
241
153=item * Where possible, the row_pitch value is calculated from the perl 242=item * Where possible, one of the pitch values is calculated from the
154scalar length and need not be specified. 243perl scalar length and need not be specified.
155 244
156=item * When enqueuing commands, the wait list is specified by adding 245=item * When enqueuing commands, the wait list is specified by adding
157extra arguments to the function - everywhere a C<$wait_events...> argument 246extra arguments to the function - anywhere a C<$wait_events...> argument
158is documented this can be any number of event objects. 247is documented this can be any number of event objects.
159 248
160=item * When enqueuing commands, if the enqueue method is called in void 249=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 250context, no event is created. In all other contexts an event is returned
162by the method. 251by the method.
167 256
168=back 257=back
169 258
170=head2 PERL AND OPENCL TYPES 259=head2 PERL AND OPENCL TYPES
171 260
172This handy(?) table lists OpenCL types and their perl and pack/unpack 261This handy(?) table lists OpenCL types and their perl, PDL and pack/unpack
173format equivalents: 262format equivalents:
174 263
175 OpenCL perl pack/unpack 264 OpenCL perl PDL pack/unpack
176 char IV c 265 char IV - c
177 uchar IV C 266 uchar IV byte C
178 short IV s 267 short IV short s
179 ushort IV S 268 ushort IV ushort S
180 int IV l 269 int IV long? l
181 uint IV L 270 uint IV - L
182 long IV q 271 long IV longlong q
183 ulong IV Q 272 ulong IV - Q
184 float NV f 273 float NV float f
185 half IV S 274 half IV ushort S
186 double NV d 275 double NV double d
187 276
188=head2 THE OpenCL PACKAGE 277=head2 THE OpenCL PACKAGE
189 278
190=over 4 279=over 4
191 280
192=item $int = OpenCL::errno 281=item $int = OpenCL::errno
193 282
194The last error returned by a function - it's only changed on errors. 283The last error returned by a function - it's only valid after an error occured
284and before calling another OpenCL function.
195 285
196=item $str = OpenCL::err2str $errval 286=item $str = OpenCL::err2str $errval
197 287
198Comverts an error value into a human readable string. 288Comverts an error value into a human readable string.
199 289
200=item $str = OpenCL::err2str $enum 290=item $str = OpenCL::enum2str $enum
201 291
202Converts most enum values (inof parameter names, image format constants, 292Converts most enum values (inof parameter names, image format constants,
203object types, addressing and filter modes, command types etc.) into a 293object types, addressing and filter modes, command types etc.) into a
204human readbale string. When confronted with some random integer it can be 294human readbale string. When confronted with some random integer it can be
205very helpful to pass it through this function to maybe get some readable 295very helpful to pass it through this function to maybe get some readable
209 299
210Returns all available OpenCL::Platform objects. 300Returns all available OpenCL::Platform objects.
211 301
212L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetPlatformIDs.html> 302L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetPlatformIDs.html>
213 303
214=item $ctx = OpenCL::context_from_type_simple $type = OpenCL::DEVICE_TYPE_DEFAULT 304=item $ctx = OpenCL::context_from_type $properties, $type = OpenCL::DEVICE_TYPE_DEFAULT, $notify = undef
215 305
216Tries to create a context from a default device and platform - never worked for me. 306Tries to create a context from a default device and platform - never worked for me.
217 307
218L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateContextFromType.html> 308L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateContextFromType.html>
219 309
239 329
240=item @devices = $platform->devices ($type = OpenCL::DEVICE_TYPE_ALL) 330=item @devices = $platform->devices ($type = OpenCL::DEVICE_TYPE_ALL)
241 331
242Returns a list of matching OpenCL::Device objects. 332Returns a list of matching OpenCL::Device objects.
243 333
244=item $ctx = $platform->context_from_type_simple ($type = OpenCL::DEVICE_TYPE_DEFAULT) 334=item $ctx = $platform->context_from_type ($properties, $type = OpenCL::DEVICE_TYPE_DEFAULT, $notify = undef)
245 335
246Tries to create a context. Never worked for me. 336Tries to create a context. Never worked for me, and you need devices explitly anyway.
247 337
248L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateContextFromType.html> 338L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateContextFromType.html>
249 339
340=item $ctx = $device->context ($properties = undef, @$devices, $notify = undef)
341
342Create a new OpenCL::Context object using the given device object(s)- a
343CL_CONTEXT_PLATFORM property is supplied automatically.
344
345L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateContext.html>
346
250=back 347=back
251 348
252=head2 THE OpenCL::Device CLASS 349=head2 THE OpenCL::Device CLASS
253 350
254=over 4 351=over 4
257 354
258See C<< $platform->info >> for details. 355See C<< $platform->info >> for details.
259 356
260L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetDeviceInfo.html> 357L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetDeviceInfo.html>
261 358
262=item $ctx = $device->context_simple
263
264Convenience function to create a new OpenCL::Context object.
265
266L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateContext.html>
267
268=back 359=back
269 360
270=head2 THE OpenCL::Context CLASS 361=head2 THE OpenCL::Context CLASS
271 362
272=over 4 363=over 4
275 366
276See C<< $platform->info >> for details. 367See C<< $platform->info >> for details.
277 368
278L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetContextInfo.html> 369L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetContextInfo.html>
279 370
280=item $queue = $ctx->command_queue_simple ($device) 371=item $queue = $ctx->queue ($device, $properties)
281 372
282Convenience function to create a new OpenCL::Queue object from the context and the given device. 373Create a new OpenCL::Queue object from the context and the given device.
283 374
284L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateCommandQueue.html> 375L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateCommandQueue.html>
285 376
286=item $ev = $ctx->user_event 377=item $ev = $ctx->user_event
287 378
297 388
298=item $buf = $ctx->buffer_sv ($flags, $data) 389=item $buf = $ctx->buffer_sv ($flags, $data)
299 390
300Creates a new OpenCL::Buffer object and initialise it with the given data values. 391Creates a new OpenCL::Buffer object and initialise it with the given data values.
301 392
302=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)
303 394
304Creates a new OpenCL::Image2D object and optionally initialises it with the given data values. 395Creates a new OpenCL::Image2D object and optionally initialises it with the given data values.
305 396
306L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateImage2D.html> 397L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateImage2D.html>
307 398
308=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)
309 400
310Creates a new OpenCL::Image3D object and optionally initialises it with the given data values. 401Creates a new OpenCL::Image3D object and optionally initialises it with the given data values.
311 402
312L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateImage3D.html> 403L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateImage3D.html>
313 404
376 467
377=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...)
378 469
379L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueReadImage.html> 470L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueReadImage.html>
380 471
381=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...)
382 473
383L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueWriteImage.html> 474L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueWriteImage.html>
384 475
385=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...)
386 477
387Yeah. 478Yeah.
388 479
389L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyBufferRect.html> 480L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyBufferRect.html>
390 481
391=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...)
392 483
393L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyBufferToImage.html>. 484L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyBufferToImage.html>.
394 485
395=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...)
396 487
397L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyImage.html> 488L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyImage.html>
398 489
399=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...)
400 491
401L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyImageToBuffer.html> 492L<http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clEnqueueCopyImageToBuffer.html>
402 493
403=item $ev = $queue->enqueue_task ($kernel, $wait_events...) 494=item $ev = $queue->enqueue_task ($kernel, $wait_events...)
404 495
569package OpenCL; 660package OpenCL;
570 661
571use common::sense; 662use common::sense;
572 663
573BEGIN { 664BEGIN {
574 our $VERSION = '0.03'; 665 our $VERSION = '0.15';
575 666
576 require XSLoader; 667 require XSLoader;
577 XSLoader::load (__PACKAGE__, $VERSION); 668 XSLoader::load (__PACKAGE__, $VERSION);
578 669
579 @OpenCL::Buffer::ISA = 670 @OpenCL::Buffer::ISA =

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines