1
votes

I'm very new to GPU programming, I'm planning to access GPUs through pyopencl in Python.

Unfortunately there's not much support out there for this topic, before diving deep into it I thought it might be a good idea to ask an expert for their experience.

I'm planning to solve maximum entropy equations on GPU. The way that I'd like to do it is to run the code 1000 times each time taking different inputs.

I'd be grateful if someone could point me in the right direction on whether this is possible at all.

Thank you

1
Running the same code on different inputs is exactly what OpenCL (or Cuda, or pyopenCL) is meant for. What you are trying to do is called Single Instruction Multiple Data (SIMD). There is a lot of support to OpenCL as it is and especially for pyopenCL, wheras getting a good starting point is tricky. I suppose the links from the pyopenCL dokumentation at documen.tician.de/pyopencl and especially the set of slices at github.com/HandsOnOpenCL/Lecture-Slides/releases - Dschoni
Thank you for your comment. Are you aware if Cuda has the same capability as well? - Ali S
Yes it does. Read some documentation on what these languages can do, and try to figure out, which one you need. My idea: If you don't have strong arguments to use CUDA, better use openCL. - Dschoni

1 Answers

2
votes

As others have already commented: Yes (py)OpenCl is the "perfect" tool for this job.

I'll suggest having a look at the examples to get a feeling how everything works. https://github.com/pyopencl/pyopencl/blob/master/examples

Also this slides from the pyOpenCL author are a nice read.

A short example (without imports and added comments from here)

# Create some random test data
a_np = np.random.rand(50000).astype(np.float32)
b_np = np.random.rand(50000).astype(np.float32)

# Select a device
ctx = cl.create_some_context(interactive=True)
queue = cl.CommandQueue(ctx)

# Allocate memory on the device and copy the content of our numpy array    
mf = cl.mem_flags
a_g = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=a_np)
b_g = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=b_np)

# The code running on your device    
prg = cl.Program(ctx, """
__kernel void sum(
    __global const float *a_g, __global const float *b_g, __global float *res_g)
{
  int gid = get_global_id(0);
  res_g[gid] = a_g[gid] + b_g[gid];
}
""").build()

# Allocate the output buffer on the device
res_g = cl.Buffer(ctx, mf.WRITE_ONLY, a_np.nbytes)
# and call the above defined kernel
prg.sum(queue, a_np.shape, None, a_g, b_g, res_g)

# Create a numpy array for the results and copy them from the device
res_np = np.empty_like(a_np)
cl.enqueue_copy(queue, res_np, res_g)