Skip to content

Commit

Permalink
Enabling Async support for External Buffers (#8467)
Browse files Browse the repository at this point in the history
* enable async operations for gmio/external buffers

Signed-off-by: ch vamshi krishna <[email protected]>

* enable async operations for gmio/external buffers

Signed-off-by: ch vamshi krishna <[email protected]>

* enable async operations for gmio/external buffers

Signed-off-by: ch vamshi krishna <[email protected]>

* fix

* adding documentation

Signed-off-by: ch vamshi krishna <[email protected]>

* fixed review comments

Signed-off-by: ch vamshi krishna <[email protected]>

---------

Signed-off-by: ch vamshi krishna <[email protected]>
Co-authored-by: ch vamshi krishna <[email protected]>
  • Loading branch information
chvamshi-xilinx and ch vamshi krishna authored Oct 3, 2024
1 parent 3970d68 commit 81fffb0
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 6 deletions.
43 changes: 39 additions & 4 deletions src/runtime_src/core/common/api/aie/xrt_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,18 @@ class buffer_impl
{
m_buffer_handle->sync(bos, dir, size, offset);
}

void
async(std::vector<xrt::bo>& bos, xclBOSyncDirection dir, size_t size, size_t offset) const
{
m_buffer_handle->async(bos, dir, size, offset);
}

void
wait() const
{
m_buffer_handle->wait();
}
};

} // xrt::aie
Expand Down Expand Up @@ -467,20 +479,43 @@ buffer(const xrt::hw_context& hwctx, const std::string& name)

void
buffer::
sync(const xrt::bo& bo, xclBOSyncDirection dir, size_t size, size_t offset) const
sync(xrt::bo bo, xclBOSyncDirection dir, size_t size, size_t offset) const
{
std::vector<xrt::bo> bos {bo};
std::vector<xrt::bo> bos {std::move(bo)};
return get_handle()->sync(bos, dir, size, offset);
}

void
buffer::
sync(const xrt::bo& ping, const xrt::bo& pong, xclBOSyncDirection dir, size_t size, size_t offset) const
async(xrt::bo bo, xclBOSyncDirection dir, size_t size, size_t offset) const
{
std::vector<xrt::bo> bos {ping,pong};
std::vector<xrt::bo> bos {std::move(bo)};
return get_handle()->async(bos, dir, size, offset);
}

void
buffer::
sync(xrt::bo ping, xrt::bo pong, xclBOSyncDirection dir, size_t size, size_t offset) const
{
std::vector<xrt::bo> bos {std::move(ping),std::move(pong)};
return get_handle()->sync(bos, dir, size, offset);
}

void
buffer::
async(xrt::bo ping, xrt::bo pong, xclBOSyncDirection dir, size_t size, size_t offset) const
{
std::vector<xrt::bo> bos {std::move(ping),std::move(pong)};
return get_handle()->async(bos, dir, size, offset);
}

void
buffer::
wait() const
{
return get_handle()->wait();
}

} // xrt:aie

////////////////////////////////////////////////////////////////
Expand Down
12 changes: 12 additions & 0 deletions src/runtime_src/core/common/shim/aie_buffer_handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ class aie_buffer_handle
throw xrt_core::error(std::errc::not_supported, __func__);
}

virtual void
async(std::vector<xrt::bo>&, xclBOSyncDirection, size_t, size_t)
{
throw xrt_core::error(std::errc::not_supported, __func__);
}

virtual void
wait()
{
throw xrt_core::error(std::errc::not_supported, __func__);
}

};

} // xrt_core
Expand Down
22 changes: 22 additions & 0 deletions src/runtime_src/core/edge/user/aie/aie_buffer_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,26 @@ namespace zynqaie {
{
return m_aie_array->sync_bo(bos, name.c_str(), dir, size, offset);
}

void
aie_buffer_object::async(std::vector<xrt::bo>& bos, xclBOSyncDirection dir, size_t size, size_t offset)
{
std::lock_guard<std::mutex> lock(mtx);
if (async_started)
throw xrt_core::error(-EINVAL, "Asynchronous operation is already initiated. Multiple 'async' calls are not supported");

m_aie_array->sync_bo_nb(bos, name.c_str(), dir, size, offset);
async_started = true;
}

void
aie_buffer_object::wait()
{
std::lock_guard<std::mutex> lock(mtx);
if (!async_started)
throw xrt_core::error(-EINVAL, "Asynchronous operation is not initiated. Please call 'wait' after 'async' call");

m_aie_array->wait_gmio(name);
async_started = false;
}
}
8 changes: 8 additions & 0 deletions src/runtime_src/core/edge/user/aie/aie_buffer_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,21 @@ namespace zynqaie {
{
std::string name;
std::shared_ptr<aie_array> m_aie_array;
std::mutex mtx;
bool async_started = false;

public:
aie_buffer_object(xrt_core::device* device , const xrt::uuid uuid, const char* name, const zynqaie::hwctx_object* hwctx=nullptr);

void
sync(std::vector<xrt::bo>& bos, xclBOSyncDirection dir, size_t size, size_t offset) const;

void
async(std::vector<xrt::bo>& bos, xclBOSyncDirection dir, size_t size, size_t offset);

void
wait();

std::string
get_name() const;

Expand Down
45 changes: 43 additions & 2 deletions src/runtime_src/core/include/xrt/xrt_aie.h
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,24 @@ class buffer : public detail::pimpl<buffer_impl>
* This configures the required BDs , enqueues the task and wait for
* completion
*/
void sync(const xrt::bo& bo, xclBOSyncDirection dir, size_t size, size_t offset) const;
void sync(xrt::bo bo, xclBOSyncDirection dir, size_t size, size_t offset) const;

/**
* async() - This function initiates an asynchronize operation to synchronize the buffer with a single xrt::bo object
*
* @param bo
* The xrt::bo object to synchronize
* @param dir
* The direction of synchronization (e.g., host to device or device to host)
* @param size
* The size of the data to synchronize
* @param offset
* The offset within the buffer to start synchronization
*
* This function synchronizes the buffer with the specified xrt::bo object.
* This configures the required BDs , enqueues the task
*/
void async(xrt::bo bo, xclBOSyncDirection dir, size_t size, size_t offset) const;

/**
* sync() - Synchronize buffer with two xrt::bo objects (ping-pong)
Expand All @@ -426,7 +443,31 @@ class buffer : public detail::pimpl<buffer_impl>
* This configures the required BDs , enqueues the task and wait for
* completion
*/
void sync(const xrt::bo& ping, const xrt::bo& pong, xclBOSyncDirection dir, size_t size, size_t offset) const;
void sync(xrt::bo ping, xrt::bo pong, xclBOSyncDirection dir, size_t size, size_t offset) const;

/**
* async() - This function initiates an asynchronize operation to synchronize buffer with two xrt::bo objects (ping-pong)
*
* @param ping
* The first xrt::bo object to synchronize (ping)
* @param pong
* The second xrt::bo object to synchronize (pong)
* @param dir
* The direction of synchronization (e.g., host to device or device to host)
* @param size
* The size of the data to synchronize
* @param offset
* The offset within the buffer to start synchronization
*
* This function synchronizes the buffer with the specified xrt::bo objects in a ping-pong manner.
* This configures the required BDs , enqueues the task
*/
void async(xrt::bo ping, xrt::bo pong, xclBOSyncDirection dir, size_t size, size_t offset) const;

/**
* wait() - This function waits for the previously initiated async operation
*/
void wait() const;

};

Expand Down
36 changes: 36 additions & 0 deletions src/runtime_src/doc/toc/xrt_native_apis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,42 @@ The following code shows a sample example with a single input/output GMIO/Extern
auto xrt::aie::buffer out_buffer = xrt::aie::buffer(device, uuid,"gr.out1");
out_buffer.sync(out_bo, XCL_BO_SYNC_BO_AIE_TO_GMIO, SIZE * sizeof(float),0);

This class has overloaded member function ``xrt::aie::buffer::async(...)`` that can be used to initiate an asynchronize operation to synchronize the xrt::bo buffer object

xrt::aie::buffer::async(xrt::bo bo, ...) initiate an asynchronize operation between xrt::aie::buffer (GMIO/External Buffer) & xrt::bo (Global Memory)

xrt::aie::buffer::async(xrt::bo ping,xrt::bo pong, ...) initiate an asynchronize operation between xrt::aie::buffer (GMIO/External Buffer) & ping/pong xrt::bo objects

xrt::aie::buffer::wait() waits for the asynchronize operation to complete

The following code shows a sample example with a single input/output GMIO/External Buffer. Data gets transferred from global buffer "in_bo" to "gr.in1"

.. code:: c++
:number-lines: 1

auto device = xrt::aie::device(0);
auto uuid = device.load_xclbin(xclbin-filename);

// Create Buffer in DDR/Global memory & prepare input
auto in_bo = xrt::aie::bo (device, SIZE * sizeof (float), 0, 0);
auto inp_bo_map = in_bo.map<float *>();
std::copy(my_float_array,my_float_array+SIZE,inp_bo_map);
// Create Buffer in DDR/Global memory to store output
auto out_bo = xrt::aie::bo (device, SIZE * sizeof (float), 0, 0);
auto out_bo_map = out_bo.map<float *>();
// create GMIO/External Buffer object for input & sync from in_bo
auto xrt::aie::buffer in_buffer = xrt::aie::buffer(device, uuid,"gr.in1");
in_buffer.async(in_bo, XCL_BO_SYNC_BO_GMIO_TO_AIE, SIZE * sizeof(float),0);

//run your graphs which uses output GMIO/External buffer

// create GMIO/External Buffer object for output & sync from out_bo
auto xrt::aie::buffer out_buffer = xrt::aie::buffer(device, uuid,"gr.out1");
out_buffer.async(out_bo, XCL_BO_SYNC_BO_AIE_TO_GMIO, SIZE * sizeof(float),0);
out_buffer.wait();

Ping Pong buffers
~~~~~~~~~~~~~~~~~
The following code shows ping-pong buffer example.This shows an example with a ping/ping buffer being set on one of External buffer
Expand Down

0 comments on commit 81fffb0

Please sign in to comment.