When starting development on AI Engine graphs and kernels, it is critical to verify the design behavior. This is called functional simulation and it is useful in identifying errors in the design. For example, window sizes in the graph are related to the number of iterations in a kernel. Troubleshooting to see if every kernel in a large graph is absorbing and generating the right number of samples can be time consuming and iterative in nature. The x86 simulator is an ideal choice for testing, debugging, and verifying this kind of behavior because of the speed of iteration and the high level of data visibility it provides the developer. The x86 simulation does not provide timing, resource, or performance information. The x86 simulator is running exclusively on the tool development machine. This means its performance and memory use are defined by the development machine.
While the AI Engine simulator
fully models the memory of the AI Engine array
this also means that AI Engine simulator is
limited by the memory space of the AI Engine. The
x86 simulator is not limited by this and provides a nearly unlimited amount of debug
printf()s, large arrays, and variables. When
combined with the ability to single step through the kernel, very complex design
issues can quickly be isolated and addressed.
Several macros are provided to improve the kernel debug. These macros are intended for use with the x86 simulator and can be left in the code for maintainability purposes. With the benefits of the x86 simulator come some trade offs. There are several types of graph constructs that are not supported and cycle accurate behavior cannot be guaranteed to match between the AI Engine simulator and the x86 simulator. The x86 simulator is not a replacement for the AI Engine simulator. The AI Engine simulator must still be run on all designs to verify behavior and obtain performance information. For different stages of project development one tool or the other might better suit your needs.
To run the x86 simulator, change the AI Engine compiler target to
aiecompiler --target=x86sim graph.cpp
After the application is compiled for x86 simulation, the x86 simulator can be invoked as follows.
The complete x86 simulator command help is shown in the following code.
$ x86simulator [-h] [--help] [--h] [--pkg-dir=PKGDIR] optional arguments: -h,--help --h show this help message and exit --pkg-dir=PKG_DIR Set the package directory. ex: Work --timeout=secs Terminate simuation after specified number of seconds --dump Enable snapshots of data traffic on kernel ports --gdb Invoke from gdb --valgrind Run simulator under valgrind to detect access violoations --valgrind-gdb Run simulator under valgrind and debug via gdb server --valgrind-args=ARGS Override default options for valgrind. Used in conjunction with --valgrind. --stop-on-deadlock Stop simulation if deadlock is detected --trace Enable trace of kernel stall events --trace-print Print kernel stall events during simulation
The compiled binary for x86 native simulation is produced by the AI Engine compiler under the Work directory (see Compiling an AI Engine Graph Application) and is started automatically by the x86 simulator.
The input and the output files are specified in the following snippet of graph code.
adf::PLIO in1("In", adf::plio_32_bits, "In1.txt"); adf::PLIO out1("Out", adf::plio_32_bits, "Out1.txt"); simulation::platform<1,1> platform(&in1,&out1)
When running, the x86 simulator looks in the current working directory for data/In1.txt which is one of the inputs used by the ADF graph. To distinguish the output files for the x86 simulator from the output files for the AI Engine simulator the Out1.txt are located in current_working_dir/x86simulator_output/data/.
Optionally, the output files produced by the simulator can be compared with a golden output ignoring white space differences.
diff –w <data>/golden.txt <data>/output.txt