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

miniBDD: added a non-recursive variant of APPLY #1144

Merged
merged 2 commits into from
Aug 3, 2017

Conversation

kroening
Copy link
Member

This adds a non-recursive variant of APPLY, for systems that have limited stacks.
The commit retains the recursive variant, which is much easier to read.

@kroening
Copy link
Member Author

A performance comparison would be interesting.

@kroening kroening requested review from tautschnig and mgudemann July 15, 2017 14:25
Copy link
Collaborator

@tautschnig tautschnig left a comment

Choose a reason for hiding this comment

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

See detailed comments plus all the linter's complaints.


G[key]=u;

return u;
}

mini_bddt mini_bdd_applyt::APP_non_rec(const mini_bddt &_x, const mini_bddt &_y)
{
struct e
Copy link
Collaborator

Choose a reason for hiding this comment

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

Contesting for the least descriptive type name of the year? :-) In absence of any comment, this isn't exactly helping readability.

Copy link
Contributor

Choose a reason for hiding this comment

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

it should also end on t

Copy link
Member Author

Choose a reason for hiding this comment

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

e -> et? ;)

Copy link
Contributor

Choose a reason for hiding this comment

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

technically, t would be ok

break;

default:
assert(false);
Copy link
Collaborator

Choose a reason for hiding this comment

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

There is no case other than INIT or FINISH, the default is unnecessary.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

e(mini_bddt &_result, const mini_bddt &_x, const mini_bddt &_y):
result(_result), x(_x), y(_y), var(0), phase(INIT) { }
mini_bddt &result, x, y, lr, hr;
std::pair<unsigned, unsigned> key;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is key not being initialised? (It is done via a separate assignment later on for some reason.)


G[key]=u;

return u;
}

mini_bddt mini_bdd_applyt::APP_non_rec(const mini_bddt &_x, const mini_bddt &_y)
{
struct e
Copy link
Contributor

Choose a reason for hiding this comment

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

it should also end on t

mini_bddt &result, x, y, lr, hr;
std::pair<unsigned, unsigned> key;
unsigned var;
enum { INIT, FINISH } phase;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd prefer

enum class phaset { INIT, FINISH};
phaset phase;

}
}

assert(u.is_initialized());
Copy link
Contributor

Choose a reason for hiding this comment

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

should be POSTCONDITION

assert(x.low().var()>t.var);
assert(y.low().var()>t.var);
assert(x.high().var()>t.var);
assert(y.high().var()>t.var);
Copy link
Contributor

Choose a reason for hiding this comment

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

INVARIANT instead of assert

Copy link
Member Author

Choose a reason for hiding this comment

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

This is un-obvious: there is some intent to maintain MiniBDD as a library that can be separately distributed.

Copy link
Collaborator

Choose a reason for hiding this comment

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

In that case please add linter overrides (and possibly the above explanation).

@mgudemann
Copy link
Contributor

@kroening I did some tests with EBMC on 4 smv models from AIG_SMV_08.tgz. Those were the ones I found that required less than 1m and more than just 1s. So the non-recursive variant is quicker on the micro-benchmark

Name Status recursive non-recursive
bj08vendingcycle.aig.smv KO 45.3s 41.8s
pdtvisvending06.aig.smv OK 7.6s 6.3s
pdtvisrethersqo1.aig.smv OK 43.8s 29.9s
pdtvisvending03.aig.smv OK 8.7s 7.1s

this is average run-time over 10 runs, with the patch for operator< applied, only difference is

commit db2da98cee960e4601dccc8c0cd34f73b11ff325
Author: Daniel Kroening <[email protected]>
Date:   Sat Jul 15 15:23:11 2017 +0100

    added a non-recursive variant of APPLY

@kroening
Copy link
Member Author

@mgudemann oh, wow, this is bigger than I thought it would be.

@kroening kroening force-pushed the miniBDD-non-recursive-apply branch from db2da98 to 8a8f5f2 Compare July 17, 2017 15:18
@mgudemann
Copy link
Contributor

@kroening I'll see whether I find others that use a non-trivial amount of time and also do not require excessive resources when using BDDs. The above are all converted from AIG, that may skew the results a bit. I'll see whether I find other .smv or Verilog files.

@kroening kroening force-pushed the miniBDD-non-recursive-apply branch from 8a8f5f2 to bda4ec5 Compare July 19, 2017 11:58
@kroening
Copy link
Member Author

Ready to go?

@mgudemann
Copy link
Contributor

I did a small benchmark on the .sv files of the regression tests which are compatible with the BDD engine

name status recursive non-recursive
viseisenberg.sv KO 4.53 4.42
eijks208o.sv OK 24.3 25.27
bobcount.sv OK 0.36 0.39
visbakery.sv KO 38.89 39.15

which shows a very slight advantage for the recursive variant with the exception of the first model. In conclusion I think the recursive version can be significantly worse (maybe if the recursion depth is very high?) and in the best case is slighly better (as it is shorter / less complex?)

Overall, this is ready for merge.

{
t.var=x.var();
t.phase=stack_elementt::phaset::FINISH;
assert(x.low().var()>t.var);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Linter overrides, please.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

case stack_elementt::phaset::INIT:
{
// dynamic programming
t.key=std::pair<unsigned, unsigned>(x.node_number(), y.node_number());
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think I've asked this before: why is this not part of the constructor?

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@kroening kroening force-pushed the miniBDD-non-recursive-apply branch from bda4ec5 to a71ca41 Compare July 20, 2017 21:32
@tautschnig tautschnig dismissed their stale review July 21, 2017 07:19

As said before I'm unhappy about the absence of tests, but I don't want to stand in the way of others approving of this.

@@ -22,6 +22,7 @@ Author: Daniel Kroening, [email protected]

void mini_bdd_nodet::remove_reference()
{
// NOLINTNEXTLINE(build/deprecated)
Copy link
Member

Choose a reason for hiding this comment

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

Use PRECONDITION(), INVARIANT(), etc from https://github.com/diffblue/cbmc/blob/master/src/util/invariant.h rather than silencing the linter.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Ok.

@kroening kroening merged commit 8e70eaa into master Aug 3, 2017
@kroening kroening deleted the miniBDD-non-recursive-apply branch August 3, 2017 20:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants