Global Graph-Scoped Tables - 2024.2 English - UG1603

AI Engine-ML Kernel and Graph Programming Guide (UG1603)

Document ID
UG1603
Release Date
2024-11-28
Version
2024.2 English

While the previous example only includes an eight entry look-up table accessed as a global variable, many other algorithms require much larger look-up tables. Because AI Engine-ML local memory is at a premium, it is much more efficient for the AI Engine-ML compiler to manage the look-up table explicitly for specific kernels than to leave a large amount of stack or heap space on every processor. Such tables should not be declared static in the kernel header file.

#ifndef USER_PARAMETER_H
#define USER_PARAMETER_H

#include <adf.h>

int16 lutarray[8] = {1,2,3,4,5,6,0,0} ; 

#endif

The kernel source continues to include the header file and use the table as before. But, now you must declare this table as extern in the graph class header and use the parameter::array(…) function to create a parameter object explicitly in the graph. You also need to attach this parameter object to the kernel as shown in the following code:

#include <adf.h>
extern int16 lutarray[8];
class simple_lut_graph : public graph {
public:
  kernel k;
  parameter p;

  simple_lut_graph() {
    k = kernel::create(simple);
    p = parameter::array(lutarray);
    connect<>(p,k);
    ...
  }
}

Including this explicit specification of the look-up table in the graph description ensures that the compiler is aware of the requirement to reserve a suitably sized piece of memory for the look-up table when it allocates memory for kernel input and output buffers.

Following is an example graph code for constraining LUTs to different banks to avoid conflicts:
using namespace adf;
const int size=1024;
extern int16 lnr_lutab[size*2*2];
extern int16 lnr_lutcd[size*2*2];

class adaptive_graph : public graph
{
  public:
    input_plio in;
    output_plio out;
    kernel k;

  adaptive_graph(){
    k = kernel::create(linear_approx);
    source(k) = "linear_approx.cc";    in=input_plio::create("Datain10", plio_64_bits, "data/input1.txt");
    out=output_plio::create("Dataout1", plio_64_bits, "data/output1.txt");    runtime<ratio>(k) = 0.8;

    auto buf_lnr_ab = parameter::array(lnr_lutab);
    auto buf_lnr_cd = parameter::array(lnr_lutcd);
    connect<>(buf_lnr_ab,k);
    connect<>(buf_lnr_cd,k);
    location<parameter>(buf_lnr_ab)={ address(8,1,0x8000) };//optional
    location<parameter>(buf_lnr_cd)={ address(8,1,0xC000) };//optional
    location<buffer>(k.out[0])={ address(8,0,0x8000),address(8,0,0xC000) };//optional
    location<stack>(k)={ address(8,1,0x4000) };//optional
    location<buffer>(k.in[0])={ address(8,0,0x0000), address(8,0,0x4000) };//optional

    connect(in.out[0], k.in[0]);
    connect(k.out[0], out.in[0]);
    adf::dimensions(k.in[0])={1024};//elements
    adf::dimensions(k.out[0])={1024};//elements
  }
};