-
Notifications
You must be signed in to change notification settings - Fork 169
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 program analysis tool #198
Add program analysis tool #198
Conversation
@tohrnii - thank you for working on this! A few preliminary thoughts:
|
I think it should probably be a library which could then be used for front-end tooling or as a dependency for a binary |
I guess the question is where to put the library portion of the code and where to put the binaries. For example, we could put the actual code into the Another option is for |
This seems like the best way to go to me. |
Moved the library to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! I left a few comments inline.
dda81c8
to
9212b46
Compare
Thank you so much @bobbinth for the review. Made suggested changes. Please let me know if we should add rest of the analysis to the same pr or open another one. |
4987c10
to
945e478
Compare
On rebasing to latest next branch, the total number of vm cycles have changed. This seems to be related to PR #212 . For example for script |
@tohrnii - yes, this is mostly likely due to #212. The difference in count should come primarily form more
By the way, it may be a good metric to track: number of |
Thanks for the explanation on PR 212. I'll add NOOPs metric to be added as part of the program analysis tool to issue #138 as a comment. |
@tohrnii - let's add |
@bobbinth - Sounds good! |
Actually, I should say that counting NOOPs would be pretty difficult right now, but will become very easy once #195 is merges. So, let's wait until I'm done with decoder trace, and then we can finish this PR. |
79363c2
to
30285ed
Compare
cleanup print number of program blocks in the script change path to string refactor refactor more refactor based on review remove debug rebase next rename binary to mvt
@bobbinth - I've added Two pending analysis left to be addressed are:
I will address these in a separate PR after completing #226. |
6366068
to
16b3527
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! I left a few more comments inline.
a11b9d9
to
c3407d4
Compare
feat(core): add None operation feat(tools): add total noops to program analysis fix(processor): change operation type to Option<Operation>
c3407d4
to
4d9fa2c
Compare
4d9fa2c
to
4d46d39
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! A few more comments inline.
4d46d39
to
bb2133b
Compare
@bobbinth - Thank you for the review. Made suggested changes. |
miden/src/tools/mod.rs
Outdated
let mut noop_count = 0; | ||
|
||
for vm_state in vm_state_iterator { | ||
if matches!(vm_state.as_ref().unwrap().op, Some(Operation::Noop)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need the unwrap()
here? Would something like this work: matches!(vm_state.op, Some(Operation::Noop))
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh - I think it won't. I'm trying to think of a way to get rid of the unwrap
's here - ideally, we shouldn't have them in production code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess one thing that this doesn't account for is when a program terminates with an error. We should probably change the return type of analyze()
to return a Result<ProgramInfo, ExecutionError>
and then if we encounter an error it would be just returned instead of ProgramInfo
. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to think of a way to get rid of the unwrap's here - ideally, we shouldn't have them in production code.
Just to clarify, the reason is proper error propagation right?
Can we use something like:
for state in vm_state_iterator {
let vm_state = match state {
Ok(vm_state) => vm_state,
Err(err) => return Err(err)
};
if matches!(vm_state.op, Some(Operation::Noop)) {
noop_count += 1;
}
total_vm_cycles = vm_state.clk;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess one thing that this doesn't account for is when a program terminates with an error. We should probably change the return type of analyze() to return a Result<ProgramInfo, ExecutionError> and then if we encounter an error it would be just returned instead of ProgramInfo. What do you think?
Makes sense to propagate error here. Since there are two possible errors here, AssemblyError
while compiling the script and ExecutionError
while executing the script, should we add a new enum called AnalysisError
with those two variants and return that instead? That doesn't look very clean though. Is there a better (more idiomatic) way to handle that? Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes - the reason is proper error propagation, but also, as a general rule, I try not to have unwrap
's in non-test code.
Yes, let's add a new enum. We did something like this here. Though I don't love the name AnalysisError
. One other option that came to mind is MidenError
- but I don't love this one too much either.
The code snippet above looks right - though, I'd prefer to use map_err() instead of match
. For example, something like:
for state in vm_state_iterator {
let vm_state = state.map_err(...)?;
if matches!(vm_state.op, Some(Operation::Noop)) {
noop_count += 1;
}
total_vm_cycles = vm_state.clk;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe ProgramError
is better than the other options?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bobbinth - ProgramError
sounds good to me. For future, in general should we lean more towards verbosity or succinctness in naming things?
2025f59
to
8058c72
Compare
@bobbinth - Thank you for the review. Made suggested changes. |
8058c72
to
3de91a7
Compare
cargo fix change string to str fix comment fixes change analyze function return type to result remove std remove std add comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All looks good! Thank you!
Partly addresses #138
Adds a utility package to analyse any given script. Takes a source script as a file input and prints the following information.
Input:
proc.foo.1 pop.local.0 end begin popw.mem.1 push.17 exec.foo end
Output: