First you need to find one or more OpenCL::Platforms (kind of like vendors) - usually there is only one.

Each platform gives you access to a number of OpenCL::Device objects, e.g. your graphics card.

From a platform and some device(s), you create an OpenCL::Context, which is a very central object in OpenCL: Once you have a context you can create most other objects:

OpenCL::Program objects, which store source code and, after building for a specific device ("compiling and linking"), also binary programs. For each kernel function in a program you can then create an OpenCL::Kernel object which represents basically a function call with argument values.

OpenCL::Sampler objects, which are kind of like texture filter modes in OpenGL.

OpenCL::Queue objects - command queues, which allow you to submit memory reads, writes and copies, as well as kernel calls to your devices. They also offer a variety of methods to synchronise request execution, for example with barriers or OpenCL::Event objects.

This is not a one-to-one C-style translation of OpenCL to Perl - instead I attempted to make the interface as type-safe as possible by introducing object syntax where it makes sense. There are a number of important differences between the OpenCL C API and this module:

Object lifetime managament is automatic - there is no need to free objects explicitly (clReleaseXXX), the release function is called automatically once all Perl references to it go away.

Structures are often specified by flattening out their components as with short vectors, and returned as arrayrefs.

When enqueuing commands, the wait list is specified by adding extra arguments to the function - anywhere a $wait_events... argument is documented this can be any number of event objects. As an extsnion implemented by this module, undef values will be ignored in the event list.

When enqueuing commands, if the enqueue method is called in void context, no event is created. In all other contexts an event is returned by the method.

This module expects all functions to return OpenCL::SUCCESS. If any other status is returned the function will throw an exception, so you don't normally have to to any error checking.

All CL_xxx constants that this module supports are always available in the OpenCL namespace as OpenCL::xxx (i.e. without the CL_ prefix). Constants which are not defined in the header files used during compilation, or otherwise are not available, will have the value 0 (in some cases, this will make them indistinguishable from real constants, sorry).

This module supports both OpenCL version 1.1 and 1.2, although the OpenCL 1.2 interface hasn't been tested much for lack of availability of an actual implementation.

Every function or method in this manual page that interfaces to a particular OpenCL function has a link to the its C manual page.

If the link contains a 1.1, then this function is an OpenCL 1.1 function. Most but not all also exist in OpenCL 1.2, and this module tries to emulate the missing ones for you, when told to do so at compiletime. You can check whether a function was removed in OpenCL 1.2 by replacing the 1.1 component in the URL by 1.2.

If the link contains a 1.2, then this is a OpenCL 1.2-only function. Even if the module was compiled with OpenCL 1.2 header files and has an 1.2 OpenCL library, calling such a function on a platform that doesn't implement 1.2 causes undefined behaviour, usually a crash (But this is not guaranteed).

You can find out whether this module was compiled to prefer 1.1 functionality by ooking at OpenCL::PREFER_1_1 - if it is true, then 1.1 functions generally are implemented using 1.1 OpenCL functions. If it is false, then 1.1 functions missing from 1.2 are emulated by calling 1.2 fucntions.

This is a somewhat sorry state of affairs, but the Khronos group choose to make every release of OpenCL source and binary incompatible with previous releases.

Due to the sad state that OpenGL support is in in Perl (mostly the OpenGL module, which has little to no documentation and has little to no support for glX), this module, as a special extension, treats context creation properties OpenCL::GLX_DISPLAY_KHR and OpenCL::GL_CONTEXT_KHR specially: If either or both of these are undef, then the OpenCL module tries to dynamically resolve glXGetCurrentDisplay and glXGetCurrentContext, call these functions and use their return values instead.

For this to work, the OpenGL library must be loaded, a GLX context must have been created and be made current, and dlsym must be available and capable of finding the function via RTLD_DEFAULT.

OpenCL can generate a number of (potentially) asynchronous events, for example, after compiling a program, to signal a context-related error or, perhaps most important, to signal completion of queued jobs (by setting callbacks on OpenCL::Event objects).

The OpenCL module converts all these callbacks into events - you can still register callbacks, but they are not executed when your OpenCL implementation calls the actual callback, but only later. Therefore, none of the limitations of OpenCL callbacks apply to the perl implementation: it is perfectly safe to make blocking operations from event callbacks, and enqueued operations don't need to be flushed.

To facilitate this, this module maintains an event queue - each time an asynchronous event happens, it is queued, and perl will be interrupted. This is implemented via the Async::Interrupt module. In addition, this module has AnyEvent support, so it can seamlessly integrate itself into many event loops.

Since Async::Interrupt is a bit hard to understand, here are some case examples:

This module automatically registers a watcher that invokes all outstanding event callbacks when AnyEvent is initialised (and block asynchronous interruptions). Using this mode of operations is the safest and most recommended one.

To use this, simply use AnyEvent and this module normally, make sure you have an event loop running:

Note that this module will not initialise AnyEvent for you. Before AnyEvent is initialised, the module will asynchronously interrupt perl instead. To avoid any surprises, it's best to explicitly initialise AnyEvent.

You can temporarily enable asynchronous interruptions (see next paragraph) by calling $OpenCL::INTERRUPT-unblock> and disable them again by calling $OpenCL::INTERRUPT-block>.

This mode is the default unless AnyEvent is loaded and initialised. In this mode, OpenCL asynchronously interrupts a running perl program. The emphasis is on both asynchronously and running here.

Asynchronously means that perl might execute your callbacks at any time. For example, in the following code (THAT YOU SHOULD NOT COPY), the until loop following the marker call will be interrupted by the callback:

The reason why you shouldn't blindly copy the above code is that busy waiting is a really really bad thing, and really really bad for performance.

While at first this asynchronous business might look exciting, it can be really hard, because you need to be prepared for the callback code to be executed at any time, which limits the amount of things the callback code can do safely.

This can be mitigated somewhat by using $OpenCL::INTERRUPT->scope_block (see the Async::Interrupt documentation for details).

The other problem is that your program must be actively running to be interrupted. When you calculate stuff, your program is running. When you hang in some C functions or other block execution (by calling sleep, select, running an event loop and so on), your program is waiting, not running.

One way around that would be to attach a read watcher to your event loop, listening for events on $OpenCL::INTERRUPT->pipe_fileno, using a dummy callback (sub { }) to temporarily execute some perl code.

That is then awfully close to using the built-in AnyEvent support above, though, so consider that one instead.

Converts most enum values (of parameter names, image format constants, object types, addressing and filter modes, command types etc.) into a human readable string. When confronted with some random integer it can be very helpful to pass it through this function to maybe get some readable string out of it.

OpenCL objects are represented by pointers or integers on the C level. If you want to interface to an OpenCL object directly on the C level, then you need this value, which is returned by this method. You should use an IV type in your code and cast that to the correct type.

An OpenCL::Queue represents an execution queue for OpenCL. You execute requests by calling their respective method and waiting for it to complete in some way.

Most methods that enqueue some request return an event object that can be used to wait for completion (optionally using a callback), unless the method is called in void context, in which case no event object is created.

They also allow you to specify any number of other event objects that this request has to wait for before it starts executing, by simply passing the event objects as extra parameters to the enqueue methods. To simplify program design, this module ignores any undef values in the list of events. This makes it possible to code operations such as this, without having to put a valid event object into $event first:

$event = $queue->xxx (..., $event);

Queues execute in-order by default, without any parallelism, so in most cases (i.e. you use only one queue) it's not necessary to wait for or create event objects, althoguh an our of order queue is often a bit faster.

Fills the given image area with the given rgba colour components. The components are normally floating point values between 0 and 1, except when the image channel data type is a signe dor unsigned unnormalised format, in which case the range is determined by the format.

\@global_work_size must be specified as a reference to an array of integers specifying the work sizes (element counts).

\@global_work_offset must be either undef (in which case all offsets are 0), or a reference to an array of work offsets, with the same number of elements as \@global_work_size.

\@local_work_size must be either undef (in which case the implementation is supposed to choose good local work sizes), or a reference to an array of local work sizes, with the same number of elements as \@global_work_size.

OpenCL allows you to map buffers and images to host memory (read: perl scalars). This is done much like reading or copying a buffer, by enqueuing a map or unmap operation on the command queue.

The map operations return an OpenCL::Mapped object - see "THE OpenCL::Mapped CLASS" section for details on what to do with these objects.

The object will be unmapped automatically when the mapped object is destroyed (you can use a barrier to make sure the unmap has finished, before using the buffer in a kernel), but you can also enqueue an unmap operation manually.

Example: map an image (with OpenCL::UNSIGNED_INT8 channel type) and set the first channel of the leftmost column to 5, then explicitly unmap it. You are not necessarily meant to do it this way, this example just shows you the accessors to use :)

Tries to build the program with the given options. See also the $ctx-build> convenience function.

If a callback is specified, then it will be called when compilation is finished. Note that many OpenCL implementations block your program while compiling whether you use a callback or not. See build_async if you want to make sure the build is done in the background.

Note that some OpenCL implementations act up badly, and don't call the callback in some error cases (but call it in others). This implementation assumes the callback will always be called, and leaks memory if this is not so. So best make sure you don't pass in invalid values.

Some implementations fail with OpenCL::INVALID_BINARY when the compilation state is successful but some later stage fails.

Sets the arguments of a kernel. Since OpenCL 1.1 doesn't have a generic way to set arguments (and with OpenCL 1.2 it might be rather slow), you need to specify a format argument, much as with printf, to tell OpenCL what type of argument it is.

This is a family of methods to set the kernel argument with the number $index to the give $value.

Chars and integers (including the half type) are specified as integers, float and double as floating point values, memory/buffer/image must be an object of that type or undef, local-memory arguments are set by specifying the size, and sampler and event must be objects of that type.

Note that set_memory works for all memory objects (all types of buffers and images) - the main purpose of the more specific set_TYPE functions is type checking.

Setting an argument for a kernel does NOT keep a reference to the object - for example, if you set an argument to some image object, free the image, and call the kernel, you will run into undefined behaviour.

This class represents objects mapped into host memory. They are represented by a blessed string scalar. The string data is the mapped memory area, that is, if you read or write it, then the mapped object is accessed directly.

You must only ever use operations that modify the string in-place - for example, a substr that doesn't change the length, or maybe a regex that doesn't change the length. Any other operation might cause the data to be copied.

When the object is destroyed it will enqueue an implicit unmap operation on the queue that was used to create it.

Keep in mind that you need to unmap (or destroy) mapped objects before OpenCL sees the changes, even if some implementations don't need this sometimes.

Example, replace the first two floats in the mapped buffer by 1 and 2.

Return the event object associated with the mapped object. Initially, this will be the event object created when mapping the object, and after an unmap, this will be the event object that the unmap operation created.