Как передать список строк в ядро opencl правильным способом?Как передать список строк в ядро opencl с помощью pyopencl?
Я пробовал этот способ с использованием буферов (см. Следующий код), но мне не удалось.
OpenCL (struct.cl):
typedef struct{
uchar uc[40];
} my_struct9;
inline void try_this7_now(__global const uchar * IN_DATA ,
const uint IN_len_DATA ,
__global uchar * OUT_DATA){
for (unsigned int i=0; i<IN_len_DATA ; i++) OUT_DATA[i] = IN_DATA[i];
}
__kernel void try_this7(__global const my_struct9 * pS_IN_DATA ,
const uint IN_len ,
__global my_struct9 * pS_OUT){
uint idx = get_global_id(0);
for (unsigned int i=0; i<idx; i++) try_this7_now(pS_IN_DATA[i].uc, IN_len, pS_OUT[i].uc);
}
Python (opencl_struct.py):
# -*- coding: utf-8 -*-
import pyopencl as cl
import pyopencl.array as cl_array
import numpy
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
# --------------------------------------------------------
LIMIT = 40
mf = cl.mem_flags
import ctypes,sys,struct
"""
typedef struct{
uchar uc[40];
} my_struct9;
"""
INlist = []
INlist.append("That is VERY cool!")
INlist.append("It is a list!")
INlist.append("A big one!")
#INlist.append("But it failes to output. :-(") # PLAY WITH THOSE
INlist.append("WTF is THAT?") # PLAY WITH THOSE
print "INlist : "+str(INlist)
print "largest string "+str(max(len(INlist[iL]) for iL in range(len(INlist))))
strLIMIT=str(LIMIT)
s7 = struct.Struct( (str(strLIMIT+'s') *len(INlist)))
IN_host_buffer = ctypes.create_string_buffer(s7.size)
s7.pack_into(IN_host_buffer, 0, *INlist)
IN_dev_buffer = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=IN_host_buffer)
OUT_host_buffer = ctypes.create_string_buffer(s7.size)
OUT_dev_buffer = cl.Buffer(ctx, mf.WRITE_ONLY, len(OUT_host_buffer))
print "> len(OUT_host_buffer) "+str(len(OUT_host_buffer))
# ========================================================================================
f = open("struct.cl", 'r')
fstr = "".join(f.readlines())
prg = cl.Program(ctx, fstr).build()
#cl.enqueue_copy(queue, IN_dev_buffer, IN_host_buffer, is_blocking=True) # copy data to device
cl.enqueue_write_buffer(queue, IN_dev_buffer, IN_host_buffer).wait()
prg.try_this7(queue, (1,), None, IN_dev_buffer, numpy.uint32(LIMIT), OUT_dev_buffer)
# ========================================================================================
cl.enqueue_copy(queue, OUT_host_buffer, OUT_dev_buffer).wait()
SSS = s7.unpack_from(OUT_host_buffer,0)
# unpack here OUT_host_buffer
print "(GPU) output : "+str(SSS)+" "
for s in range(len(SSS)):
print ">>> (GPU) output : "+str(SSS[s])
Я побежал программу первый раз с "но failes к выходу" в качестве 4-го элемента списка , Затем я играл, увеличивая и уменьшая элементы списка. И, наконец, появилась такая проблема: Выход программы должен быть (короткая версия)
(GPU) выход: Это очень здорово!
(GPU) output: Это список!
(GPU) мощность: большой!
(GPU) мощность: WTF это?
Но:
питон opencl_struct.py
INlist: [ '! Это очень круто', '! Это список', «Большой!», «WTF is THAT?»]
наибольшая строка 18
Выход len (OUT_host_buffer) 160 (GPU): («Это ОЧЕНЬ круто! \ X00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 ', ' Это список ! \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \, 'Большой один! \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00' , 'Но это не позволяет выводить. : - (\ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00')
(GPU) выход: Это очень здорово!
(GPU) output: Это список!
(GPU) мощность: большой!
(GPU) выход: но он не подходит для вывода.:-(
Как вы видите, на 4-й differes список элементов.
Так, может быть, мой подход является неправильным или есть ошибка в pyopencl или где-нибудь еще.
Я использую NVidia 9400 GPU.
Рэмбо