OpenCL カーネルを呼び出すときに渡すことができる最大パラメーター サイズを見つけたいという好奇心から、最大サイズより大きいサイズの配列を渡すことができることがわかりました。これが何が起こっているかです:(ちなみに、私は pyopencl を使用しています)
>>> plat = cl.get_platforms()
>>> dev = plat[0].get_devices( cl.device_type.ALL )
>>> dev[0]
<pyopencl.Device 'Juniper' on 'AMD Accelerated Parallel Processing' at 0x58fde60>
>>> dev[0].max_parameter_size
1024
Google検索で、1024がバイトであることを知りました。(どこに書いてあったか忘れましたが、Nvidia フォーラムだと思います。)
今、私はこのスクリプトを実行しました:
import pyopencl as cl
import numpy as np
plat = cl.get_platforms()
dev = plat[0].get_devices( cl.device_type.ALL )
ctx = ctx = cl.Context( [ dev[0] ] )
cq = cl.CommandQueue( ctx )
kernel = """
__kernel void test( __global int* A, __global int* B ){
const int id = get_global_id( 0 );
B[ id ] = A[ id ];
barrier( CLK_GLOBAL_MEM_FENCE );
}
"""
prg = cl.Program( ctx, kernel ).build()
A = np.ones( ( 2**18, ), dtype = np.int32 )
B = np.zeros_like( A )
A_buf = cl.Buffer( ctx, cl.mem_flags.READ_ONLY|cl.mem_flags.COPY_HOST_PTR, hostbuf = A )
B_buf = cl.Buffer( ctx, cl.mem_flags.WRITE_ONLY, B.nbytes )
カーネルを呼び出す前に、次のことを行いました。
>>> A.nonzero()[0].shape
(262144,)
>>> B.nonzero()[0].shape
(0,)
次に、カーネルを呼び出して、B の非ゼロ要素をチェックしました。
>>> prg.test( cq, A.shape, A_buf, B_buf ).wait()
>>> cl.enqueue_copy( cq, B, B_buf )
>>> B.nonzero()[0].shape
(262144,)
したがって、明らかに、サイズが より大きい配列を送信して読み取ることができますcl.max_parameter_size
。これはどのように可能ですか?またはどこが間違っていますか?