Skip to content

Commit

Permalink
add inspection.md and address some of David's comments
Browse files Browse the repository at this point in the history
  • Loading branch information
yamaguchi1024 committed Oct 29, 2024
1 parent 32a2a4a commit 2523444
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 6 deletions.
11 changes: 6 additions & 5 deletions docs/Design.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ One of the main ideas behind Exo is **exocompilation**, which allows users to de
- The cost of adding support for new hardware is significantly reduced.
- Proprietary details of hardware can be protected.

Users can model custom memories, instructions, and configuration state in libraries to target a specific accelerator. These hardware abstractions can then be used to write hand-optimized code or as building blocks for higher-level scheduling transformations.
Users can model custom [memories](./memories.md), [instructions](./instructions.md), and configuration state in libraries to target a specific accelerator. These hardware abstractions can then be used to write hand-optimized code or as building blocks for higher-level scheduling transformations.

More info can be found in the [PLDI paper](https://people.csail.mit.edu/yuka/pdf/exo_pldi2022_full.pdf) and [instructions.md](./instructions.md) and [memories.md](./memories.md).
More info can be found in the [PLDI paper](https://people.csail.mit.edu/yuka/pdf/exo_pldi2022_full.pdf), [instructions.md](./instructions.md), and [memories.md](./memories.md).

## Fine-Grained Primitives for Performance Control

Expand All @@ -45,16 +45,17 @@ The rewrite-based approach offers several advantages:

While the flexibility of fine-grained primitives is necessary for achieving peak performance, directly using them can be verbose and laborious. To address this, Exo allows users to define new higher-level scheduling operations by composing the core primitives.

These user-defined scheduling operations can encapsulate common optimization patterns and hardware-specific transformations, greatly improving productivity. They can be put together in reusable libraries, further enabling modularity and portability.
These user-defined scheduling operations can encapsulate common optimization patterns and hardware-specific transformations such as auto-vectorize, tiling, and even simulate scheduling operations from other USLs (like Halide's `compute_at`).
They can be put together in reusable libraries, further enabling modularity and portability.

More infomation can be found in the [ASPLOS paper](.) and [Cursor.md](./Cursor.md).

## The AIR Framework: Action, Inspection, Reference

We identified that Action, Inspection, and Reference are the key scheduling language design mechanisms that enable user-defined scheduling operations.

- **Actions** are the scheduling primitives that transform the code (e.g., `divide_loop`, `reorder`).
- **Inspections** query properties of the code (e.g., loop bounds, memory access patterns).
- **[Actions](./primitives)** are scheduling operations that transform the code. This could be compiler-provided *primitive actions* (e.g., `divide_loop`, `reorder`), or *user-defined* (e.g., tile2D in the ASPLOS paper).
- **[Inspections](./inspection.md)** query properties of the code (e.g., loop bounds, memory access patterns).
- **References** point to specific parts of the code to apply actions to.

Together, AIR allows scheduling operations to be defined as composable rewrites on the code. The language implementation guarantees the correctness of these primitive rewrites with a set of effect analyses.
Expand Down
3 changes: 3 additions & 0 deletions docs/Imports.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

This document provides an overview of the imports used when writing Exo.

Exo's parser only resolves names in the local and global namespaces, and Exo reserves the attribute syntax (foo.bar) for configurations.
Therefore, if users wish to utilize Exo constructs, they must import them into their local namespace.

## Table of Contents

1. [Standard Python Future Import](#1-standard-python-future-import)
Expand Down
3 changes: 2 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ This directory provides detailed documentation about Exo's interface and interna
- To learn about the design principles of Exo, read [Design.md](Design.md).
- To understand how the Exo system is implemented, read [System.md](System.md).
- For information on writing Exo object code, APIs, and imports, refer to [Procedures.md](Procedures.md), [object_code.md](object_code.md), and [Imports.md](Imports.md).
- To learn how to define memory, instructions, and externs externally to the compiler in the user code, refer to [externs.md](externs.md), [instructions.md](instructions.md), and [memories.md](memories.md).
- To learn how to define **hardware targets externally to the compiler**, refer to [externs.md](externs.md), [instructions.md](instructions.md), and [memories.md](memories.md).
- To learn how to define **new scheduling operations externally to the compiler**, refer to [Cursors.md](./Cursors.md) and [inspection.md](./inspection.md).
- To understand the available scheduling primitives and how to use them, look into the primitives/ directory.

The scheduling primitives are classified into six categories:
Expand Down
50 changes: 50 additions & 0 deletions docs/inspection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# External Inspection Functions

Inspection is a metaprogramming feature that enables metaprograms (like schedules) to dynamically examine the properties of object code. Exo provides inspection through [Cursors](./Cursors.md), allowing users to examine standard AST properties such as variable names, literal expression values, and annotations (e.g., memory spaces and precisions) at scheduling time. Cursors also support local AST navigation, for example, accessing loop bounds (`loop.hi()`) and bodies (`loop.body()`). Inspection functions can be written externally from the Exo compiler, giving users the ability to customize them according to their needs.
For convinience, standard library inspection functions are provided as `exo.stdlib.inspection` module.

Cursor types (such as `ForCursor` and `IfCursor`) are defined in `exo.API_cursors`, so you should import it when writing inspection functions:

```python
from exo.API_cursors import *
```

Here are some simple inspection functions:

```python
def is_loop(proc, loop):
loop = proc.forward(loop)
return isinstance(loop, ForCursor)

def get_top_level_stmt(proc, c):
c = proc.forward(c)

while not isinstance(c.parent(), InvalidCursor):
c = c.parent()
return c
```

Explanation:
- The `is_loop` function takes a `proc` object and a `loop` cursor as input. It forwards the `loop` cursor using `proc.forward(loop)` and checks if the resulting cursor is an instance of `ForCursor`. This function determines whether the given cursor points to a loop statement.
- The `get_top_level_stmt` function takes a `proc` object and a cursor `c` as input. It forwards the cursor `c` using `proc.forward(c)` and then iteratively moves the cursor to its parent using `c.parent()` until it reaches an `InvalidCursor`, which means the cursor reached the outer-most level of the procedure. This function finds the top-level statement that wraps the given cursor.

Exo also exposes `ExoType` for expression types (defined in `src/exo/API_types.py`), which users can access using constructs like `ExoType.F16` and branch on it.

```python
class ExoType(Enum):
F16 = auto()
F32 = auto()
F64 = auto()
UI8 = auto()
I8 = auto()
UI16 = auto()
I32 = auto()
R = auto()
Index = auto()
Bool = auto()
Size = auto()
Int = auto()
Stride = auto()
```

All the Cursor types and the kind of navigation you can perform on them are documented in [Cursors.md](./Cursors.md).

0 comments on commit 2523444

Please sign in to comment.