Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add kani::spawn and an executor to the Kani library #1659

Merged
merged 46 commits into from
Jul 6, 2023

Conversation

fzaiser
Copy link
Contributor

@fzaiser fzaiser commented Sep 8, 2022

Description of changes:

This adds an executor (scheduler for async futures) to the Kani library, thus supporting kani::spawn as a replacement for tokio::spawn.

It also includes kani::yield_now which is similar to tokio::yield_now.

Resolved issues:

Resolves #1504

Call-outs:

Testing:

  • How is this change tested? Additional regression tests.

  • Is this a refactor change? No.

Checklist

  • Each commit message has a non-empty body, explaining why the change was made
  • Methods or procedures are documented
  • Regression or unit tests are included, or existing tests cover the modified code
  • My PR is restricted to a single feature or bugfix

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.

@fzaiser fzaiser requested a review from a team as a code owner September 8, 2022 20:53
@fzaiser fzaiser changed the title Add kani::spawn and an executor to the Kani library BLOCKED: Add kani::spawn and an executor to the Kani library Sep 9, 2022
Copy link
Contributor

@celinval celinval left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More tests please! :)

library/kani/src/futures.rs Outdated Show resolved Hide resolved
library/kani/src/futures.rs Outdated Show resolved Hide resolved
tests/kani/AsyncAwait/spawn.rs Outdated Show resolved Hide resolved
library/kani/src/futures.rs Show resolved Hide resolved
library/kani/src/futures.rs Show resolved Hide resolved
library/kani/src/futures.rs Outdated Show resolved Hide resolved
library/kani/src/futures.rs Show resolved Hide resolved
@fzaiser
Copy link
Contributor Author

fzaiser commented Sep 17, 2022

TODO: add check that the number of tasks is less than MAX_TASKS. Done

@fzaiser fzaiser changed the title BLOCKED: Add kani::spawn and an executor to the Kani library Add kani::spawn and an executor to the Kani library Oct 31, 2022
@fzaiser
Copy link
Contributor Author

fzaiser commented Oct 31, 2022

With the MIR linker, this is no longer blocked! Ready for review @danielsn @celinval

@fzaiser
Copy link
Contributor Author

fzaiser commented Nov 1, 2022

The latest CI run failed for spawn.rs: CBMC failed with status 137. Exit code 137 means that it ran out of memory, I think.

@celinval: could this be related to the new linker? If the scheduling code is in the same file, like in manual_spawn.rs, everything finishes quickly. (#1818 seems to be related?)

@celinval
Copy link
Contributor

celinval commented Nov 2, 2022

Yes,

The latest CI run failed for spawn.rs: CBMC failed with status 137. Exit code 137 means that it ran out of memory, I think.

@celinval: could this be related to the new linker? If the scheduling code is in the same file, like in manual_spawn.rs, everything finishes quickly. (#1818 seems to be related?)

Yes, the main purpose of the new linker was to get rid of the undefined symbols from the standard library. Fixing this issue meant that some models got bigger and harder to process.

@fzaiser
Copy link
Contributor Author

fzaiser commented Nov 3, 2022

Yes, the main purpose of the new linker was to get rid of the undefined symbols from the standard library. Fixing this issue meant that some models got bigger and harder to process.

@celinval That makes sense. What I don't get is that it works fine if all the scheduling code is in the same file, see manual_spawn.rs. This file uses the same code that this PR puts into the Kani library, but puts that code directly into the file with the harness. That seems to verify much more quickly, which does not make sense to me. Do you know why?

@celinval
Copy link
Contributor

celinval commented Nov 3, 2022

Yes, the main purpose of the new linker was to get rid of the undefined symbols from the standard library. Fixing this issue meant that some models got bigger and harder to process.

@celinval That makes sense. What I don't get is that it works fine if all the scheduling code is in the same file, see manual_spawn.rs. This file uses the same code that this PR puts into the Kani library, but puts that code directly into the file with the harness. That seems to verify much more quickly, which does not make sense to me. Do you know why?

I see. Let me take a look, but it is possible that moving the file into a different crate changed how rustc optimizes the code.

@celinval
Copy link
Contributor

celinval commented Nov 3, 2022

I looked at the issue you mentioned, and I think the difference is due to the second harness in spawn.rs (nondeterministic_schedule). If you remove it, the time and problem size is basically the same independent on the location of the scheduling code.

The interesting thing is that the time is pretty bad even if you run --harness deterministic_schedule. That's probably because we perform reachability analysis for all harnesses at the same time, instead of doing them separately. My guess is that CBMC slicer is not smart enough to prune the closures out of the model due to a more conservative pointer analysis.

You can see a similar effect with the --legacy-linker by just moving the scheduling code to spawn.rs. If you run kani --harness deterministic_schedule --legacy-linker with and without the second harness co-located in spawn.rs, the times are drastically different. In my machine, Kani verification succeeds after 70ish seconds if you remove the second harness, but it doesn't finish under 5min if you add the second one.

@fzaiser
Copy link
Contributor Author

fzaiser commented Nov 4, 2022

@celinval Thanks for that investigation. I've removed the nondeterministic test for now to make CI (hopefully) pass. I've also converted a bool to an enum and improved the documentation.

@fzaiser
Copy link
Contributor Author

fzaiser commented Nov 4, 2022

Hm, seems like CI still runs out of memory. I'm not sure what to do about that. Any ideas?

@celinval
Copy link
Contributor

celinval commented Nov 4, 2022

Can you run it locally and measure the memory consumption so we have an idea on how bad the problem is?

@fzaiser
Copy link
Contributor Author

fzaiser commented Feb 15, 2023

@celinval I renamed the function spawnable_block_on to block_on_with_spawn as I think this name is clearer. ("spawnable" sounds like "can be spawned" instead of "can spawn")

If you don't have any other concerns, this should be ready to be merged.

@fzaiser
Copy link
Contributor Author

fzaiser commented Feb 27, 2023

@danielsn @celinval friendly reminder :)

@celinval
Copy link
Contributor

@dsn @celinval friendly reminder :)

Sorry about that. Let me take a look

@celinval
Copy link
Contributor

celinval commented Mar 1, 2023

Hi @fzaiser, I think this is good to go, except that I think we should add a mechanism to guard this code under a unstable flag. Let me just sketch something quick and we can merge this. Thanks!

@celinval
Copy link
Contributor

celinval commented Mar 8, 2023

@fzaiser I created #2281 to get some feedback. Feel free to add comments there, but it should be a very quick change (famous last words).

@fzaiser fzaiser mentioned this pull request Mar 13, 2023
4 tasks
@celinval
Copy link
Contributor

I created #2373 to add the unstable attribute and I'm planning to create another one to enforce the opt-in model.

Once #2373 is merged, I believe you can just tag the public APIs from this PR as unstable and we can merge these changes.

@celinval
Copy link
Contributor

celinval commented May 4, 2023

Hi @fzaiser, I just wanted to let you know that we have merged the unstable API code, so you should be good to go. Please tag all public functions in this PR as unstable.

celinval added a commit that referenced this pull request May 16, 2023
Kani compiler used to generate one `goto-program` for all harnesses in one crate. In some cases, this actually had a negative impact on the harness verification time. This was first reported in #1659

The main changes were done in the compiler's module `compiler_interface` and the module `project` from the driver. The compiler will now gather all the harnesses beforehand and it will perform reachability + codegen steps for each harness. All files related to a harness `goto-program` will follow the naming convention bellow:
```
<BASE_NAME>_<MANGLED_NAME>.<EXTENSION>
```
This applies to symtab / goto / type_map / restriction files.

The metadata file is still generated once per target crate, and its name is still the same (`<BASE_NAME>.kani-metadata.json`).

On the driver side, the way we process the artifacts have changed. The driver will now read the metadata for each crate, and collect all artifacts based on the symtab goto file that is recorded in the metadata of each harness.

These changes do not apply for `--function`. We still keep all artifacts based on the crate's `<BASE_NAME>` and we have a separate logic to handle that. Fixing this is captured by #2129.
@fzaiser
Copy link
Contributor Author

fzaiser commented Jun 23, 2023

@celinval This should be good to go :) Could you please merge this if you're happy with it?

@fzaiser
Copy link
Contributor Author

fzaiser commented Jun 23, 2023

I'm not sure what the perf-benchcomp failure is about. Could it be spurious? Any ideas?

@zhassan-aws
Copy link
Contributor

I'm not sure what the perf-benchcomp failure is about. Could it be spurious? Any ideas?

Yes, this is most likely spurious due to variance in performance. The perf-benchcomp workflow is not blocking for merges.

Copy link
Contributor

@celinval celinval left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Can you please add a reason to the unstable attribute? It could be something "recently added" or something like "experimental API". @adpaco-aws any suggestion?

@adpaco-aws
Copy link
Contributor

Thanks! Can you please add a reason to the unstable attribute? It could be something "recently added" or something like "experimental API". @adpaco-aws any suggestion?

I'd suggest "experimental async support/library" or something along those lines.

Also, thanks @fzaiser for persistence on this one!

@celinval celinval enabled auto-merge (squash) July 6, 2023 17:24
@celinval celinval merged commit 2be57b4 into model-checking:main Jul 6, 2023
12 of 13 checks passed
@fzaiser
Copy link
Contributor Author

fzaiser commented Jul 10, 2023

@celinval Thanks for reviewing and making the final changes for the merge! 🎉

celinval added a commit that referenced this pull request Jul 27, 2023
…unctions (#1661)

Instead of having to manually wrap the code in `kani::spawnable_block_on` as in #1659, this PR allows `#[kani::proof]` to be applied to harnesses that use `spawn` as well. For this to happen, the user has to specify a scheduling strategy.

Co-authored-by: Celina G. Val <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement kani::spawn
7 participants