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

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

Document ID
UG1393
Release Date
2021-03-22
Version
2020.2 Japanese

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

出力データの書き込みの開始時に、カーネルが出力データに書き込む量を書き込むようにするのが 1 つの方法です。ホスト アプリケーションでは、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