デバイス バッファーから特定部分を読み込む方法 - 2021.1 Japanese

Vitis 統合ソフトウェア プラットフォームの資料: アプリケーション アクセラレーション開発 (UG1393)

Document ID
UG1393
Release Date
2022-03-29
Version
2021.1 Japanese

カーネルへの入力によって、出力されるデータ量が異なることがあります。たとえば、入力データ パターンによって、出力サイズが変更する圧縮エンジンがあります。ホストで clEnqueueMigrateMemObjects を使用して出力バッファー全体を読み出すことはできますが、必要以上のメモリ転送が発生するので、最適な方法ではありません。理想的なのは、ホストがカーネルの書き込んだのと同じ量のデータだけを読み出す方法です。

たとえば、カーネルが出力データの書き込み開始時点で出力データ量を書き込むようにするという方法があります。ホスト アプリケーションは clEnqueueReadBuffer を 2 回使用できます (1 回目は返されたデータ量を読み出して、2 回目で最初の読み出しからの情報に基づいてカーネルから返されたのと同じ量のデータを読み出します)。
clEnqueueReadBuffer(command_queue,device_write_ptr, CL_FALSE, 0, sizeof(int) * 1, 
                    &kernel_write_size, 0, nullptr, &size_read_event);
clEnqueueReadBuffer(command_queue,device_write_ptr, CL_FALSE, DATA_READ_OFFSET, 
                    kernel_write_size, host_ptr, 1, &size_read_event, &data_read_event);
clEnqueueMigrateMemObject (clEnqueueReadBuffer または clEnqueueWriteBuffer よりも推奨) を使用すると、サブバッファーを使用して同様の方法を使用できます。次のコードはその具体例です。
ヒント: コード例は、この概念を示すことを目的としているので、コマンドの一部しか表示していません。
//Create a small sub-buffer to read the quantity of data
cl_buffer_region buffer_info_1={0,1*sizeof(int)}; 
cl_mem size_info = clCreateSubBuffer (device_write_ptr, CL_MEM_WRITE_ONLY, 
      CL_BUFFER_CREATE_TYPE_REGION, &buffer_info_1, &err);

// Map the sub-buffer into the host space
auto size_info_host_ptr = clEnqueueMapBuffer(queue, size_info,,,, );

// Read only the sub-buffer portion
clEnqueueMigrateMemObjects(queue, 1, &size_info, CL_MIGRATE_MEM_OBJECT_HOST,,,);
                          
// Retrive size information from the already mapped size_info_host_ptr
kernel_write_size = ........... 

// Create sub-buffer to read the required amount of data     
cl_buffer_region buffer_info_2={DATA_READ_OFFSET, kernel_write_size};
cl_mem  buffer_seg = clCreateSubBuffer (device_write_ptr, CL_MEM_WRITE_ONLY, 
      CL_BUFFER_CREATE_TYPE_REGION, &buffer_info_2,&err);

// Map the subbuffer into the host space
auto read_mem_host_ptr = clEnqueueMapBuffer(queue, buffer_seg,,,);

// Migrate the subbuffer
clEnqueueMigrateMemObjects(queue, 1, &buffer_seg, CL_MIGRATE_MEM_OBJECT_HOST,,,);

// Now use the read data from already mapped read_mem_host_ptr