XRT のバッファー割り当て - 2021.1 Japanese

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

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

データセンター プラットフォームでは、4K ページ境界に合わせてメモリを割り当てる方が効率的です。エンベデッド プラットフォームでは、連続的なメモリ割り当てを実行する方が効率的です。いずれの場合も、バッファーの作成時に XRT にホストメモリを割り当てることができます。これは、バッファーを作成するときに CL_MEM_ALLOC_HOST_PTR フラグを使用し、 clEnqueueMapBuffer を使用して割り当てられたメモリをユーザー空間ポインターにマッピングすると実行できます。この方法を使用する場合、4K 境界に揃えられたホスト空間ポインターを作成する必要はありません。

clEnqueueMapBuffer API は指定したバッファーをマップして XRT で作成されたポインターをこのマップした領域に戻します。この後、ホスト側のポインターをユーザーのデータで埋めて、clEnqueueMigrateMemObject でデータをデバイスに送信したり受信したりします。次は、この形式を使用したコード例です。

// Two cl_mem buffer, for read and write by kernel
cl_mem dev_mem_read_ptr = clCreateBuffer(context, CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_ONLY,
    				 sizeof(int) * number_of_words, NULL, NULL); 

cl_mem dev_mem_write_ptr = clCreateBuffer(context, CL_MEM_ALLOC_HOST_PTR | CL_MEM_WRITE_ONLY,
    				 sizeof(int) * number_of_words, NULL, NULL); 


cl::Buffer in1_buf(context, CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_ONLY,  sizeof(int) * DATA_SIZE, NULL, &err);

// Setting arguments
clSetKernelArg(kernel, 0, sizeof(cl_mem), &dev_mem_read_ptr); 
clSetKernelArg(kernel, 1, sizeof(cl_mem), &dev_mem_write_ptr); 

// Get Host side pointer of the cl_mem buffer object
auto host_write_ptr = clEnqueueMapBuffer(queue,dev_mem_read_ptr,true,CL_MAP_WRITE,0,bytes,0,nullptr,nullptr,&err);
auto host_read_ptr = clEnqueueMapBuffer(queue,dev_mem_write_ptr,true,CL_MAP_READ,0,bytes,0,nullptr,nullptr,&err);

// Fill up the host_write_ptr to send the data to the FPGA

for(int i=0; i< MAX; i++) {
    host_write_ptr[i] = <.... > 
}

// Migrate
cl_mem mems[2] = {host_write_ptr,host_read_ptr};
clEnqueueMigrateMemObjects(queue,2,mems,0,0,nullptr,&migrate_event));

// Schedule the kernel
clEnqueueTask(queue,kernel,1,&migrate_event,&enqueue_event);

// Migrate data back to host
clEnqueueMigrateMemObjects(queue, 1, &dev_mem_write_ptr, 
                           CL_MIGRATE_MEM_OBJECT_HOST,1,&enqueue_event, &data_read_event);
     
clWaitForEvents(1,&data_read_event);

// Now use the data from the host_read_ptr

clEnqueueMapBuffer を使用する例は、Vitis Examples GitHub リポジトリの Data Transfer (C) を参照してください。