这将是一个很长的问题,但是我没有其他方法可以提出这个问题。请忍受我。
如果提供了一个短字符串,根据一些规则,该字符串将在OpenCL中扩展为较大的输出。
小字符串:FX
rules:
X -> X+YF+
Y-> -FX-Y
只要您看到,X
就会用X+YF+
替换,Y
会用-FX-Y
替换。
我预见到的问题之一是确定问题的范围。我将小字符串作为我的内核程序的输入,并期望将扩展的字符串作为我的输出。扩展小字符串20 times
将导致输出长度为4194302
。这个问题的全球规模是多少?输入大小是长度为2的小字符串FX
,输出是将其扩展20倍的结果,即长度(4194302)。
我也想知道如何在OpenCL上扩展字符串。首先,输入只有大小2。如何将多个线程作用于该输入以并行扩展它?这是否意味着我最多只能从2个线程开始,因为输入的大小为2?如果是这样,我将在第一次扩展后获得一个输出,然后必须找到一种将相同的输出作为输入进行后续扩展的方式。以下是我的粗略尝试。欢迎任何建议。
#!/usr/bin/env python3
import pyopencl as cl
import numpy as np
import seq
# Write down our kernel as a multiline string.
kernel = """
__kernel void dragon(
const int N,
__global char *in,
__local char *out,
__global char *XEXPANSION,
__global char *YEXPANSION)
{
int gid = get_global_id(0);
int globalSize = get_global_size(0);
int i;
for(i=gid; i< N; i++){
in[i] = out[i];
if (in[i]== 'X') {
for(int a=0; a<5; a++){
out[i+a]=XEXPANSION[a];
}
}
if (in[i]== 'Y') {
for(int a=0; a<5; a++){
out[i+a]=XEXPANSION[a];
}
}
}
}
"""
#declare constants
number_of_expansions = 20
resulting_str_size=4194302
# Step 1: Create a context.
# This will ask the user to select the device to be used.
context = cl.create_some_context()
# Create a queue to the device.
queue = cl.CommandQueue(context)
# Create the program.
program = cl.Program(context, kernel).build()
# Create the input string
original_str =np.array(('FX'))
XEXPANSION = np.array(('X+YF+'))
YEXPANSION = np.array(('-FX-Y'))
# Send the data to the guest memory.
mf = cl.mem_flags
in_buf = cl.Buffer(context, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=original_str)
XEXP = cl.Buffer(context, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=XEXPANSION)
YEXP = cl.Buffer(context, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=YEXPANSION )
# Create the memory on the device to put the result into.
out_buf = cl.Buffer(context, mf.WRITE_ONLY, size=resulting_str_size)
copied_str = np.zeros((resulting_str_size,), dtype=int)
# Initiate the kernel.
dragon = program.dragon
dragon.set_scalar_arg_dtypes([np.int32, None, None,None,None])
global_work_size = number_of_expansions
# Execute C = A * B.
dragon(queue, (global_work_size,), None,np.int32(number_of_expansions),in_buf, out_buf,XEXP, YEXP)
# Wait for the queue to be completely processed.
queue.finish()
# Read the array from the device.
cl.enqueue_copy(queue, copied_str, out_buf).wait()
print (copied_str)