Importing AI Engine Graphs - 2020.2 English

Model Composer and System Generator User Guide (UG1483)

Document ID
UG1483
Release Date
2020-11-18
Version
2020.2 English

As discussed in AI Engine Graphs, a graph is a connection of different compute kernel functions. Unlike when importing kernels, where a kernel function is imported as a block into Model Composer, in this case, graph code is imported as a block. To import the graph as block into Model Composer, you need to select the AI Engine graph block from the AI Engine library (shown in the following figure).

Figure 1. AI Engine Graph

Model Composer allows to connect the AI Engine graph block with the AI Engine kernel block so that the whole design can be simulated in the Simulink environment.

Important: It is assumed that your kernel code is already developed and that the associates kernels are properly organized.

To import the graph code, double-click the AIE Graph block. This opens the block parameters GUI from where you can specify the graph source file, search paths, and preprocessor options as shown in the following figure.

Figure 2. AI Engine Graph Block Parameters

The following table provides further details including names and descriptions of each parameter.

Table 1. AI Engine Graph Block Parameters
Parameter Name Parameter Type Criticality Description
Graph application file String Mandatory Specify the file(.cpp), where the adf dataflow graph is instantiated and connected to the simulation platform. This file should contain the main() function from where the dataflow graph initializes and runs.
Graph search paths Vector of strings Mandatory Specify search paths where header files, kernels, and other included files can be located and included for simulation. The search path $XILINX_VITIS/adf/include (where adf.h is defined) is be included by default and does not need to be specified.
Preprocessor options   Optional Optional preprocessor arguments for downstream compilation with specific preprocessor options. The following preprocessor option formats are accepted and multiple can be selected: -Dname and -Dname=definition. That is, the optional argument must begin with the -D string and if the option definition value is not provided, it is assumed to be 1.

The following example shows the sample graph header file (graph.h) with class definitions and interconnections of different kernels.

graph.h

#ifndef _GRAPH_H
#define _GRAPH_H
#include <adf.h>
#include "kernels.h"

class mygraph : public adf::graph {

  private:
    adf::kernel k0;
    adf::kernel k1;
    adf::bypass b1;
    adf::kernel k2;
  public:
    adf::port<input> datain[2];
    adf::port<output> dataout[2];
    adf::port<input> control;

    mygraph() { 

      // Nodes

      // Create kernel0
      k0 = adf::kernel::create(kernel0);
      adf::source(k0) = "kernel0.cc";
      adf::runtime<ratio>(k0) = 0.9;
      adf::location<adf::kernel>(k0) = adf::tile(0,0);

      // Create kernel1
      k1 = adf::kernel::create(kernel1);
      adf::source(k1) = "kernel1.cc";
      adf::runtime<ratio>(k1) = 0.9;
      adf::location<adf::kernel>(k1) = adf::tile(1,0);
      b1 = adf::bypass::create(k1);

      // Create kernel2
      k2 = adf::kernel::create(kernel2);
      adf::source(k2) = "kernel2.cc";
      adf::runtime<ratio>(k2) = 0.9;
      adf::location<adf::kernel>(k2) = adf::tile(3,0);  // Far away, so as to force ME-to-ME tile DMA.

      // Edges

      adf::connect< adf::parameter > (control, b1.bp);
      adf::connect< adf::stream, adf::window<64,32> > (datain[0], k0.in[0]);
      adf::connect< adf::stream, adf::window<256,128> > (datain[1], k0.in[1]);
      adf::connect< adf::window<64> > (k0.out[0], b1.in[0]);
      adf::connect< adf::window<256> > (k0.out[1], b1.in[1]);
      adf::connect< adf::window<64> > (b1.out[0], k2.in[0]);
      adf::connect< adf::window<256> > (b1.out[1], k2.in[1]);
      adf::connect< adf::window<64>, adf::stream > (k2.out[0], dataout[0]);
      adf::connect< adf::window<256>, adf::stream > (k2.out[1], dataout[1]);

    };


  };
#endif

The kernels and the function definitions are provided to the graph by the kernels.h file. A preview of that file is as follows.

kernels.h

#ifndef KERNEL_H

void kernel0(input_window_int32 * in0, input_window_int32 * in1, output_window_int32 * out0, output_window_int32 * out1);

void kernel1(input_window_int32 * in0, input_window_int32 * in1, output_window_int32 * out0, output_window_int32 * out1);

void kernel2(input_window_int32 * in0, input_window_int32 * in1, output_window_int32 * out0, output_window_int32 * out1);

#endif

The graph.cpp file is where the graph is connected to the simulation platform as follows. This file should be pointed to the Graph application file field in the Block parameters GUI.

#include "graph.h"

adf::simulation::platform<2,2> platform("data/input0.txt", "data/input1.txt", "data/output0.txt", "data/output1.txt");

mygraph g;

adf::connect<> i0(platform.src[0], g.datain[0]);
adf::connect<> i1(platform.src[1], g.datain[1]);

adf::connect<> o0(g.dataout[0], platform.sink[0]);
adf::connect<> o1(g.dataout[1], platform.sink[1]);


int main(int argc, char ** argv) { 
  int value;
  g.init();
  g.run();
  value = 1;
  g.update(g.control, value);
  value = 0;
  g.update(g.control, value);
  value = 0;
  g.update(g.control, value);
  value = 1;
  g.update(g.control, value);
  g.end();

}

When the GUI parameters are updated, click the Import button. After a successful import, the tool generates the graph database and updates the AI Engine graph block with inputs and outputs. The GUI interface is as shown in the following figure.

Figure 3. AI Engine Graph Updated

After import, the Function tab GUI displays as shown in the following figure. This includes parameters such as Data Type and Size which are automatically captured from the graph code.

Figure 4. Function Tab

The user-editable function configuration parameters (Graph Port Name and Signal size) are described in the following table.

Table 2. Parameters
Use-Editable Parameter Criticality Description
Graph Port Name Mandatory Enter the port names for all interfaces as specified in the graph header file (graph.h).
Snippet of graph.h
 public:
    adf::port<input> datain[2];
    adf::port<output> dataout[2];
    adf::port<input> control;
Signal size Mandatory This parameter represents the size of the output signal and should be set to a value equal to or greater than the number of samples that are produced at every invocation of the kernel.

In the General tab, the Import button changes to Update, enabling further update of block parameters.

Figure 5. General Tab
Important:
  • To connect an AI Engine graph inout port to an AI Engine graph input RTP port, the synchronocities of both ports must be compatible, otherwise, an appropriate error is reported by Model Composer.
  • If the RTP port's behavior is different from its default behavior, the connection should appropriately specify it as an async or sync port in graph code.