import pyopencl as cl
import numpy as np
import numpy.linalg as la
a = np.random.rand(1024, 1024).astype(np.float32)
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
This notebook demonstrates working with PyOpenCL's arrays, which provide a friendlier (and more numpy-like) face on OpenCL's buffers. This is the module where they live:
import pyopencl.array
Now transfer to a device array.
a_dev = cl.array.to_device(queue, a)
Works like a numpy array! (shape
, dtype
, strides
)
a_dev.shape
a_dev.dtype
a_dev.strides
Goal: Wanted to double all entries.
twice_a_dev = 2*a_dev
Easy to turn back into a numpy
array.
twice_a = twice_a_dev.get()
Check!
#check
print(la.norm(twice_a - 2*a))
Can just print
the array, too.
print(twice_a_dev)
Easy to evaluate arbitrary (elementwise) expressions.
import pyopencl.clmath
cl.clmath.sin(a_dev)**2 - (1./a_dev) + 5
Can still do everything manually though!
prg = cl.Program(ctx, """
__kernel void twice(__global float *a)
{
int gid0 = get_global_id(0);
int gid1 = get_global_id(1);
int i = gid1 * 1024 + gid0;
a[i] = 2*a[i];
}
""").build()
twice = prg.twice
twice(queue, a_dev.shape, None, a_dev.data)
print(la.norm(a_dev.get() - 2*a), la.norm(a))
But the hardcoded 1024 is ... inelegant. So fix that!
(Also with arg dtype setting
.)