You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Shard Kani verification workflow across multiple runners by:
1. Running `kani list --format json`, which outputs a JSON file like
this:
```json
{
"kani-version": "0.56.0",
"file-version": "0.1",
"standard-harnesses": {
"src/lib.rs": [
"proof3",
"verify::proof2"
],
"src/test.rs": [
"test::proof4",
"test::proof5"
]
},
"contract-harnesses": {
"src/lib.rs": [
"proof"
]
},
"contracts": [
{
"function": "bar",
"file": "src/lib.rs",
"harnesses": [
"proof"
]
}
],
"totals": {
"standard-harnesses": 4,
"contract-harnesses": 1,
"functions-under-contract": 1
}
}
```
2. Extracting the harnesses inside `"standard-harnesses"` and
`"contract-harnesses"` into an array called `ALL_HARNESSES` and the
length of that array into `HARNESS_COUNT`. (So in this example,
`ALL_HARNESSES = [proof3, verify::proof2, test::proof4, test::proof5,
proof]` and `HARNESS_COUNT=5`).
3. Dividing the harnesses evenly between four workers. For example, if
worker 1's harnesses are `proof3` and `verify::proof2`, then we call
`kani verify-std --harness proof3 --harness verify::proof2 --exact`. The
`--exact` makes Kani look for the exact harness name. This is important
so that we don't match on partial patterns, e.g., if there is a harness
called "foo" and a harness called "foo_bar", passing `--harness foo`
without `--exact` would match against both harnesses, and then `foo_bar`
would run twice.
4. Also parallelize verification within a single runner by passing `-j`
to Kani.
I chose four workers somewhat arbitrarily--it makes each worker take
about 45 minutes to an hour to finish. I thought it was good to have a
balance between too few workers (which still makes us wait a while) and
too many workers (which makes you look through more logs to find where a
given harness is being verified). But happy to play with this number if
people have opinions.
By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.
# Variables used for parallel harness verification
84
+
# When we say "parallel," we mean two dimensions of parallelization:
85
+
# 1. Sharding verification across multiple workers. The Kani workflow that calls this script defines WORKER_INDEX and WORKER_TOTAL for this purpose:
86
+
# we shard verification across WORKER_TOTAL workers, where each worker has a unique WORKER_INDEX that it uses to derive its share of ALL_HARNESSES to verify.
87
+
# 2. Within a single worker, we parallelize verification between multiple cores by invoking kani with -j.
88
+
89
+
# Array of all of the harnesses in the repository, set in get_harnesses()
90
+
declare -a ALL_HARNESSES
91
+
# Length of ALL_HARNESSES, set in get_harnesses()
92
+
declare -i HARNESS_COUNT
93
+
# `kani list` JSON FILE_VERSION that the parallel verification command expects
94
+
EXPECTED_JSON_FILE_VERSION="0.1"
95
+
80
96
# Function to read commit ID from TOML file
81
97
read_commit_from_toml() {
82
98
local file="$1"
@@ -151,10 +167,50 @@ get_kani_path() {
151
167
echo"$(realpath "$build_dir/scripts/kani")"
152
168
}
153
169
154
-
run_kani_command() {
170
+
# Run kani list with JSON format and process with jq to extract harness names and total number of harnesses.
171
+
# Note: The code to extract ALL_HARNESSES is dependent on `kani list --format json` FILE_VERSION 0.1.
172
+
# (The FILE_VERSION variable is defined in Kani in the list module's output code, current path kani-driver/src/list/output.rs)
173
+
# If FILE_VERSION changes, first update the ALL_HARNESSES extraction logic to work with the new format, if necessary,
174
+
# then update EXPECTED_JSON_FILE_VERSION.
175
+
get_harnesses() {
155
176
local kani_path="$1"
156
-
shift
157
-
"$kani_path""$@"
177
+
"$kani_path" list -Z list $unstable_args ./library --std --format json
178
+
local json_file_version=$(jq -r '.["file-version"]'"$WORK_DIR/kani-list.json")
179
+
if [[ $json_file_version!=$EXPECTED_JSON_FILE_VERSION ]];then
180
+
echo"Error: The JSON file-version in kani-list.json does not equal $EXPECTED_JSON_FILE_VERSION"
181
+
exit 1
182
+
fi
183
+
# Extract the harnesses inside "standard-harnesses" and "contract-harnesses"
184
+
# into an array called ALL_HARNESSES and the length of that array into HARNESS_COUNT
0 commit comments