-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
By default, SLOTHY includes a 'selfcheck' verifying that the DFGs of input and output are isomorphic with respect to the rescheduling found by SLOTHY. This selfcheck is very powerful and should catch most modelling errors in SLOTHY. However, some aspects of SLOTHY remain outside of the scope of the DFG-based selfcheck: - Address offset fixup This is a historically rather error prone feature to which the self-check is blind (since it relies on making the DFG blind to address increments). - Loop boundaries If SW pipelining is enabled, the selfcheck checks equivalence of a _bounded unrolling_ of the input and output loops. Therefore, it would not catch issues with (a) the loop boundary, or (b) exceptional iterations for low loop counts. While it is not SLOTHY's goal to provide formal guarantees of correctness of the optimizations -- this should be gauged/confirmed through extensive test and ideally formal verification -- development would be faster if bugs in the aforementioned areas were caught before the developer integrates and tests the SLOTHY output manually. As a step towards catching more potential pitfalls early in the SLOTHY workflow, this commit starts the development of an _equivalence tester_. The idea of the equivalence tester is simple: Just run original and optimized assembly with various random inputs, and check that they indeed lead to equivalent outputs. This commit implements this idea for AArch64, leveraging the keystone assembler and the unicorn emulation framework. Extending the checker to other architectures is left for future commits. Another initial limitation is support for loops: For now, the equivalence checker tests bounded unrollings of loops, just like the selfcheck. That is against the point of the equivalenc check, but it will be improved at a later point, after some refactoring of the loop generation code. The checker added in this commit is able to detect issues with address offset fixup, however, which would previously have gone unnoticed by the selfcheck. The new equivalence test is configured via config.selftest, which is enabled by default, but silently skipped for unsupported platforms or target architectures.
- Loading branch information
1 parent
13f38d0
commit b1e7899
Showing
11 changed files
with
1,460 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
checker: kernel0.i kernel1.i harness.S checker.c harness_config.i | ||
gcc harness.S checker.c -o $@ | ||
|
||
run: checker | ||
./checker |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# AArch64 equivalence tester | ||
|
||
This directory contains an empirical equivalence tester for AArch64 assembly snippets. | ||
|
||
## Usage | ||
|
||
So far, the checker can only be used on AArch64 hosts; in principle, however, you can cross-compile and emulate it to | ||
run on x86_64 system too. | ||
|
||
* Copy the kernels to compare into `kernel0.i` and `kernel1.i`. | ||
* Configure the checker (see below) | ||
* Build the checker: `make checker` | ||
* Run the checker: `./checker` | ||
|
||
The checker will repeatedly run the assembly snippets with randomly chosen register inputs (GPR and FPR) and compare the final | ||
register states. The output is the set of registers that have been found to always agree across all tests. | ||
|
||
The checker also supports kernels accessing memory buffers, provided the base of the buffers is passed through GPRs. In | ||
this case, the checker will randomly generate initial memory contents, and compare the final memory contents. When | ||
memory contents differ, the checker fails. | ||
|
||
### Configuration | ||
|
||
You can configure the checker by adjusting `harness_config.i`: | ||
|
||
* With `#define KERNEL_STACK_SIZE XXX` you can indicate that the kernels assume memory of size `XXX` starting from | ||
`sp`. Note that you do not need to specify anything for the kernel(s) to use additional stack below `sp`. However, | ||
it is assumed that the kernels restore the original value of `sp` (otherwise, the checker will likely segfault). | ||
* With `#define FPR_FIX_VALUE_X{0-30} VALUE` you can omit random assignment to a GPR and instead force a given | ||
value. This is intended to force loop counters to sensible values. | ||
* With `#define KERNEL_MEMORY_IN_X{0-30} XXX` you can indicate that the kernels assume that a GPR is assumed to hold the | ||
base address of a buffer of size `XXX`. The checker will then allocate and randomly initialize such buffer, and set | ||
the GPR to point to ti. |
Oops, something went wrong.