2017-08-09 4 views
1

Ich versuche, numpy Array zum Kernel als Array von opencl Vektor übergeben. (numpy Array von np.int32 -> int3 *) Aber das Ergebnis scheint verwildert. Es wird sehr geschätzt werden, wenn jemand erklären, warum es passiert ist.Übergeben Array von Vektor in pyOpencl

Vielen Dank im Voraus.

Der Quellcode:

import pyopencl as cl 
import numpy as np 

platforms = cl.get_platforms() 
ctx = cl.Context(dev_type=cl.device_type.GPU, properties=[(cl.context_properties.PLATFORM, platforms[0])]) 
queue = cl.CommandQueue(ctx) 

rowcnt = 3 
ipt = np.linspace(1, rowcnt * 3, num=rowcnt * 3, dtype=np.int32) 
rst = np.ones((rowcnt * 3), dtype=np.int32) 

mf = cl.mem_flags 
iptbuf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=ipt) 
rstbuf = cl.Buffer(ctx, mf.WRITE_ONLY, rst.nbytes) 

src = ''' 
__kernel void test(__global int3* ipt, __global int* rst) { 
    int idx = get_global_id(0); 
    rst[idx * 3] = ipt[idx].x; 
    rst[idx * 3 + 1] = ipt[idx].y; 
    rst[idx * 3 + 2] = ipt[idx].z; 
} 
''' 

prg = cl.Program(ctx, src).build() 
prg.test(queue, (rowcnt,), None, iptbuf, rstbuf) 

cl.enqueue_copy(queue, rst, rstbuf) 

print ipt 
print rst 

Erwartete Ausgabe:

[1 2 3 4 5 6 7 8 9] 
[1 2 3 4 5 6 7 8 9] 

Ergebnisausgabe:

[1 2 3 4 5 6 7 8 9] 
[1 2 3 5 6 7 9 0 0] 

Antwort

1

int3 (und andere type3 Typen) verhalten sich wie int4 (und andere type4 Typen) für die Zwecke der Größe und Ausrichtung. Sie müssen dies in Ihrem Beispiel berücksichtigen. Sie können dies schnell überprüfen, indem Sie Ihr Beispiel so ändern, dass int4 verwendet wird, und alle weiteren relevanten Informationen aktualisieren.

import pyopencl as cl 
import numpy as np 

platforms = cl.get_platforms() 
ctx = cl.Context(dev_type=cl.device_type.GPU, properties=[(cl.context_properties.PLATFORM, platforms[0])]) 
queue = cl.CommandQueue(ctx) 

rowcnt = 4 
ipt = np.linspace(1, rowcnt * 4, num=rowcnt * 4, dtype=np.int32) 
rst = np.ones((rowcnt * 4), dtype=np.int32) 

mf = cl.mem_flags 
iptbuf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=ipt) 
rstbuf = cl.Buffer(ctx, mf.WRITE_ONLY, rst.nbytes) 

src = ''' 
__kernel void test(__global int4* ipt, __global int* rst) { 
    int idx = get_global_id(0); 
    rst[idx * 4] = ipt[idx].x; 
    rst[idx * 4 + 1] = ipt[idx].y; 
    rst[idx * 4 + 2] = ipt[idx].z; 
    rst[idx * 4 + 3] = ipt[idx].w; 
} 
''' 

prg = cl.Program(ctx, src).build() 
prg.test(queue, (rowcnt,), None, iptbuf, rstbuf) 

cl.enqueue_copy(queue, rst, rstbuf) 

print ipt 
print rst 

Ausgang:

[ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16] 
[ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]