2021年5月28日金曜日

enqueueMigrateMemObjectを使ってみたときのメモ

enqueueMigrateMemObjectを使ってみたときのメモ

使い方

1.cl::Bufferを宣言する

hostが書き込む場合はCL_MEM_READ_ONLYのflagを指定する。
hostが読み込む場合はCL_MEM_WRITE_ONLYのflagを指定する。
exampleには無いが、ドキュメントではCL_MEM_ALLOC_HOST_PTRを使う方が良いらしい。

cl::Buffer *imageToDevice_fast;
cl::Buffer *buffer_vec;
imageToDevice_fast = new cl::Buffer(*context, CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, fast_and_dist_in_size_bytes, NULL, &err);
buffer_vec = new cl::Buffer(*context, CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR, vector_size, NULL, &err);

2.Kernelにcl::Bufferを紐付ける

cl::Kernel *fast_krnl;
fast_krnl = new cl::Kernel(program,"fast_and_dist_accel", &err);
fast_krnl->setArg(0, *imageToDevice_fast);
fast_krnl->setArg(4, *buffer_vec);

3.cl::Bufferのポインタを取得する

unsigned char *host_write_ptr_fast;
host_write_ptr_fast = (unsigned char *)q->enqueueMapBuffer(*imageToDevice_fast,CL_TRUE,CL_MAP_WRITE,0,rows_fast*cols_fast*sizeof(unsigned char),nullptr,nullptr,&err);
kernel_write_ptr_fast = (unsigned int *)q->enqueueMapBuffer(*buffer_vec,CL_TRUE,CL_MAP_READ,0,vector_size,nullptr,nullptr,&err);

4.書き込む場合は取得したポインタを使用してcl::Bufferを操作する

for(int k=0; k < rows_fast; ++k){
    memcpy( (host_write_ptr_fast + k*buffer_row_pitch),
            (img_ptr + (k+(unsigned int)iniY)*host_row_pitch + (unsigned int)iniX),
            buffer_row_pitch);
}

5.enqueueMigrateMemObjectsでcl::Bufferを指定する。

q->enqueueMigrateMemObjects({*imageToDevice_fast},0,nullptr, &write_event);

6.読み出す場合はenqueueMigrateMemObjectsの実行後にポインタを介してデータ取得する。

if((kernel_write_ptr_fast[ii] & 0x80000000) != 0){
    // statements
}

感想

KernelにBufferを紐付けるのは最後でも良い気がする。 そうすれば前処理したデータをcl::Bufferとしてたくさん持っておいて、 これを逐次切り替えながらkernelを動作させるということも可能そう。

0 件のコメント:

コメントを投稿