Xilinx/XRT

Can't convert xrt::aie::bo to xrt::bo

Closed this issue · 4 comments

Not sure if I am missing something here, but it doesn't seem like I can easily transfer ta xrt::aie::bo to an xrt::bo without doing a copy() operation.

For example, I need to perform the following data flow (I'm using a Versal VCK190 eval board):

DDR -> AIE -> DDR -> PL -> AIE -> DDR

I do this with the following example code snippet:

const int BLOCK_SIZE_BYTES = 1024*1024*8;
 
auto buffer_to_aie = xrt::aie::bo(m_device, BLOCK_SIZE_BYTES, xrt::bo::flags::normal, 0);
auto buffer_from_aie = xrt::aie::bo(m_device, BLOCK_SIZE_BYTES, xrt::bo::flags::normal, 0);
auto dma_hls_kernel = xrt::kernel(m_device, m_uuid, "dma_hls:{dma_hls_0}");
auto buffer_to_pl = xrt::bo(m_device, BLOCK_SIZE_BYTES, xrt::bo::flags::normal, dma_hls_kernel.group_id(0));
auto dma_hls_kernel_run = xrt::run(dma_hls_kernel);
 
buffer_to_aie.async("fftRowsGraph[0].gmio_in", XCL_BO_SYNC_BO_GMIO_TO_AIE, BLOCK_SIZE_BYTES, 0);
auto async_hdlr = buffer_from_aie.async("fftRowsGraph[0].gmio_out", XCL_BO_SYNC_BO_AIE_TO_GMIO, BLOCK_SIZE_BYTES, 0));
 
async_hdlr.wait();
 
buffer_to_pl.copy(buffer_from_aie, BLOCK_SIZE_BYTES);
 
buffer_to_pl.sync(XCL_BO_SYNC_BO_TO_DEVICE, BLOCK_SIZE_BYTES, 0);
dma_hls_kernel_run.set_arg(0, buffer_to_pl);
dma_hls_kernel_run.start();

I can't find a more optimal way to do the buffer object transfer from buffer_from_aie to buffer_to_pl. The copy operation takes up too much time. But it doesn't seem like I really need to do this copy operation into another buffer object...the data is already in the DDR. Ideally, I would just stick the buffer_from_aie into the argument of the kernel before I run it, like this:

dma_hls_kernel_run.set_arg(0, buffer_from_aie);

But wasn't able to get this to work. There is no "sync" operation like there is with a xrt::bo so I'm not sure how you're supposed to go about this.

@AustinOwens Try assign the xrt::aie::bo directly to an xrt::bo, that should suffice. You only need the xrt::aie::bo for the extended functionality defined in that API.

@stsoe xrt::bo does not allow directives like XCL_BO_SYNC_BO_GMIO_TO_AIE or XCL_BO_SYNC_BO_AIE_TO_GMIO to be used. If I adopt to using xrt::bo for everything, would I just use directives like XCL_BO_SYNC_BO_TO_DEVICE or XCL_BO_SYNC_BO_FROM_DEVICE instead? Will the XRT API know to send this data to the AIE instead of the PL if I do this?

@AustinOwens. You just need to assign the xrt::aie::bo to an xrt::bo before using it with set_arg, I wasn't implying you use xrt::bo all over the place, you should indeed continue to construct xrt::aie::bo and using these with the extended APIs defined for class xrt::aie::bo.

xrt::aie::bo aie_bo{...};
aie_bo.API(...);
...;

xrt::bo bo{aie_bo};
run.set_arg(idx, bo);  // or  run.set_arg(idx, xrt::bo{aie_bo});

aie_bo.API(...);
...

@stsoe Thank you! That ended up working for me!