2016-10-27 7 views
1

私はPyOpenCLを通してOpenCLを学び始めています。私はいくつかのチュートリアルを続けてきました。私はスクリプトhereに取り組んでいます。プログラムはエラーなく実行されますが、配列の合計は正しくありません。ここでは正確なコードは次のとおりです。PyOpenCLプログラムが予期した出力を返さない

# Use OpenCL To Add Two Random Arrays (This Way Shows Details) 

import pyopencl as cl # Import the OpenCL GPU computing API 
import numpy as np # Import Np number tools 

platform = cl.get_platforms()[0] # Select the first platform [0] 
for device in platform.get_devices(): 
    print device 
device = platform.get_devices()[2] # Select the first device on this platform [0] 
context = cl.Context([device]) # Create a context with your device 
queue = cl.CommandQueue(context) # Create a command queue with your context 

np_a = np.random.rand(5).astype(np.float32) # Create a random np array 
np_b = np.random.rand(5).astype(np.float32) # Create a random np array 
np_c = np.empty_like(np_a) # Create an empty destination array 

cl_a = cl.Buffer(context, cl.mem_flags.COPY_HOST_PTR, hostbuf=np_a) 
cl_b = cl.Buffer(context, cl.mem_flags.COPY_HOST_PTR, hostbuf=np_b) 
cl_c = cl.Buffer(context, cl.mem_flags.WRITE_ONLY, np_c.nbytes) 
# Create three buffers (plans for areas of memory on the device) 

kernel = \ 
""" 
__kernel void sum(__global float* a, __global float* b, __global float* c) 
{ 
    int i = get_global_id(0); 
    c[i] = a[i] + b[i]; 
} 
""" # Create a kernel (a string containing C-like OpenCL device code) 

program = cl.Program(context, kernel).build() 
# Compile the kernel code into an executable OpenCL program 

program.sum(queue, np_a.shape, None, cl_a, cl_b, cl_c) 
# Enqueue the program for execution, causing data to be copied to the device 
# - queue: the command queue the program will be sent to 
# - np_a.shape: a tuple of the arrays' dimensions 
# - cl_a, cl_b, cl_c: the memory spaces this program deals with 
queue.finish() 
np_arrays = [np_a, np_b, np_c] 
cl_arrays = [cl_a, cl_b, cl_c] 

for x in range(3): 
    cl.enqueue_copy(queue, cl_arrays[x], np_arrays[x]) 

# Copy the data for array c back to the host 

arrd = {"a":np_a, "b":np_b, "c":np_c} 

for k in arrd: 
    print k + ": ", arrd[k] 


# Print all three host arrays, to show sum() worked 

そして、出力:ここで何が起こっているのかについての

<pyopencl.Device 'Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz' on 'Apple' at 0xffffffff> 
<pyopencl.Device 'Iris Pro' on 'Apple' at 0x1024500> 
<pyopencl.Device 'AMD Radeon R9 M370X Compute Engine' on 'Apple' at 0x1021c00> 
a: [ 0.44930401 0.77514887 0.28574091 0.24021916 0.3193087 ] 
c: [ 0.0583559 0.85157514 0.80443901 0.09400933 0.87276274] 
b: [ 0.81869799 0.49566364 0.85423696 0.68896079 0.95608395] 

私の推測では、データが適切にホストとデバイスが、カーネルのISN間でコピーされていることです実行されていない。このチュートリアルや他のチュートリアルから理解できる限り、コードはカーネルを実行するのに十分なはずです。カーネルを起動するのに必要な他の呼び出しがありますか?私は正確にこの例で使用しているPyOpenCLのバージョンはわかりませんが、私は2016.2からconda-forgeをMac OS X上で実行しています。

答えて

2

間違ったパラメータの順序でenqueue_copyを呼び出しました。 あなたはそれを呼び出す必要があります:あなたがホスト上に作成しているので、一方

cl.enqueue_copy(queue, np_arrays[x], cl_arrays[x]) 

をあなたは、入力配列をバックコピーする必要はありません。

関連する問題