Skip to content

Commit

Permalink
Complete refactoring of packages dot md file from manual docs.
Browse files Browse the repository at this point in the history
  • Loading branch information
Arslan-e-Mustafa committed Mar 13, 2022
1 parent 4f2c30f commit fb4ad02
Showing 1 changed file with 9 additions and 9 deletions.
18 changes: 9 additions & 9 deletions docs/Manual/10 Packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,45 @@
[//]: # (Version: v1.2.1)

# Section 10: Building Packages
The Accera `Package` class represents a collection of Accera-generated functions. When a package is built, it creates a stand-alone function library that can be used by other pieces of software. Accera currently supports two package formats: HAT and MLIR.
The `Package` class in Accera represents a collection of Accera-generated functions. Whenever a package is built, it creates a stand-alone function library that other pieces of software can use. Currently, Accera supports two package formats: HAT and MLIR.

## HAT package format
[HAT](https://github.com/microsoft/hat) is a format for packaging compiled libraries in the C programming language. HAT stands for "Header Annotated with TOML", which implies that a standard C header is decorated with useful metadata in the TOML markup language.
[HAT](https://github.com/microsoft/hat) "Header Annotated with TOML" is a format for packaging compiled libraries in the C programming language. HAT implies that a standard C header is styled with useful metadata in the TOML markup language.

Say that `nest` contains some loop-nest logic. To build a HAT package that contains a function with this logic for the Windows operating system, we do the following:
Consider that `nest` holds a loop-nest logic. To build a HAT package containing a function with this logic for Windows Operation System, we need to write the following lines of code:
```python
package = acc.Package()
package.add(nest, base_name="func1")
package.build(format=acc.Package.Format.HAT_DYNAMIC, name="myPackage", platform=acc.Package.Platform.WINDOWS)
```

The result is two files: `MyPackage.hat` and `MyPackage.lib`. The output directory defaults to the current working directory. To change the output directory:
The result has two files: `MyPackage.hat` and `MyPackage.lib`. The output directory defaults to current working directory. Though we can change the output directory with this:

```python
package.build(format=acc.Package.Format.HAT_DYNAMIC, name="myPackage", platform=acc.Package.Platform.WINDOWS, output_dir="hat_packages")
```

## MLIR package format
MLIR format is mainly used for debugging purposes, and as a way to follow the multiple lowering MLIR stages, from Accera DSL all the way to runnable code.
MLIR format is primarily used for debugging purposes and for following the multiple lowering MLIR stages, from Accera DSL, all the way to runnable code.
```python
package.build(format=acc.Package.Format.MLIR, name="myPackage")
```

## Function names in packages
When a function is added to a package, the user specifies its base name. The full function name is the base name followed by an automatically generated unique identifier. For example, if the base name is "myFunc" then the function name could be "myFunc_8f24bef5". If no base name is given, the function name is just the automatically-generated unique identifier.
We can specify the base name of a function when it is added to a package. The full function name is the base name followed by an automatically generated unique identifier. For example, if the base name is "myFunc" then the function name could be "myFunc_8f24bef5". If no base name is defined, the automatically-generated unique identifier becomes the function name.

The unique identifier ensures that no two functions share the same name, but also makes it harder to call the function from client code. Specifically, each time that the Accera package is updated and rebuilt, the function name could change. Therefore, the HAT file also includes the client code to call the function without the unique identifier. Concretely, if the function signature in C is
The unique identifier ensures that no two functions share the same name. However, invoking the function from the client code becomes cumbersome because the function name could change each time the Accera package is updated and rebuilt. Therefore, the HAT file includes the client code to call the function without the unique identifier. Concretely, if the function signature in C is:
```
void myFunc_8f24bef5(const float* A, float* B);
```
then the HAT file also contains the line:
```
void (*myFunc)(const float* A, float* B) = myFunc_8f24bef5;
```
The above basically makes the abbreviated name `myFunc` a synonym of the full function name `myFunc_8f24bef5`. If multiple functions share the same base name, an arbitrary one of them gets the abbreviation.
The above code makes the abbreviated name `myFunc` an alias of the full function name `myFunc_8f24bef5`. If multiple functions share the same base name, one of them randomly gets the alias.

## Debug mode
A package can be built with the option `mode=acc.Package.Mode.DEBUG`. This creates a special version of each function that checks its own correctness each time the function is called. From the outside, a debugging package looks identical to a standard package. However, each of its functions actually contains two different implementations: the RoboCode implementation (with all of the fancy scheduling and planning) and the trivial default implementation (without any of the scheduling or planning). When called, the function runs both implementations and asserts that their outputs are within some predefined tolerance. If the outputs don't match, the function prints error messages to `stderr`.
A package can be built with` mode=acc.Package.Mode.DEBUG`. Doing so creates a special version of each function that validates its own correctness every time the function is called. From the outside, a debugging package looks identical to a standard package. However, each of its functions actually contains two different implementations: the RoboCode implementation (with all of the fancy scheduling and planning) and the trivial default implementation (without any scheduling or planning). When called, the function runs both implementations and asserts that their outputs are within the predefined tolerance. If the outputs don't match, the function prints error messages to `stderr`.
```python
package.build(format=acc.Package.Format.HAT_DYNAMIC, name="myPackage", mode=acc.Package.Mode.DEBUG, tolerance=1.0e-6)
```
Expand Down

0 comments on commit fb4ad02

Please sign in to comment.