AIRCC - The AIR Compiler Driver

Overview

aircc.py is a compiler driver processing air programs. It takes the AIR MLIR dialect as input and produces AIE binaries plus host library code as output.

Usage

command line:

usage: aircc [-h] [-o OUTPUT_FILE] [--tmpdir tmpdir] [-v] [-row-offset ROW_OFFSET] [-col-offset COL_OFFSET] [-num-rows NUM_ROWS] [-num-cols NUM_COLS] [-cc CC]
             [--sysroot sysroot] [--host-target host_target] [--shared] [-xbridge]
             air_mlir_file

positional arguments:
  air_mlir_file         AIR Dialect mlir file

optional arguments:
  -h, --help            show this help message and exit
  -o OUTPUT_FILE        Output filename
  --tmpdir tmpdir       directory used for temporary file storage
  -v                    Trace commands as they are executed
  -row-offset ROW_OFFSET
                        Default row offset for generated partitions
  -col-offset COL_OFFSET
                        Default column offset for generated partitions
  -num-rows NUM_ROWS    Default number of rows for generated partitions
  -num-cols NUM_COLS    Default number of rows for generated partitions
  -cc CC                Compiler to use
  --sysroot sysroot     sysroot for cross-compilation
  --host-target host_target
                        Target architecture of the host program
  --shared              Generate a shared library (.so) instead of the default of a static library (.a)
  -xbridge              pass --xbridge to aiecc, otherwise pass --no-xbridge

Python:

import air.compiler.aircc.main as aircc

# same as command line options above, but as a python list
aircc_options = ['air.mlir', '--shared', '-o', 'air.mlir.so']
aircc.run(air_module, aircc_options)

Compilation pipeline

aircc.py runs several code transformations and tools to generate executable code from AIR dialect.

The first steps are to:

  • Run herd placement (air-place-herds) using the aircc.py commmand line options
  • Run AIR dialect to AIE dialect conversion (air-to-aie)

The air-to-aie pass will generate an AIE dialect MLIR module for each AIR dialect partition in the program and will add runtime metadata to the AIR dialect program.

Lowering of control code

The AIR dialect program is lowered to control code with the following pipeline:

  • Run air-to-std to generate AIRRt dialect from AIR dialect.
  • Run airrt-to-llvm to lower AIRRt dialect to LLVM dialect
  • Bufferize any remaing tensors
  • Lower standard dialects (linalg, scf, memref, …) to LLVM dialect
  • Translate LLVM dialect to LLVM IR (aie-translate)
  • Compile LLVM IR to object code (opt and clang)

Lowering of AIE code

For each AIE dialect module generated by the air-to-aie pass, aircc will:

  • Run aiecc.py on the AIE dialect module. This generates an AIE .elf file for every core in every herd in the partition and generates C++ code to configure the partition at runtime (using the -aie-generate-xaiev2 option).
  • Generate a C++ wrapper defining a namespace to hold each partition’s configuration code. This makes the configuration code accessible to the AIR runtime and to user programs. An example is shown below.

The generated C++ wrappers are compiled and linked with the controlled code generated by the MLIR passes into a single library. This can be a shared library to be loaded at runtime or a static library linked into an executable. The AIE .elf files are not part of the generated library and must be available to load into memory at runtime.

Example C++ wrapper generated by aircc.py:

namespace air::partitions {

// One namespace for each partition in the
// program using the MLIR symbol names
namespace partition_0 {
#include <air_project/partition_0/aie_inc.cpp>
}
namespace partition_1 {
#include <air_project/partition_1/aie_inc.cpp>
}

}