swarming: add support everywhere
Swarming implies that a single instance of the kripke structure (or product) will be explored by diffrent threads with their own exploration order. Most of the modification aims to have a thread safe kripke structure. * spot/kripke/kripke.hh, spot/ltsmin/ltsmin.cc, spot/ltsmin/ltsmin.hh, spot/mc/ec.hh, spot/mc/intersect.hh, spot/mc/reachability.hh, spot/misc/hash.hh, spot/twacube/twacube.hh, tests/core/twacube.test, tests/ltsmin/modelcheck.cc: here.
This commit is contained in:
parent
ae1a3601e6
commit
72948661e9
10 changed files with 248 additions and 119 deletions
|
|
@ -45,10 +45,10 @@ namespace spot
|
|||
|
||||
public:
|
||||
ec_renault13lpar(kripkecube<State, SuccIterator>& sys,
|
||||
twacube_ptr twa)
|
||||
twacube_ptr twa, unsigned tid, bool stop)
|
||||
: intersect<State, SuccIterator, StateHash, StateEqual,
|
||||
ec_renault13lpar<State, SuccIterator,
|
||||
StateHash, StateEqual>>(sys, twa),
|
||||
StateHash, StateEqual>>(sys, twa, tid, stop),
|
||||
acc_(twa->acc()), sccs_(0U)
|
||||
{
|
||||
}
|
||||
|
|
@ -114,6 +114,8 @@ namespace spot
|
|||
}
|
||||
roots_.back().acc |= cond;
|
||||
found_ = acc_.accepting(roots_.back().acc);
|
||||
if (SPOT_UNLIKELY(found_))
|
||||
this->stop_ = true;
|
||||
return found_;
|
||||
}
|
||||
|
||||
|
|
@ -147,7 +149,7 @@ namespace spot
|
|||
acc_cond::mark_t acc = 0U;
|
||||
|
||||
bfs.push(new ctrx_element({&this->todo.back().st, nullptr,
|
||||
this->sys_.succ(this->todo.back().st.st_kripke),
|
||||
this->sys_.succ(this->todo.back().st.st_kripke, this->tid_),
|
||||
this->twa_->succ(this->todo.back().st.st_prop)}));
|
||||
while (true)
|
||||
{
|
||||
|
|
@ -160,7 +162,7 @@ namespace spot
|
|||
while (!front->it_prop->done())
|
||||
{
|
||||
if (this->twa_->get_cubeset().intersect
|
||||
(this->twa_->trans_data(front->it_prop).cube_,
|
||||
(this->twa_->trans_data(front->it_prop, this->tid_).cube_,
|
||||
front->it_kripke->condition()))
|
||||
{
|
||||
const product_state dst = {
|
||||
|
|
@ -181,7 +183,8 @@ namespace spot
|
|||
// This is a valid transition. If this transition
|
||||
// is the one we are looking for, update the counter-
|
||||
// -example and flush the bfs queue.
|
||||
auto mark = this->twa_->trans_data(front->it_prop).acc_;
|
||||
auto mark = this->twa_->trans_data(front->it_prop,
|
||||
this->tid_).acc_;
|
||||
if (!acc.has(mark))
|
||||
{
|
||||
ctrx_element* current = front;
|
||||
|
|
@ -213,7 +216,7 @@ namespace spot
|
|||
const product_state* q = &(it->first);
|
||||
ctrx_element* root = new ctrx_element({
|
||||
q , nullptr,
|
||||
this->sys_.succ(q->st_kripke),
|
||||
this->sys_.succ(q->st_kripke, this->tid_),
|
||||
this->twa_->succ(q->st_prop)
|
||||
});
|
||||
bfs.push(root);
|
||||
|
|
@ -224,7 +227,7 @@ namespace spot
|
|||
const product_state* q = &(it->first);
|
||||
ctrx_element* root = new ctrx_element({
|
||||
q , nullptr,
|
||||
this->sys_.succ(q->st_kripke),
|
||||
this->sys_.succ(q->st_kripke, this->tid_),
|
||||
this->twa_->succ(q->st_prop)
|
||||
});
|
||||
bfs.push(root);
|
||||
|
|
@ -243,7 +246,7 @@ namespace spot
|
|||
virtual istats stats() override
|
||||
{
|
||||
return {this->states(), this->trans(), sccs_,
|
||||
(unsigned)roots_.size(), dfs_};
|
||||
(unsigned) roots_.size(), dfs_, found_};
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ namespace spot
|
|||
unsigned sccs;
|
||||
unsigned instack_sccs;
|
||||
unsigned instack_item;
|
||||
bool is_empty;
|
||||
};
|
||||
|
||||
/// \brief This class explores (with a DFS) a product between a
|
||||
|
|
@ -59,8 +60,8 @@ namespace spot
|
|||
{
|
||||
public:
|
||||
intersect(kripkecube<State, SuccIterator>& sys,
|
||||
twacube_ptr twa):
|
||||
sys_(sys), twa_(twa)
|
||||
twacube_ptr twa, unsigned tid, bool& stop):
|
||||
sys_(sys), twa_(twa), tid_(tid), stop_(stop)
|
||||
{
|
||||
SPOT_ASSERT(is_a_kripkecube(sys));
|
||||
map.reserve(2000000);
|
||||
|
|
@ -87,10 +88,10 @@ namespace spot
|
|||
bool run()
|
||||
{
|
||||
self().setup();
|
||||
product_state initial = {sys_.initial(), twa_->get_initial()};
|
||||
product_state initial = {sys_.initial(tid_), twa_->get_initial()};
|
||||
if (SPOT_LIKELY(self().push_state(initial, dfs_number+1, 0U)))
|
||||
{
|
||||
todo.push_back({initial, sys_.succ(initial.st_kripke),
|
||||
todo.push_back({initial, sys_.succ(initial.st_kripke, tid_),
|
||||
twa_->succ(initial.st_prop)});
|
||||
|
||||
// Not going further! It's a product with a single state.
|
||||
|
|
@ -100,7 +101,7 @@ namespace spot
|
|||
forward_iterators(true);
|
||||
map[initial] = ++dfs_number;
|
||||
}
|
||||
while (!todo.empty())
|
||||
while (!todo.empty() && !stop_)
|
||||
{
|
||||
// Check the kripke is enough since it's the outer loop. More
|
||||
// details in forward_iterators.
|
||||
|
|
@ -113,8 +114,8 @@ namespace spot
|
|||
is_init,
|
||||
newtop,
|
||||
map[newtop])))
|
||||
{
|
||||
sys_.recycle(todo.back().it_kripke);
|
||||
{
|
||||
sys_.recycle(todo.back().it_kripke, tid_);
|
||||
// FIXME a local storage for twacube iterator?
|
||||
todo.pop_back();
|
||||
if (SPOT_UNLIKELY(self().counterexample_found()))
|
||||
|
|
@ -126,9 +127,9 @@ namespace spot
|
|||
++transitions;
|
||||
product_state dst = {
|
||||
todo.back().it_kripke->state(),
|
||||
twa_->trans_storage(todo.back().it_prop).dst
|
||||
twa_->trans_storage(todo.back().it_prop, tid_).dst
|
||||
};
|
||||
auto acc = twa_->trans_data(todo.back().it_prop).acc_;
|
||||
auto acc = twa_->trans_data(todo.back().it_prop, tid_).acc_;
|
||||
forward_iterators(false);
|
||||
auto it = map.find(dst);
|
||||
if (it == map.end())
|
||||
|
|
@ -136,7 +137,7 @@ namespace spot
|
|||
if (SPOT_LIKELY(self().push_state(dst, dfs_number+1, acc)))
|
||||
{
|
||||
map[dst] = ++dfs_number;
|
||||
todo.push_back({dst, sys_.succ(dst.st_kripke),
|
||||
todo.push_back({dst, sys_.succ(dst.st_kripke, tid_),
|
||||
twa_->succ(dst.st_prop)});
|
||||
forward_iterators(true);
|
||||
}
|
||||
|
|
@ -167,7 +168,7 @@ namespace spot
|
|||
|
||||
virtual istats stats()
|
||||
{
|
||||
return {dfs_number, transitions, 0U, 0U, 0U};
|
||||
return {dfs_number, transitions, 0U, 0U, 0U, false};
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
@ -190,7 +191,7 @@ namespace spot
|
|||
// There is no need to move iterators forward.
|
||||
SPOT_ASSERT(!(todo.back().it_prop->done()));
|
||||
if (just_pushed && twa_->get_cubeset()
|
||||
.intersect(twa_->trans_data(todo.back().it_prop).cube_,
|
||||
.intersect(twa_->trans_data(todo.back().it_prop, tid_).cube_,
|
||||
todo.back().it_kripke->condition()))
|
||||
return;
|
||||
|
||||
|
|
@ -207,7 +208,7 @@ namespace spot
|
|||
while (!todo.back().it_prop->done())
|
||||
{
|
||||
if (SPOT_UNLIKELY(twa_->get_cubeset()
|
||||
.intersect(twa_->trans_data(todo.back().it_prop).cube_,
|
||||
.intersect(twa_->trans_data(todo.back().it_prop, tid_).cube_,
|
||||
todo.back().it_kripke->condition())))
|
||||
return;
|
||||
todo.back().it_prop->next();
|
||||
|
|
@ -263,5 +264,7 @@ namespace spot
|
|||
visited_map map;
|
||||
unsigned int dfs_number = 0;
|
||||
unsigned int transitions = 0;
|
||||
unsigned tid_;
|
||||
bool& stop_; // Do not need to be atomic.
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ namespace spot
|
|||
class SPOT_API seq_reach_kripke
|
||||
{
|
||||
public:
|
||||
seq_reach_kripke(kripkecube<State, SuccIterator>& sys):
|
||||
sys_(sys)
|
||||
seq_reach_kripke(kripkecube<State, SuccIterator>& sys, unsigned tid):
|
||||
sys_(sys), tid_(tid)
|
||||
{
|
||||
SPOT_ASSERT(is_a_kripkecube(sys));
|
||||
visited.reserve(2000000);
|
||||
|
|
@ -54,15 +54,15 @@ namespace spot
|
|||
void run()
|
||||
{
|
||||
self().setup();
|
||||
State initial = sys_.initial();
|
||||
todo.push_back({initial, sys_.succ(initial)});
|
||||
State initial = sys_.initial(tid_);
|
||||
todo.push_back({initial, sys_.succ(initial, tid_)});
|
||||
visited[initial] = ++dfs_number;
|
||||
self().push(initial, dfs_number);
|
||||
while (!todo.empty())
|
||||
{
|
||||
if (todo.back().it->done())
|
||||
{
|
||||
sys_.recycle(todo.back().it);
|
||||
sys_.recycle(todo.back().it, tid_);
|
||||
todo.pop_back();
|
||||
}
|
||||
else
|
||||
|
|
@ -76,7 +76,7 @@ namespace spot
|
|||
self().push(dst, dfs_number);
|
||||
self().edge(visited[todo.back().s], dfs_number);
|
||||
todo.back().it->next();
|
||||
todo.push_back({dst, sys_.succ(dst)});
|
||||
todo.push_back({dst, sys_.succ(dst, tid_)});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -113,5 +113,6 @@ namespace spot
|
|||
visited_map visited;
|
||||
unsigned int dfs_number = 0;
|
||||
unsigned int transitions = 0;
|
||||
unsigned int tid_;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue