As explained in Data Accessing Mechanisms, the size of the input and output data blocks for buffer-based access depends on the specified buffer size. Vitis Model Composer supports the following buffer-based input and output data types as interfaces to the AI Engine kernel block.
-
input_buffer<Type> -
output_buffer<Type>
| <Type> | Complexity | Signedness |
|---|---|---|
| int8 | Real | Signed |
| int16 | Real | Signed |
| int32 | Real | Signed |
| int64 | Real | Signed |
| uint8 | Real | Unsigned |
| uint16 | Real | Unsigned |
| uint32 | Real | Unsigned |
| uint64 | Real | Unsigned |
| cint16 | Complex | Signed |
| cint32 | Complex | Signed |
| float | Real | N/A |
| cfloat | Complex | N/A |
| bfloat16 | Real | N/A |
As an example, to import a simple kernel with a buffer-based interface, the
following simple.h header file defines the
add_kernel function with two input buffers and
one output buffer of type int16.
Simple.h
#ifndef __ADD_KERNEL_H__
#define __ADD_KERNEL_H__
#include <adf.h>
#define NUM_SAMPLES 4
using namespace adf;
void add_kernel(input_buffer<int16> & in1,input_buffer<int16> & in2, output_buffer<int16> & outw);
#endif
The kernel (simple.cc) is defined as follows. It processes a
sum operation on in1 and in2
and produces output on outw.
#include "simple.h"
void add_kernel(input_buffer<int16> & in1,input_buffer<int16> & in2, output_buffer<int16> & outw)
{
// Use scalar iterator to traverse data
auto pIn1 = aie::begin(in1);
auto pIn2 = aie::begin(in2);
auto pOut = aie::begin(outw);
for (unsigned i=0; i<NUM_SAMPLES; i++) {
*pOut++ = *pIn1++ + *pIn2++;
}
}
- Define each kernel in its own source file.
- Organize kernels by creating directories for header files and source files separately.
- Ensure kernel source files include all relevant header files to allow for independent compilation.
add_kernel function as a block in a Model Composer
design, double-click the AIE Kernel block and update
parameters as follows:- Kernel header file
- kernels/include/simple.h
- Kernel function
-
add_kernel - Kernel Init function
- Leave empty
- Kernel source file
- kernels/source/simple.cc
- Kernel search path
- Leave empty
- Preprocessor options
- Leave empty
When you click the Import button in the Block Parameters dialog box, the tool parses the function signature in the header file. It also updates the AI Engine kernel block GUI interface as shown in the following figure.
When you add the AIE Kernel block to the Simulink editor, input and output ports are not present. But, when you add the kernel parameters in the Block Parameters dialog box, the block updates with two input ports and one output port. The block name matches the imported kernel function.
After a successful import, the Function tab displays automatically, providing user-editable configuration parameters. You can quickly review the function definition of the imported kernel function and the port names with directions.
Enter appropriate values in the Function tab for Buffer size and Buffer margin (see the previous figure).
Setting the Buffer Margin Value
As explained in Data Accessing Mechanisms, buffer margin is the overlapping of input data samples. Model Composer accepts Buffer margin value in terms of the number of samples. Ensure that the values given in the Buffer margin fields are multiples of 32 bytes.
For example, if your input data type is int16 which is 2 bytes, the minimum accepted Buffer margin value is 16 samples (16*2).
Other acceptable other values can be 32, 48, 64 samples and so on.
As another example, if your input is of type cint32, which is 8 bytes (4 real, 4 imaginary), then the minimum accepted buffer margin value is 4 samples. Other acceptable values can be 8, 12, 16 samples and so on.
The following table provides details on the parameters and description for each parameter.
| Parameter Name | Criticality | Description |
|---|---|---|
| Buffer size | Mandatory |
|
| Buffer margin | Mandatory |
|
| Synchronicity | Mandatory |
|
After the successful import of kernel functions, the Import button label in the General tab changes to Update enabling further updates of block parameters. You can change the source code of the kernel function even after importing the block without requiring a re-import. However, if you change the function signature, or the parameters to the function, then you will need to click Update in the General tab to apply changes.