Buffer Objects
In order to transfer data between host and devices, XRT primarily uses buffers in the form of BO
(Buffer Object). These BO
need to be allocated on an available device's memory bank depending on the kernel argument. Then, they can be synchronized to and from the device.
The BOArray
Type
XRT.jl offers an extended version of BO
, the XRT.BOArray
, which additionally supports indexing and automatic alignment of the buffer as it must be aligned to 4K boundary.
The simplest way to create a BOArray
object is to prepare an AbstractArray
with the required user data and pass it to the BOArray
constructor together with the desired memory bank index:
julia> a = Array{Float64}(MemAlign(4096), array_size); a .= 1.0
julia> xa = XRT.BOArray(a, group_id(kernel, 0))
In this example the Array
is optionally aligned using the MemAlign
function from the ArrayAllocators.jl package, which is reexported by XRT.jl. The array can also be instantiated as usual. Alignment is then performed by XRT.jl.
It is important to correctly set the right memory bank index. This can be done via the
group_id
function that takes the kernel object and the kernel argument index starting at 0. Alternatively, a memory bank id, obtained by thememory
report, can directly be specified.
To allocate the buffer on a device other than the one currently selected, the device
keyword argument can be used. It is also possible to set a flag
as a keyword argument for creating special buffers (see Official XRT Documentation).
The BOArray
must then be transferred explicitly. This is done with the XRT.sync!
function and the corresponding synchronization direction, which can be found in the XRT.BOSyncDirection
module:
julia> sync!(xa, XRT.TO_DEVICE)
Restricting Synchronization Direction
Some functions used for High Level Abstractions for Kernel Executions handle the automatic synchronization of buffers. However, this always happens in both directions, which can lead to unnecessary data transfers. XRT.jl offers at least two options to avoid this.
The AbstractSyncDirectionArray
and the AbstractBOArray
Type
In addition to the BOArray
and AbstractArray
types, there are also XRT.ToDeviceBOArray
/XRT.FromDeviceBOArray
or XRT.ToDeviceArray
/XRT.FromDeviceArray
types in XRT.jl. A BOArray
/AbstractArray
can be instantiated as these types and thus restricts the respective synchronization direction of the user data.
In addition, a BOArray
can also be converted as required:
julia> todevice_xa = convert(XRT.ToDeviceBOArray, xa)
The AbstractSyncDirectionWrapper
Type
Another way to restrict the synchronization direction is to wrap the AbstractArray
or the BOArray
by either an XRT.ToDeviceWrapper
object or an XRT.FromDeviceWrapper
. These wrapper types guarantee that synchronization only happens in the specified direction:
julia> XRT.Run(XRT.ToDeviceWrapper(input), XRT.FromDeviceWrapper(output),...)