cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

AI Engine Series 2 - Introduction to AI Engine graphs

florentw
Moderator
Moderator
10 0 1,017

Introduction

In the previous article, we had a first look at an AI Engine (AIE) application for Versal™ within the Vitis™ 2020.2 unified software platform.

We have seen the structure of an AIE application project and how an AIE graph is connected to a simulation platform. We also looked at some APIs to initialize, run and terminate the graph. In this article we will have a closer look at the AIE graph inside the project.

This was the view we had on the project from the previous article, with the AIE graph shown as a black box:

01.jpg

 

In this article we will look at what is inside the mygraph graph.

 

Requirements

 

The following article requires that you have gone through the AI Engine Series 1 article.

 

Introduction to AI Engine Graphs

 

The Adaptive Data Flow (ADF) graphs are the higher level for the AIE applications. They are written in C++ and consist of nodes and edges where nodes represent compute kernel functions and/or sub-graphs and edges represent data connections. All ADF graph class definitions are a subclass of the predefined dataflow graph class adf::graph and must be located in a header file.

Multiple ADF graph definitions can be included in the same header file. This class header file should be included in the main application file where the actual top-level graph is declared in the file scope.

Graphs are compiled and executed using the AI Engine tool chain integrated into the Vitis 2020.2 unified software platform.

It is important to note that graphs are statically defined, mapped and compiled (they do not change during runtime).

Open the file project.h from the template project which was imported during the previous article.

This is the content of the file:

2.JPG

 

The include headers (Line 3 > Line 5) add the adf dataflow library (adf.h) and the kernel functions prototypes (kernels.h).

From line 8 to line 14:

class simpleGraph : public adf::graph {
   private:
      kernel first;
      kernel second;
   public:
      input_port in;
      output_port out;

 

  • There is a graph declared based on the graph class adf::graph (line 8).
  • 2 kernels, called first and second respectively, are declared inside the graph with private member access (line 9 to 11)
  • This graph has one input port called in and one output port called out (line 12 to 14)

Based on this, we can update our view of the mygraph graph as follow:

3.jpg

Line 15 to line 29 contain the constructor function of the graph:

simpleGraph(){
 
    first = kernel::create(simple);
    second = kernel::create(simple);
    connect< window<128> > net0 (in, first.in[0]);
    connect< window<128> > net1 (first.out[0], second.in[0]);
    connect< window<128> > net2 (second.out[0], out);
 
    source(first) = "kernels/kernels.cc";
    source(second) = "kernels/kernels.cc";
 
    runtime<ratio>(first) = 0.1;
    runtime<ratio>(second) = 0.1;
 
  }

 

On lines 17 and 18, the two kernels are created and associated to the function named "simple".

Lines 19 to 21 add the connectivity information:

  • On line 19, the input of the first kernel (first.in[0]) is connected to the input of the graph (in). The connection is called net0 and is a window of 128 bytes (we will go through the type of connections in the next article)
  • On line 20, the input of the second kernel (second.in[0]) is connected to the output of the first kernel (first.out[0]). The connection is called net1 and is a window of 128 bytes.
  • On line 21, the output of the second kernel (second.out[0]) is connected to the output of the graph (out). The connection is called net1 and is a window of 128 bytes.

On lines 23 and 24, the kernels are associated to the source file containing the function ("simple") which is to be executed.

Finally, a run-time ratio of 0.1 is applied to both kernels. That means that both kernels are estimated to run at 10% of the processing time of a single AI Engine. We will see the impact of the run-time ratio in a later article.

Based on the details above, we can draw a view of the mygraph graph as follows:

04.jpg

 

In the next article we will take a closer look at the kernels.

Tags (1)