Merge pull request #4795 from janetournois/Mesh_3-fix_optimisers_parallel-jtournois

Mesh_3 - fix parallel optimisers
This commit is contained in:
Laurent Rineau 2020-06-30 16:38:05 +02:00
commit 07eacf5231
4 changed files with 120 additions and 100 deletions

View File

@ -839,16 +839,6 @@ public:
Moving_vertices_set& moving_vertices,
bool *could_lock_zone) const;
/**
* Try to lock the incident cells and return them in \c cells
* Return value:
* - false: everything is unlocked and \c cells is empty
* - true: incident cells are locked and \c cells contains all of them
*/
bool
try_lock_and_get_incident_cells(const Vertex_handle& v,
Cell_vector &cells) const;
/**
* Try to lock ALL the incident cells and return in \c cells the ones
* whose \c filter says "true".
@ -1267,6 +1257,7 @@ private:
class Facet_updater
{
const Self& m_c3t3_helpers;
Vertex_set& vertex_to_proj;
C3T3& c3t3_;
Update_c3t3& c3t3_updater_;
@ -1275,8 +1266,10 @@ private:
typedef Facet& reference;
typedef const Facet& const_reference;
Facet_updater(C3T3& c3t3, Vertex_set& vertex_to_proj, Update_c3t3& c3t3_updater_)
: vertex_to_proj(vertex_to_proj), c3t3_(c3t3), c3t3_updater_(c3t3_updater_)
Facet_updater(const Self& c3t3_helpers,
C3T3& c3t3, Vertex_set& vertex_to_proj, Update_c3t3& c3t3_updater_)
: m_c3t3_helpers(c3t3_helpers),
vertex_to_proj(vertex_to_proj), c3t3_(c3t3), c3t3_updater_(c3t3_updater_)
{}
void
@ -1296,9 +1289,9 @@ private:
const Vertex_handle& v = f.first->vertex((k+i)&3);
if ( c3t3_.in_dimension(v) > 2 )
{
//lock_vertex_to_proj();
m_c3t3_helpers.lock_vertex_to_proj();
vertex_to_proj.insert(v);
//unlock_vertex_to_proj();
m_c3t3_helpers.unlock_vertex_to_proj();
}
}
}
@ -2731,7 +2724,7 @@ rebuild_restricted_delaunay(OutdatedCells& outdated_cells,
// Note: ~42% of rebuild_restricted_delaunay time
// Facet_vector facets;
lock_vertex_to_proj();
Facet_updater facet_updater(c3t3_,vertex_to_proj, updater);
Facet_updater facet_updater(*this, c3t3_,vertex_to_proj, updater);
unlock_vertex_to_proj();
update_facets(outdated_cells_vector, facet_updater);
@ -2760,7 +2753,7 @@ rebuild_restricted_delaunay(OutdatedCells& outdated_cells,
// Get facets (returns each canonical facet only once)
// Note: ~42% of rebuild_restricted_delaunay time
// Facet_vector facets;
Facet_updater facet_updater(c3t3_,vertex_to_proj, updater);
Facet_updater facet_updater(*this, c3t3_,vertex_to_proj, updater);
update_facets(outdated_cells, facet_updater);
// now we can clear
@ -2948,7 +2941,19 @@ move_point(const Vertex_handle& old_vertex,
Cell_vector incident_cells_;
incident_cells_.reserve(64);
tr_.incident_cells(old_vertex, std::back_inserter(incident_cells_));
# ifdef CGAL_LINKED_WITH_TBB
// Parallel
if (boost::is_convertible<Concurrency_tag, Parallel_tag>::value)
{
tr_.incident_cells_threadsafe(old_vertex, std::back_inserter(incident_cells_));
}
// Sequential
else
# endif // CGAL_LINKED_WITH_TBB
{
tr_.incident_cells(old_vertex, std::back_inserter(incident_cells_));
}
const Weighted_point& position = tr_.point(old_vertex);
const Weighted_point& new_position = cwp(translate(cp(position), move));
@ -3037,9 +3042,10 @@ move_point(const Vertex_handle& old_vertex,
//======= Get incident cells ==========
Cell_vector incident_cells_;
incident_cells_.reserve(64);
if (try_lock_and_get_incident_cells(old_vertex, incident_cells_) == false)
if (tr_.try_lock_and_get_incident_cells(old_vertex, incident_cells_) == false)
{
*could_lock_zone = false;
unlock_all_elements();
return Vertex_handle();
}
//======= /Get incident cells ==========
@ -3066,11 +3072,12 @@ move_point(const Vertex_handle& old_vertex,
lock_outdated_cells();
std::copy(incident_cells_.begin(),incident_cells_.end(),
std::inserter(outdated_cells_set, outdated_cells_set.end()));
unlock_outdated_cells();
Vertex_handle new_vertex =
move_point_no_topo_change(old_vertex, move, new_position);
unlock_outdated_cells();
// Don't "unlock_all_elements" here, the caller may need it to do it himself
return new_vertex;
}
@ -3582,60 +3589,6 @@ get_incident_slivers_without_using_tds_data(const Vertex_handle& v,
tr_.incident_cells_threadsafe(v, boost::make_function_output_iterator(f));
}
// CJTODO: call tr_.try_lock_and_get_incident_cells instead?
template <typename C3T3, typename MD>
bool
C3T3_helpers<C3T3,MD>::
try_lock_and_get_incident_cells(const Vertex_handle& v,
Cell_vector &cells) const
{
// We need to lock v individually first, to be sure v->cell() is valid
if (!try_lock_vertex(v))
return false;
Cell_handle d = v->cell();
if (!try_lock_element(d)) // LOCK
{
unlock_all_elements();
return false;
}
cells.push_back(d);
d->tds_data().mark_in_conflict();
int head=0;
int tail=1;
do {
Cell_handle c = cells[head];
for (int i=0; i<4; ++i) {
if (c->vertex(i) == v)
continue;
Cell_handle next = c->neighbor(i);
if (!try_lock_element(next)) // LOCK
{
for(Cell_handle ch : cells)
{
ch->tds_data().clear();
}
cells.clear();
unlock_all_elements();
return false;
}
if (! next->tds_data().is_clear())
continue;
cells.push_back(next);
++tail;
next->tds_data().mark_in_conflict();
}
++head;
} while(head != tail);
for(Cell_handle ch : cells)
{
ch->tds_data().clear();
}
return true;
}
template <typename C3T3, typename MD>
template <typename Filter>
bool
@ -3646,7 +3599,7 @@ try_lock_and_get_incident_cells(const Vertex_handle& v,
{
std::vector<Cell_handle> tmp_cells;
tmp_cells.reserve(64);
bool ret = try_lock_and_get_incident_cells(v, tmp_cells);
bool ret = tr_.try_lock_and_get_incident_cells(v, tmp_cells);
if (ret)
{
for(Cell_handle ch : tmp_cells)
@ -3655,6 +3608,8 @@ try_lock_and_get_incident_cells(const Vertex_handle& v,
cells.push_back(ch);
}
}
else
tr_.unlock_all_elements();
return ret;
}
@ -3872,7 +3827,19 @@ get_conflict_zone_topo_change(const Vertex_handle& v,
// Get triangulation_vertex incident cells : removal conflict zone
// TODO: hasn't it already been computed in "perturb_vertex" (when getting the slivers)?
// We don't try to lock the incident cells since they've already been locked
tr_.incident_cells(v, removal_conflict_cells);
# ifdef CGAL_LINKED_WITH_TBB
// Parallel
if (boost::is_convertible<Concurrency_tag, Parallel_tag>::value)
{
tr_.incident_cells_threadsafe(v, removal_conflict_cells);
}
// Sequential
else
# endif // CGAL_LINKED_WITH_TBB
{
tr_.incident_cells(v, removal_conflict_cells);
}
// Get conflict_point conflict zone
int li=0;

View File

@ -1249,7 +1249,7 @@ public:
return visit_incident_cells_threadsafe<
Vertex_extractor<Edge_feeder_treatment<OutputIterator>,
OutputIterator, Filter,
internal::Has_member_visited<Vertex>::value>,
false>,
OutputIterator>(v, edges, f);
}
@ -1321,6 +1321,52 @@ public:
return adjacent_vertices<False_filter>(v, vertices);
}
template <class OutputIterator>
OutputIterator
adjacent_vertices_threadsafe(Vertex_handle v, OutputIterator vertices) const
{
return adjacent_vertices_threadsafe<False_filter>(v, vertices);
}
template <class Filter, class OutputIterator>
OutputIterator
adjacent_vertices_threadsafe(Vertex_handle v, OutputIterator vertices,
Filter f = Filter()) const
{
CGAL_triangulation_precondition(v != Vertex_handle());
CGAL_triangulation_precondition(dimension() >= -1);
CGAL_triangulation_expensive_precondition(is_vertex(v));
CGAL_triangulation_expensive_precondition(is_valid());
if (dimension() == -1)
return vertices;
if (dimension() == 0) {
Vertex_handle v1 = v->cell()->neighbor(0)->vertex(0);
if (!f(v1)) *vertices++ = v1;
return vertices;
}
if (dimension() == 1) {
CGAL_triangulation_assertion(number_of_vertices() >= 3);
Cell_handle n0 = v->cell();
const int index_v_in_n0 = n0->index(v);
CGAL_assume(index_v_in_n0 <= 1);
Cell_handle n1 = n0->neighbor(1 - index_v_in_n0);
const int index_v_in_n1 = n1->index(v);
CGAL_assume(index_v_in_n1 <= 1);
Vertex_handle v1 = n0->vertex(1 - index_v_in_n0);
Vertex_handle v2 = n1->vertex(1 - index_v_in_n1);
if (!f(v1)) *vertices++ = v1;
if (!f(v2)) *vertices++ = v2;
return vertices;
}
return visit_incident_cells_threadsafe<
Vertex_extractor<Vertex_feeder_treatment<OutputIterator>, OutputIterator, Filter,
false>,
OutputIterator>(v, vertices, f);
}
template <class Visitor, class OutputIterator, class Filter>
OutputIterator
visit_incident_cells(Vertex_handle v, OutputIterator output, Filter f) const

View File

@ -153,6 +153,7 @@ public:
using Tr_Base::geom_traits;
#endif
using Tr_Base::adjacent_vertices;
using Tr_Base::adjacent_vertices_threadsafe;
using Tr_Base::cw;
using Tr_Base::ccw;
using Tr_Base::construct_point;
@ -1717,7 +1718,7 @@ nearest_power_vertex(const Bare_point& p, Cell_handle start) const
while(true)
{
Vertex_handle tmp = nearest;
adjacent_vertices(nearest, std::back_inserter(vs));
adjacent_vertices_threadsafe(nearest, std::back_inserter(vs));
for(typename std::vector<Vertex_handle>::const_iterator
vsit = vs.begin(); vsit != vs.end(); ++vsit)
tmp = nearest_power_vertex(p, tmp, *vsit);

View File

@ -1652,7 +1652,7 @@ private:
Vertex_handle>::type Vertex_handle_unique_hash_map;
Vertex_triple make_vertex_triple(const Facet& f) const;
void make_canonical(Vertex_triple& t) const;
void make_canonical_oriented_triple(Vertex_triple& t) const;
template < class VertexRemover >
VertexRemover& make_hole_2D(Vertex_handle v, std::list<Edge_2D>& hole,
@ -2144,6 +2144,12 @@ public:
return _tds.adjacent_vertices(v, vertices);
}
template <class OutputIterator>
OutputIterator adjacent_vertices_threadsafe(Vertex_handle v, OutputIterator vertices) const
{
return _tds.adjacent_vertices_threadsafe(v, vertices);
}
template <class OutputIterator>
OutputIterator adjacent_vertices_and_cells_3(Vertex_handle v, OutputIterator vertices,
std::vector<Cell_handle>& cells) const
@ -4287,7 +4293,7 @@ make_vertex_triple(const Facet& f) const
template < class Gt, class Tds, class Lds >
void
Triangulation_3<Gt,Tds,Lds>::
make_canonical(Vertex_triple& t) const
make_canonical_oriented_triple(Vertex_triple& t) const
{
int i = (t.first < t.second) ? 0 : 1;
if(i==0)
@ -4840,7 +4846,7 @@ make_hole_3D(Vertex_handle v,
Cell_handle opp_cit = (*cit)->neighbor(indv);
Facet f(opp_cit, opp_cit->index(*cit));
Vertex_triple vt = make_vertex_triple(f);
make_canonical(vt);
make_canonical_oriented_triple(vt);
outer_map[vt] = f;
for(int i=0; i<4; i++)
{
@ -4867,7 +4873,7 @@ make_hole_3D(Vertex_handle v,
Cell_handle opp_cit = (*cit)->neighbor(indv);
Facet f(opp_cit, opp_cit->index(*cit));
Vertex_triple vt = make_vertex_triple(f);
make_canonical(vt);
make_canonical_oriented_triple(vt);
outer_map[vt] = f;
for(int i=0; i<4; i++)
{
@ -5055,7 +5061,7 @@ remove_3D(Vertex_handle v, VertexRemover& remover)
Facet f = std::pair<Cell_handle,int>(it,i);
Vertex_triple vt_aux = make_vertex_triple(f);
Vertex_triple vt(vmap[vt_aux.first], vmap[vt_aux.third], vmap[vt_aux.second]);
make_canonical(vt);
make_canonical_oriented_triple(vt);
inner_map[vt]= f;
}
}
@ -5070,7 +5076,7 @@ remove_3D(Vertex_handle v, VertexRemover& remover)
Facet f = std::pair<Cell_handle,int>(it,i);
Vertex_triple vt_aux = make_vertex_triple(f);
Vertex_triple vt(vmap[vt_aux.first], vmap[vt_aux.third], vmap[vt_aux.second]);
make_canonical(vt);
make_canonical_oriented_triple(vt);
inner_map[vt]= f;
}
}
@ -5113,7 +5119,7 @@ remove_3D(Vertex_handle v, VertexRemover& remover)
{
Facet f = std::pair<Cell_handle,int>(new_ch,i);
Vertex_triple vt = make_vertex_triple(f);
make_canonical(vt);
make_canonical_oriented_triple(vt);
std::swap(vt.second,vt.third);
typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt);
@ -5251,7 +5257,7 @@ remove_3D(Vertex_handle v, VertexRemover& remover,
Facet f = std::pair<Cell_handle,int>(it,i);
Vertex_triple vt_aux = make_vertex_triple(f);
Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]);
make_canonical(vt);
make_canonical_oriented_triple(vt);
inner_map[vt]= f;
}
}
@ -5266,7 +5272,7 @@ remove_3D(Vertex_handle v, VertexRemover& remover,
Facet f = std::pair<Cell_handle,int>(it,i);
Vertex_triple vt_aux = make_vertex_triple(f);
Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]);
make_canonical(vt);
make_canonical_oriented_triple(vt);
inner_map[vt]= f;
}
}
@ -5311,7 +5317,7 @@ remove_3D(Vertex_handle v, VertexRemover& remover,
{
Facet f = std::pair<Cell_handle,int>(new_ch,i);
Vertex_triple vt = make_vertex_triple(f);
make_canonical(vt);
make_canonical_oriented_triple(vt);
std::swap(vt.second,vt.third);
typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt);
@ -5555,7 +5561,7 @@ remove_3D(Vertex_handle v, VertexRemover& remover, OutputItCells fit)
Facet f = std::pair<Cell_handle,int>(it,i);
Vertex_triple vt_aux = make_vertex_triple(f);
Vertex_triple vt(vmap[vt_aux.first], vmap[vt_aux.third], vmap[vt_aux.second]);
make_canonical(vt);
make_canonical_oriented_triple(vt);
inner_map[vt] = f;
}
}
@ -5569,7 +5575,7 @@ remove_3D(Vertex_handle v, VertexRemover& remover, OutputItCells fit)
Facet f = std::pair<Cell_handle,int>(it,i);
Vertex_triple vt_aux = make_vertex_triple(f);
Vertex_triple vt(vmap[vt_aux.first], vmap[vt_aux.third], vmap[vt_aux.second]);
make_canonical(vt);
make_canonical_oriented_triple(vt);
inner_map[vt] = f;
}
}
@ -5616,7 +5622,7 @@ remove_3D(Vertex_handle v, VertexRemover& remover, OutputItCells fit)
{
Facet f = std::pair<Cell_handle,int>(new_ch,i);
Vertex_triple vt = make_vertex_triple(f);
make_canonical(vt);
make_canonical_oriented_triple(vt);
std::swap(vt.second, vt.third);
typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt);
if(oit2 == outer_map.end())
@ -5943,7 +5949,7 @@ move_if_no_collision(Vertex_handle v, const Point& p,
Facet f = std::pair<Cell_handle,int>(it,i);
Vertex_triple vt_aux = make_vertex_triple(f);
Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]);
make_canonical(vt);
make_canonical_oriented_triple(vt);
inner_map[vt]= f;
}
}
@ -5958,7 +5964,7 @@ move_if_no_collision(Vertex_handle v, const Point& p,
Facet f = std::pair<Cell_handle,int>(it,i);
Vertex_triple vt_aux = make_vertex_triple(f);
Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]);
make_canonical(vt);
make_canonical_oriented_triple(vt);
inner_map[vt]= f;
}
}
@ -6004,7 +6010,7 @@ move_if_no_collision(Vertex_handle v, const Point& p,
{
Facet f = std::pair<Cell_handle,int>(new_ch,i);
Vertex_triple vt = make_vertex_triple(f);
make_canonical(vt);
make_canonical_oriented_triple(vt);
std::swap(vt.second,vt.third);
typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt);
if(oit2 == outer_map.end())
@ -6395,7 +6401,7 @@ move_if_no_collision_and_give_new_cells(Vertex_handle v, const Point& p,
Facet f = std::pair<Cell_handle,int>(it,i);
Vertex_triple vt_aux = make_vertex_triple(f);
Vertex_triple vt(vmap[vt_aux.first], vmap[vt_aux.third], vmap[vt_aux.second]);
make_canonical(vt);
make_canonical_oriented_triple(vt);
inner_map[vt]= f;
}
}
@ -6410,7 +6416,7 @@ move_if_no_collision_and_give_new_cells(Vertex_handle v, const Point& p,
Facet f = std::pair<Cell_handle,int>(it,i);
Vertex_triple vt_aux = make_vertex_triple(f);
Vertex_triple vt(vmap[vt_aux.first], vmap[vt_aux.third], vmap[vt_aux.second]);
make_canonical(vt);
make_canonical_oriented_triple(vt);
inner_map[vt]= f;
}
}
@ -6457,7 +6463,7 @@ move_if_no_collision_and_give_new_cells(Vertex_handle v, const Point& p,
{
Facet f = std::pair<Cell_handle, int>(new_ch, i);
Vertex_triple vt = make_vertex_triple(f);
make_canonical(vt);
make_canonical_oriented_triple(vt);
std::swap(vt.second,vt.third);
typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt);
if(oit2 == outer_map.end())
@ -6589,7 +6595,7 @@ _make_big_hole_3D(Vertex_handle v,
Facet f(opp_cit, opp_i);
Vertex_triple vt = make_vertex_triple(f);
make_canonical(vt);
make_canonical_oriented_triple(vt);
outer_map[vt] = f;
v1->set_cell(opp_cit);
v2->set_cell(opp_cit);
@ -6734,7 +6740,7 @@ _remove_cluster_3D(InputIterator first, InputIterator beyond, VertexRemover& rem
Facet f = std::pair<Cell_handle,int>(it,index);
Vertex_triple vt_aux = this->make_vertex_triple(f);
Vertex_triple vt(vmap[vt_aux.first], vmap[vt_aux.third], vmap[vt_aux.second]);
this->make_canonical(vt);
this->make_canonical_oriented_triple(vt);
inner_map[vt]= f;
}
}
@ -6749,7 +6755,7 @@ _remove_cluster_3D(InputIterator first, InputIterator beyond, VertexRemover& rem
Facet f = std::pair<Cell_handle,int>(it,index);
Vertex_triple vt_aux = this->make_vertex_triple(f);
Vertex_triple vt(vmap[vt_aux.first], vmap[vt_aux.third], vmap[vt_aux.second]);
this->make_canonical(vt);
this->make_canonical_oriented_triple(vt);
inner_map[vt]= f;
}
}
@ -6798,7 +6804,7 @@ _remove_cluster_3D(InputIterator first, InputIterator beyond, VertexRemover& rem
{
Facet f = std::pair<Cell_handle,int>(new_ch,index);
Vertex_triple vt = this->make_vertex_triple(f);
this->make_canonical(vt);
this->make_canonical_oriented_triple(vt);
std::swap(vt.second,vt.third);
typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt);
if(oit2 == outer_map.end())