Importing Buffer-Based Kernels - 2024.1 English

Vitis Model Composer User Guide (UG1483)

Document ID
UG1483
Release Date
2024-05-30
Version
2024.1 English

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>
Table 1. Buffer-Based Input and Output Data Types
<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++;
    }
}
Tip: Although not required, the following recommendations are useful for reusability and faster compilation.
  • Define each kernel in its own source file.
  • Organize kernels by creating directories for header files and source files separately.
  • Kernel source files should include all relevant header files to allow for independent compilation.
To import the 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 and updates the AI Engine kernel block GUI interface as shown in the following figure.

Figure 1. AIE Kernel Block (Updated)

After the AIE Kernel block is added to the Simulink editor, input and output ports are not present. But, after adding the kernel parameters in the Block Parameters dialog box, the block is updated with two input ports and one output port with block name matching 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.

Figure 2. Function Tab

Appropriate values should be entered 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. The values given in the Buffer margin fields should be multiple of 32 bytes.

For example, if your input data type is int16 which is 2 bytes, the minimum Buffer margin value that is accepted is 16 samples (16*2). The other values that are accepted can be 32, 48, 64 samples and so on.

Another example: If your input is of type cint32 which is 8 bytes (real 4 bytes and 4 imaginary bytes), in this case the minimum buffer margin value that is accepted is 4 samples. The other values that are accepted can be 8, 12, 16 samples and so on.

The following table provides details on the parameters and description for each parameter.

Table 2. Buffer Port Parameters
Parameter Name Criticality Description
Buffer size Mandatory
  • Buffer size is required for each port (argument) of the kernel function.
  • The value represents the number of samples (elements).
  • The buffer size must be a positive integer value.
  • Buffer size should be a multiple of 16 bytes if no buffer margin is specified. If a margin is specified, the buffer size should be a multiple of 32 bytes.
Buffer margin Mandatory
  • Buffer margin is required for each input port (argument) of the kernel function.
  • The value represents the number of samples (elements).
  • The buffer margin must be a non-negative integer.
  • The buffer margin should be a multiple of 32 bytes.
Synchronicity Mandatory
  • The Synchronicity value options available are sync and async.
  • Port synchronicity is set to sync by default. You can optionally change it async.

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.

Figure 3. General Tab