Many projects need similar basic linear algebra operations, but essentially operate in their own OpenCL context. To provide the functionality and convenience of ViennaCL to such existing projects, existing contexts can be passed to ViennaCL and memory objects can be wrapped into the basic linear algebra types vector
, matrix
, or compressed_matrix
. This chapter is devoted to the description of the necessary steps to use ViennaCL on contexts provided by the library user.
examples/tutorial/custom-contexts.cpp
ViennaCL is able to handle an arbitrary number of contexts, which are identified by a key value of type long
. By default, ViennaCL operates on the context identified by 0
, unless the user switches the context, cf. Configuring OpenCL Contexts and Devices.
According to the OpenCL standard, a context contains devices and queues for each device. Thus, it is assumed in the following that the user has successfully created a context with one or more devices and one or more queues per device.
In the case that the context contains only one device my_device
and one queue my_queue
, the context can be passed to ViennaCL with the code
If a context ID other than 0
, say, id
is used, the user-defined context has to be selected using
It is also possible to provide a context with several devices and multiple queues per device. To do so, the device IDs have to be stored in a STL vector and the queues in a STL map:
It is not necessary to pass all devices and queues created within a particular context to ViennaCL, only those which ViennaCL should use have to be passed. ViennaCL will by default use the first queue on each device. The user has to care for appropriate synchronization between different queues.
clReleaseContext()
as usual for destroying the context.Now as the user provided context is supplied to ViennaCL, user-created memory objects have to be wrapped into ViennaCL data-types in order to use the full functionality. Typically, one of the types scalar
, vector
, matrix
and compressed_matrix
are used:
The following has to be emphasized:
clRetainMem()
is called once for the provided memory handle. Similarly, clReleaseMem()
is called as soon as the memory is not used any longer.