2016-10-13 12 views
-3

Есть много примеров PyopenCL по выполнению арифметических операций над векторами размером 4. Если мне нужно умножить 100 целых чисел на 100 целых чисел одновременно, используя AMD GPU на Mac через PyOpenCL, может кто-нибудь предоставить и объяснить код, пожалуйста? Поскольку максимальный размер вектора может быть 16, я хотел бы знать, как я могу попросить GPU выполнить эту операцию, которая требует обработки более 16 целых чисел параллельно.Как умножить 100 целых чисел на другие 100 целых чисел параллельно на графическом процессоре с использованием PyOpenCL?

У меня есть GPU AMD D500 firepro. Выполняет ли каждый рабочий элемент (нить) задачу независимо, если да, то есть 24 вычислительных блока, и каждый вычислительный блок имеет 255 рабочих элементов для одного измерения и [255,255,255] для трех измерений. Означает ли это, что мой GPU имеет 6120 независимых рабочих элементов?

+0

Перед тем, как погрузиться в его использование с API, вам обязательно нужно некоторое чтение на модели памяти OpenCL. – Dschoni

ответ

0

Я сделал короткий пример для ввода в виде умножения двух одномерных целых массивов. Обратите внимание, что если вы планируете умножать только 100 значений, это будет не так быстро, как это делать на CPU, так как у вас много накладных расходов при копировании данных и т. Д.

import pyopencl as cl 
import numpy as np 

#this is compiled by the GPU driver and will be executed on the GPU 
kernelsource = """ 
__kernel void multInt( __global int* res, 
         __global int* a, 
         __global int* b){ 
    int i = get_global_id(0); 
    int N = get_global_size(0); //this is the dimension given as second argument in the kernel execution 
    res[i] = a[i] * b[i]; 
} 
""" 

device = cl.get_platforms()[0].get_devices()[0] 
context = cl.Context([device]) 
program = cl.Program(context, kernelsource).build() 
queue = cl.CommandQueue(context) 

#preparing input data in numpy arrays in local memory (i.e. accessible by the CPU) 
N = 100 
a_local = np.array(range(N)).astype(np.int32) 
b_local = (np.ones(N)*10).astype(np.int32) 

#preparing result buffer in local memory 
res_local = np.zeros(N).astype(np.int32) 

#copy input data to GPU-memory 
a_buf = cl.Buffer(context, cl.mem_flags.READ_ONLY | cl.mem_flags.COPY_HOST_PTR, hostbuf=a_local) 
b_buf = cl.Buffer(context, cl.mem_flags.READ_ONLY | cl.mem_flags.COPY_HOST_PTR, hostbuf=b_local) 
#prepare result buffer in GPU-memory 
res_buf = cl.Buffer(context, cl.mem_flags.WRITE_ONLY, res_local.nbytes) 
#execute previously compiled kernel on GPU 
program.multInt(queue,(N,), None, res_buf, a_buf, b_buf) 
#copy the result from GPU-memory to CPU-memory 
cl.enqueue_copy(queue, res_local, res_buf) 

print("result: {}".format(res_local)) 

Для документирования PyOpenCL: После того, как вы поняли принцип работы GPGPU программирования и концепций программирования OpenCL, PyOpenCL довольно прост.