13. OpenCL model evaluator

sasmodels.kernelcl

GPU driver for C kernels

There should be a single GPU environment running on the system. This environment is constructed on the first call to env(), and the same environment is returned on each call.

After retrieving the environment, the next step is to create the kernel. This is done with a call to GpuEnvironment.make_kernel(), which returns the type of data used by the kernel.

Next a GpuData object should be created with the correct kind of data. This data object can be used by multiple kernels, for example, if the target model is a weighted sum of multiple kernels. The data should include any extra evaluation points required to compute the proper data smearing. This need not match the square grid for 2D data if there is an index saying which q points are active.

Together the GpuData, the program, and a device form a GpuKernel. This kernel is used during fitting, receiving new sets of parameters and evaluating them. The output value is stored in an output buffer on the devices, where it can be combined with other structure factors and form factors and have instrumental resolution effects applied.

In order to use OpenCL for your models, you will need OpenCL drivers for your machine. These should be available from your graphics card vendor. Intel provides OpenCL drivers for CPUs as well as their integrated HD graphics chipsets. AMD also provides drivers for Intel CPUs, but as of this writing the performance is lacking compared to the Intel drivers. NVidia combines drivers for CUDA and OpenCL in one package. The result is a bit messy if you have multiple drivers installed. You can see which drivers are available by starting python and running:

import pyopencl as cl cl.create_some_context(interactive=True)

Once you have done that, it will show the available drivers which you can select. It will then tell you that you can use these drivers automatically by setting the SAS_OPENCL environment variable, which is PYOPENCL_CTX equivalent but not conflicting with other pyopnecl programs.

Some graphics cards have multiple devices on the same card. You cannot yet use both of them concurrently to evaluate models, but you can run the program twice using a different device for each session.

OpenCL kernels are compiled when needed by the device driver. Some drivers produce compiler output even when there is no error. You can see the output by setting PYOPENCL_COMPILER_OUTPUT=1. It should be harmless, albeit annoying.

class sasmodels.kernelcl.GpuEnvironment

Bases: object

GPU context, with possibly many devices, and one queue per device.

compile_program(name, source, dtype, fast, timestamp)

Compile the program for the device in the given context.

get_context(dtype)

Return a OpenCL context for the kernels of type dtype.

get_queue(dtype)

Return a command queue for the kernels of type dtype.

has_type(dtype)

Return True if all devices support a given type.

class sasmodels.kernelcl.GpuInput(q_vectors, dtype=dtype('float32'))

Bases: object

Make q data available to the gpu.

q_vectors is a list of q vectors, which will be [q] for 1-D data, and [qx, qy] for 2-D data. Internally, the vectors will be reallocated to get the best performance on OpenCL, which may involve shifting and stretching the array to better match the memory architecture. Additional points will be evaluated with q=1e-3.

dtype is the data type for the q vectors. The data type should be set to match that of the kernel, which is an attribute of GpuProgram. Note that not all kernels support double precision, so even if the program was created for double precision, the GpuProgram.dtype may be single precision.

Call release() when complete. Even if not called directly, the buffer will be released when the data object is freed.

release()

Free the memory.

class sasmodels.kernelcl.GpuKernel(kernel, dtype, model_info, q_vectors)

Bases: sasmodels.kernel.Kernel

Callable SAS kernel.

kernel is the GpuKernel object to call

model_info is the module information

q_vectors is the q vectors at which the kernel should be evaluated

dtype is the kernel precision

The resulting call method takes the pars, a list of values for the fixed parameters to the kernel, and pd_pars, a list of (value,weight) vectors for the polydisperse parameters. cutoff determines the integration limits: any points with combined weight less than cutoff will not be calculated.

Call release() when done with the kernel instance.

release()

Release resources associated with the kernel.

dim = None
dtype = None
info = None
results = None
class sasmodels.kernelcl.GpuModel(source, model_info, dtype=dtype('float32'), fast=False)

Bases: sasmodels.kernel.KernelModel

GPU wrapper for a single model.

source and model_info are the model source and interface as returned from generate.make_source() and generate.make_model_info().

dtype is the desired model precision. Any numpy dtype for single or double precision floats will do, such as ‘f’, ‘float32’ or ‘single’ for single and ‘d’, ‘float64’ or ‘double’ for double. Double precision is an optional extension which may not be available on all devices. Half precision (‘float16’,’half’) may be available on some devices. Fast precision (‘fast’) is a loose version of single precision, indicating that the compiler is allowed to take shortcuts.

make_kernel(q_vectors)
release()

Free the resources associated with the model.

dtype = None
info = None
sasmodels.kernelcl.compile_model(context, source, dtype, fast=False)

Build a model to run on the gpu.

Returns the compiled program and its type. The returned type will be float32 even if the desired type is float64 if any of the devices in the context do not support the cl_khr_fp64 extension.

sasmodels.kernelcl.environment()

Returns a singleton GpuEnvironment.

This provides an OpenCL context and one queue per device.

sasmodels.kernelcl.fix_pyopencl_include()

Monkey patch pyopencl to allow spaces in include file path.

sasmodels.kernelcl.get_warp(kernel, queue)

Return the size of an execution batch for kernel running on queue.

sasmodels.kernelcl.has_type(device, dtype)

Return true if device supports the requested precision.

sasmodels.kernelcl.quote_path(v)

Quote the path if it is not already quoted.

If v starts with ‘-‘, then assume that it is a -I option or similar and do not quote it. This is fragile: -Ipath with space needs to be quoted.