AIRCC - The AIR Compiler Driver

Overview

aircc 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

## Compilation pipeline

`aircc` 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` command 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`:
```c++
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>
}

}