Pre-built algorithms for common dataflow patterns on AIE. These abstractions handle Workers, ObjectFifos, and data movement automatically.
| Algorithm | Description |
|---|---|
transform |
Unary transformation with tiled processing |
transform_binary |
Binary transformation with tiled processing |
for_each |
In-place transformation (same tensor for input/output) |
transform_parallel |
Parallel transform across multiple AIE tiles |
transform_parallel_binary |
Parallel transform_binary across multiple AIE tiles |
For C++ kernels, the kernel signature and ExternalFunction must match the algorithm's expected format.
| Algorithm | C++ Kernel Signature | ExternalFunction arg_types |
|---|---|---|
transform |
void kernel(T* in, T* out, params..., int32_t tile_size) |
[tile_ty, tile_ty, *param_types, np.int32] |
transform_binary |
void kernel(T* in1, T* in2, T* out, params..., int32_t tile_size) |
[tile_ty, tile_ty, tile_ty, *param_types, np.int32] |
for_each |
void kernel(T* in, T* out, params..., int32_t tile_size) |
[tile_ty, tile_ty, *param_types, np.int32] |
transform_parallel |
void kernel(T* in, T* out, params..., int32_t tile_size) |
[tile_ty, tile_ty, *param_types, np.int32] |
transform_parallel_binary |
void kernel(T* in1, T* in2, T* out, params..., int32_t tile_size) |
[tile_ty, tile_ty, tile_ty, *param_types, np.int32] |
The algorithm library automatically tiles input/output tensors and streams them through ObjectFifos. However, C++ kernels require tile_size as a runtime parameter because they loop over tile data without compile-time knowledge of the size. As such the last argument of each kernel this library supports must be tile_size (np.int32)
For setup, this means:
ExternalFunction.arg_typesmust match the C++ kernel signature, using tile-sized array shapes- Algorithm call accepts full-size tensors and handles tile automatically in terms of ObjectFifo streaming.
tile_sizemust be passed explictly as a keyword argument because the kernel needs it at runtime.
TODO: Future work is needed to consolidate this setup process and combine with ExternalFunction declaration.
TILE_SIZE = 16
tile_ty = np.ndarray[(TILE_SIZE,), np.dtype[np.int16]]
scalar_ty = np.ndarray[(1,), np.dtype[np.int32]]
# Input and output should still be declared as tiled shapes in arg_types
my_kernel = ExternalFunction(
"my_kernel",
source_file="my_kernel.cc",
arg_types=[tile_ty, tile_ty, np.int32, np.int32], # [in, out, factor, tile_size]
)
# Pass in full size tensors, algorithm will tile it to tile_size
# tile_size must be passed as a keyword argument
iron.jit(transform)(
my_kernel, input, output, factor, tile_size=TILE_SIZE
)For a complete example, see vector_scalar_mul.py.
Run and verify a design:
python3 transform.py