In this mode the top level application can be written inside graph.cpp
file. The application contains an instance of ADF graph and a main function within which API’s are called to initialize, run, and end the graph. It may also have additional API’s to update Run time parameters. Additionally for hw emulation / hw run modes, the ‘main()
’ function can be guarded by a #ifdef
to ensure graph is only initialized once, or run only once. The following example code is the simple application defined in Creating a Data Flow Graph (Including Kernels) with the additional guard macro __AIESIM__ and __X86SIM__.
// Virtual platform ports
inptr = input_plio::create("DataIn1", adf::plio_128_bits, "data/input_128x16.txt");
outptr = output_plio::create("DataOut1", adf::plio_128_bits, "data/output.txt");
// Virtual platform connectivity
connect<>(inptr.out[0], k1.in[0]);
connect<parameter>(kernelCoefficients, async(k1.in[1]));
connect<>(k1.out[0], outptr.in[0]);
#define SRS_SHIFT 10
float kData[9] = {0.0625, 0.1250, 0.0625, 0.125, 0.25, 0.125, 0.0625, 0.125, 0.0625};
#if defined(__AIESIM__) || defined(__X86SIM__)
int main(int argc, char** argv) {
filter_graph.init();
filter_graph.update(filter_graph.kernelCoefficients, float2fixed_coeff<10, 16>(kData).data(), 16);
filter_graph.run(1);
filter_graph.end();
return 0;
}
#endif
In case GMIO based ports are used.
#if defined(__AIESIM__) || defined(__X86SIM__)
int main(int argc, char** argv) {
...
...
int16_t* inputData = (int16_t*)GMIO::malloc(BLOCK_SIZE_in_Bytes);
int16_t* outputData = (int16_t*)GMIO::malloc(BLOCK_SIZE_in_Bytes);
//Prepare input data
...
...
filter_graph.init();
filter_graph.update(filter_graph.kernelCoefficients, float2fixed_coeff<10, 16>(kData).data(), 16);
filter_graph.run(1);
//GMIO Data transfer calls
gmioIn[0].gm2aie_nb(inputData, BLOCK_SIZE_in_Bytes);
gmioOut[0].aie2gm_nb(outputData, BLOCK_SIZE_in_Bytes);
gmioOut[0].wait();
printf("after grph wait\n");
filter_graph.end();
...
}
#endif