mirror of https://github.com/CGAL/cgal
Move range splitting higher to also parallelize 'box_intersection_d()'
This commit is contained in:
parent
9ef1c976c6
commit
b7d20e0033
|
|
@ -26,17 +26,103 @@
|
||||||
#include <CGAL/Box_intersection_d/box_limits.h>
|
#include <CGAL/Box_intersection_d/box_limits.h>
|
||||||
|
|
||||||
#include <CGAL/use.h>
|
#include <CGAL/use.h>
|
||||||
|
#include <CGAL/tags.h>
|
||||||
|
|
||||||
#ifdef CGAL_LINKED_WITH_TBB
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
#include <tbb/parallel_invoke.h>
|
#include <tbb/parallel_invoke.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
// Generic call with custom predicate traits parameter.
|
// Generic call with custom predicate traits parameter.
|
||||||
template< class RandomAccessIter1, class RandomAccessIter2,
|
template< class ConcurrencyTag,
|
||||||
|
class RandomAccessIter1, class RandomAccessIter2,
|
||||||
|
class Callback, class Traits >
|
||||||
|
void box_intersection_segment_tree_d(
|
||||||
|
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||||
|
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
||||||
|
Callback callback,
|
||||||
|
const Traits& traits,
|
||||||
|
const std::ptrdiff_t cutoff,
|
||||||
|
const bool in_order)
|
||||||
|
{
|
||||||
|
typedef typename Traits::NT NT;
|
||||||
|
|
||||||
|
CGAL_assertion(Traits::dimension() > 0);
|
||||||
|
const int dim = Traits::dimension() - 1;
|
||||||
|
|
||||||
|
const NT inf = Box_intersection_d::box_limits<NT>::inf();
|
||||||
|
const NT sup = Box_intersection_d::box_limits<NT>::sup();
|
||||||
|
|
||||||
|
#ifndef CGAL_LINKED_WITH_TBB
|
||||||
|
CGAL_static_assertion_msg (!(boost::is_convertible<ConcurrencyTag, Parallel_tag>::value),
|
||||||
|
"Parallel_tag is enabled but TBB is unavailable.");
|
||||||
|
#else // CGAL_LINKED_WITH_TBB
|
||||||
|
if(boost::is_convertible<ConcurrencyTag, Parallel_tag>::value)
|
||||||
|
{
|
||||||
|
typename std::iterator_traits<RandomAccessIter1>::difference_type r1hs = std::distance(begin1, end1) / 2;
|
||||||
|
typename std::iterator_traits<RandomAccessIter2>::difference_type r2hs = std::distance(begin2, end2) / 2;
|
||||||
|
|
||||||
|
// TODO: Check which of the two following approaches is better
|
||||||
|
// The first one makes three copies of the vector and performs four parallel tasks
|
||||||
|
// The second one makes one copy, but must perform two times two parallel tasks (can't
|
||||||
|
// do all four at the same time otherwise the sort / split will conflict)
|
||||||
|
#ifdef CGAL_BOX_INTER_FOUR_RANGES
|
||||||
|
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
||||||
|
|
||||||
|
std::vector< val_t> r3( begin1, end1);
|
||||||
|
std::vector< val_t> r4( begin2, end2);
|
||||||
|
|
||||||
|
RandomAccessIter1 mid1 = begin1;
|
||||||
|
std::advance(mid1, r1hs);
|
||||||
|
RandomAccessIter2 mid2 = begin2;
|
||||||
|
std::advance(mid2, r2hs);
|
||||||
|
typename std::vector< val_t>::iterator mid3 = r3.begin();
|
||||||
|
std::advance(mid3, r1hs);
|
||||||
|
typename std::vector< val_t>::iterator mid4 = r4.begin();
|
||||||
|
std::advance(mid4, r2hs);
|
||||||
|
|
||||||
|
tbb::parallel_invoke([&]{ Box_intersection_d::segment_tree( begin1, mid1, begin2, mid2, inf, sup,
|
||||||
|
callback, traits, cutoff, dim, in_order); },
|
||||||
|
[&]{ Box_intersection_d::segment_tree( mid1, end1, mid2, end2, inf, sup,
|
||||||
|
callback, traits, cutoff, dim, in_order); },
|
||||||
|
[&]{ Box_intersection_d::segment_tree( r3.begin(), mid3, mid4, r4.end(), inf, sup,
|
||||||
|
callback, traits, cutoff, dim, in_order); },
|
||||||
|
[&]{ Box_intersection_d::segment_tree( mid3, r3.end(), r4.begin(), mid4, inf, sup,
|
||||||
|
callback, traits, cutoff, dim, in_order); } );
|
||||||
|
#else // CGAL_BOX_INTER_FOUR_RANGES
|
||||||
|
RandomAccessIter1 mid1 = begin1;
|
||||||
|
std::advance(mid1, r1hs);
|
||||||
|
RandomAccessIter2 mid2 = begin2;
|
||||||
|
std::advance(mid2, r2hs);
|
||||||
|
|
||||||
|
tbb::parallel_invoke([&]{ Box_intersection_d::segment_tree( begin1, mid1, begin2, mid2, inf, sup,
|
||||||
|
callback, traits, cutoff, dim, in_order); },
|
||||||
|
[&]{ Box_intersection_d::segment_tree( mid1, end1, mid2, end2, inf, sup,
|
||||||
|
callback, traits, cutoff, dim, in_order); } );
|
||||||
|
tbb::parallel_invoke([&]{ Box_intersection_d::segment_tree( begin1, mid1, mid2, end2, inf, sup,
|
||||||
|
callback, traits, cutoff, dim, in_order); },
|
||||||
|
[&]{ Box_intersection_d::segment_tree( mid1, end1, begin2, mid2, inf, sup,
|
||||||
|
callback, traits, cutoff, dim, in_order); } );
|
||||||
|
|
||||||
|
#endif // CGAL_BOX_INTER_FOUR_RANGES
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif // CGAL_LINKED_WITH_TBB
|
||||||
|
{
|
||||||
|
Box_intersection_d::segment_tree(begin1, end1, begin2, end2, inf, sup, callback, traits, cutoff, dim, in_order);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
// Generic call with custom predicate traits parameter.
|
||||||
|
template< class ConcurrencyTag = Sequential_tag,
|
||||||
|
class RandomAccessIter1, class RandomAccessIter2,
|
||||||
class Callback, class BoxPredicateTraits >
|
class Callback, class BoxPredicateTraits >
|
||||||
void box_intersection_custom_predicates_d(
|
void box_intersection_custom_predicates_d(
|
||||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||||
|
|
@ -46,24 +132,15 @@ void box_intersection_custom_predicates_d(
|
||||||
std::ptrdiff_t cutoff = 10,
|
std::ptrdiff_t cutoff = 10,
|
||||||
Box_intersection_d::Setting setting = Box_intersection_d::BIPARTITE)
|
Box_intersection_d::Setting setting = Box_intersection_d::BIPARTITE)
|
||||||
{
|
{
|
||||||
typedef BoxPredicateTraits Traits;
|
internal::box_intersection_segment_tree_d<ConcurrencyTag>(begin1, end1, begin2, end2, callback, traits, cutoff, true);
|
||||||
typedef typename Traits::NT NT;
|
|
||||||
CGAL_assertion( Traits::dimension() > 0 );
|
|
||||||
const int dim = Traits::dimension() - 1;
|
|
||||||
const NT inf = Box_intersection_d::box_limits<NT>::inf();
|
|
||||||
const NT sup = Box_intersection_d::box_limits<NT>::sup();
|
|
||||||
Box_intersection_d::segment_tree(begin1, end1, begin2, end2,
|
|
||||||
inf, sup, callback, traits, cutoff, dim, true);
|
|
||||||
if(setting == Box_intersection_d::BIPARTITE)
|
if(setting == Box_intersection_d::BIPARTITE)
|
||||||
Box_intersection_d::segment_tree(begin2, end2, begin1, end1,
|
internal::box_intersection_segment_tree_d<ConcurrencyTag>(begin2, end2, begin1, end1, callback, traits, cutoff, false);
|
||||||
inf, sup, callback, traits, cutoff, dim, false);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Generic call with box traits parameter.
|
// Generic call with box traits parameter.
|
||||||
// - make all default parameters explicit overloads (workaround)
|
// - make all default parameters explicit overloads (workaround)
|
||||||
template< class RandomAccessIter1, class RandomAccessIter2,
|
template< class ConcurrencyTag = Sequential_tag,
|
||||||
|
class RandomAccessIter1, class RandomAccessIter2,
|
||||||
class Callback, class BoxTraits >
|
class Callback, class BoxTraits >
|
||||||
void box_intersection_d(
|
void box_intersection_d(
|
||||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||||
|
|
@ -76,16 +153,17 @@ void box_intersection_d(
|
||||||
{
|
{
|
||||||
if (topology == Box_intersection_d::CLOSED) {
|
if (topology == Box_intersection_d::CLOSED) {
|
||||||
typedef Box_intersection_d::Predicate_traits_d<BoxTraits,true> Traits;
|
typedef Box_intersection_d::Predicate_traits_d<BoxTraits,true> Traits;
|
||||||
box_intersection_custom_predicates_d(begin1, end1, begin2, end2,
|
box_intersection_custom_predicates_d<ConcurrencyTag>(begin1, end1, begin2, end2,
|
||||||
callback, Traits(), cutoff, setting);
|
callback, Traits(), cutoff, setting);
|
||||||
} else {
|
} else {
|
||||||
typedef Box_intersection_d::Predicate_traits_d<BoxTraits,false> Traits;
|
typedef Box_intersection_d::Predicate_traits_d<BoxTraits,false> Traits;
|
||||||
box_intersection_custom_predicates_d(begin1, end1, begin2, end2,
|
box_intersection_custom_predicates_d<ConcurrencyTag>(begin1, end1, begin2, end2,
|
||||||
callback, Traits(), cutoff, setting);
|
callback, Traits(), cutoff, setting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template< class RandomAccessIter1, class RandomAccessIter2,
|
template< class ConcurrencyTag = Sequential_tag,
|
||||||
|
class RandomAccessIter1, class RandomAccessIter2,
|
||||||
class Callback, class BoxTraits >
|
class Callback, class BoxTraits >
|
||||||
void box_intersection_d(
|
void box_intersection_d(
|
||||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||||
|
|
@ -93,35 +171,39 @@ void box_intersection_d(
|
||||||
Callback callback, BoxTraits box_traits, std::ptrdiff_t cutoff,
|
Callback callback, BoxTraits box_traits, std::ptrdiff_t cutoff,
|
||||||
Box_intersection_d::Topology topology)
|
Box_intersection_d::Topology topology)
|
||||||
{
|
{
|
||||||
box_intersection_d( begin1, end1, begin2, end2, callback, box_traits,
|
box_intersection_d<ConcurrencyTag>( begin1, end1, begin2, end2, callback, box_traits,
|
||||||
cutoff, topology, Box_intersection_d::BIPARTITE);
|
cutoff, topology, Box_intersection_d::BIPARTITE);
|
||||||
}
|
}
|
||||||
template< class RandomAccessIter1, class RandomAccessIter2,
|
template< class ConcurrencyTag = Sequential_tag,
|
||||||
|
class RandomAccessIter1, class RandomAccessIter2,
|
||||||
class Callback, class BoxTraits >
|
class Callback, class BoxTraits >
|
||||||
void box_intersection_d(
|
void box_intersection_d(
|
||||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||||
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
||||||
Callback callback, BoxTraits box_traits, std::ptrdiff_t cutoff)
|
Callback callback, BoxTraits box_traits, std::ptrdiff_t cutoff)
|
||||||
{
|
{
|
||||||
box_intersection_d( begin1, end1, begin2, end2, callback, box_traits,
|
box_intersection_d<ConcurrencyTag>( begin1, end1, begin2, end2, callback, box_traits,
|
||||||
cutoff, Box_intersection_d::CLOSED,
|
cutoff, Box_intersection_d::CLOSED,
|
||||||
Box_intersection_d::BIPARTITE);
|
Box_intersection_d::BIPARTITE);
|
||||||
}
|
}
|
||||||
template< class RandomAccessIter1, class RandomAccessIter2,
|
|
||||||
|
template< class ConcurrencyTag = Sequential_tag,
|
||||||
|
class RandomAccessIter1, class RandomAccessIter2,
|
||||||
class Callback, class BoxTraits >
|
class Callback, class BoxTraits >
|
||||||
void box_intersection_d(
|
void box_intersection_d(
|
||||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||||
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
||||||
Callback callback, BoxTraits box_traits)
|
Callback callback, BoxTraits box_traits)
|
||||||
{
|
{
|
||||||
box_intersection_d( begin1, end1, begin2, end2, callback, box_traits,
|
box_intersection_d<ConcurrencyTag>( begin1, end1, begin2, end2, callback, box_traits,
|
||||||
10, Box_intersection_d::CLOSED,
|
10, Box_intersection_d::CLOSED,
|
||||||
Box_intersection_d::BIPARTITE);
|
Box_intersection_d::BIPARTITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specialized call with default box traits.
|
// Specialized call with default box traits.
|
||||||
// - make all default parameters explicit overloads (workaround)
|
// - make all default parameters explicit overloads (workaround)
|
||||||
template< class RandomAccessIter1, class RandomAccessIter2, class Callback >
|
template< class ConcurrencyTag = Sequential_tag,
|
||||||
|
class RandomAccessIter1, class RandomAccessIter2, class Callback >
|
||||||
void box_intersection_d(
|
void box_intersection_d(
|
||||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||||
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
||||||
|
|
@ -131,11 +213,13 @@ void box_intersection_d(
|
||||||
{
|
{
|
||||||
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
||||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||||
box_intersection_d( begin1, end1, begin2, end2, callback, Box_traits(),
|
|
||||||
|
box_intersection_d<ConcurrencyTag>( begin1, end1, begin2, end2, callback, Box_traits(),
|
||||||
cutoff, topology, setting);
|
cutoff, topology, setting);
|
||||||
}
|
}
|
||||||
|
|
||||||
template< class RandomAccessIter1, class RandomAccessIter2, class Callback >
|
template< class ConcurrencyTag = Sequential_tag,
|
||||||
|
class RandomAccessIter1, class RandomAccessIter2, class Callback >
|
||||||
void box_intersection_d(
|
void box_intersection_d(
|
||||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||||
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
||||||
|
|
@ -144,10 +228,12 @@ void box_intersection_d(
|
||||||
{
|
{
|
||||||
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
||||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||||
box_intersection_d( begin1, end1, begin2, end2, callback, Box_traits(),
|
|
||||||
|
box_intersection_d<ConcurrencyTag>( begin1, end1, begin2, end2, callback, Box_traits(),
|
||||||
cutoff, topology, Box_intersection_d::BIPARTITE);
|
cutoff, topology, Box_intersection_d::BIPARTITE);
|
||||||
}
|
}
|
||||||
template< class RandomAccessIter1, class RandomAccessIter2, class Callback >
|
template< class ConcurrencyTag = Sequential_tag,
|
||||||
|
class RandomAccessIter1, class RandomAccessIter2, class Callback >
|
||||||
void box_intersection_d(
|
void box_intersection_d(
|
||||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||||
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
||||||
|
|
@ -155,11 +241,12 @@ void box_intersection_d(
|
||||||
{
|
{
|
||||||
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
||||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||||
box_intersection_d( begin1, end1, begin2, end2, callback, Box_traits(),
|
box_intersection_d<ConcurrencyTag>( begin1, end1, begin2, end2, callback, Box_traits(),
|
||||||
cutoff, Box_intersection_d::CLOSED,
|
cutoff, Box_intersection_d::CLOSED,
|
||||||
Box_intersection_d::BIPARTITE);
|
Box_intersection_d::BIPARTITE);
|
||||||
}
|
}
|
||||||
template< class RandomAccessIter1, class RandomAccessIter2, class Callback >
|
template< class ConcurrencyTag = Sequential_tag,
|
||||||
|
class RandomAccessIter1, class RandomAccessIter2, class Callback >
|
||||||
void box_intersection_d(
|
void box_intersection_d(
|
||||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||||
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
||||||
|
|
@ -167,26 +254,21 @@ void box_intersection_d(
|
||||||
{
|
{
|
||||||
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
||||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||||
box_intersection_d( begin1, end1, begin2, end2, callback, Box_traits(),
|
box_intersection_d<ConcurrencyTag>( begin1, end1, begin2, end2, callback, Box_traits(),
|
||||||
10, Box_intersection_d::CLOSED,
|
10, Box_intersection_d::CLOSED,
|
||||||
Box_intersection_d::BIPARTITE);
|
Box_intersection_d::BIPARTITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generic call with box traits parameter, specialized for self-intersection.
|
// Generic call with box traits parameter, specialized for self-intersection.
|
||||||
// - make all default parameters explicit overloads (workaround)
|
// - make all default parameters explicit overloads (workaround)
|
||||||
template< class ConcurrencyTag = Sequential_tag, class RandomAccessIter, class Callback, class BoxTraits >
|
template< class ConcurrencyTag = Sequential_tag,
|
||||||
|
class RandomAccessIter, class Callback, class BoxTraits >
|
||||||
void box_self_intersection_d(
|
void box_self_intersection_d(
|
||||||
RandomAccessIter begin, RandomAccessIter end,
|
RandomAccessIter begin, RandomAccessIter end,
|
||||||
Callback callback,
|
Callback callback,
|
||||||
BoxTraits box_traits,
|
BoxTraits box_traits,
|
||||||
std::ptrdiff_t cutoff,
|
std::ptrdiff_t cutoff,
|
||||||
Box_intersection_d::Topology topology)
|
Box_intersection_d::Topology topology)
|
||||||
{
|
|
||||||
#ifndef CGAL_LINKED_WITH_TBB
|
|
||||||
CGAL_static_assertion_msg (!(boost::is_convertible<ConcurrencyTag, Parallel_tag>::value),
|
|
||||||
"Parallel_tag is enabled but TBB is unavailable.");
|
|
||||||
#else // CGAL_LINKED_WITH_TBB
|
|
||||||
if(boost::is_convertible<ConcurrencyTag, Parallel_tag>::value)
|
|
||||||
{
|
{
|
||||||
// Copying rather than calling 'box_intersection_d(begin, end, begin, end, ...'
|
// Copying rather than calling 'box_intersection_d(begin, end, begin, end, ...'
|
||||||
// is necessary because the 'std::partition' and range splits on the first range
|
// is necessary because the 'std::partition' and range splits on the first range
|
||||||
|
|
@ -194,71 +276,13 @@ void box_self_intersection_d(
|
||||||
typedef typename std::iterator_traits<RandomAccessIter>::value_type val_t;
|
typedef typename std::iterator_traits<RandomAccessIter>::value_type val_t;
|
||||||
std::vector< val_t> i( begin, end);
|
std::vector< val_t> i( begin, end);
|
||||||
|
|
||||||
// TODO: Check which of the two following approaches is better
|
box_intersection_d<ConcurrencyTag>( begin, end, i.begin(), i.end(),
|
||||||
// The first one makes three copies of the vector and performs four parallel tasks
|
|
||||||
// The second one makes one copy, but must perform two times two parallel tasks (can't
|
|
||||||
// do all four at the same time otherwise the sort / split will conflict)
|
|
||||||
#ifdef CGAL_BOX_INTER_FOUR_RANGES
|
|
||||||
std::vector< val_t> j( begin, end);
|
|
||||||
std::vector< val_t> k( begin, end);
|
|
||||||
|
|
||||||
RandomAccessIter mid = begin;
|
|
||||||
std::advance(mid, std::distance(begin,end)/2);
|
|
||||||
typename std::vector< val_t>::iterator midi = i.begin();
|
|
||||||
std::advance(midi, std::distance(begin,end)/2);
|
|
||||||
typename std::vector< val_t>::iterator midj = j.begin();
|
|
||||||
std::advance(midj, std::distance(begin,end)/2);
|
|
||||||
typename std::vector< val_t>::iterator midk = k.begin();
|
|
||||||
std::advance(midk, std::distance(begin,end)/2);
|
|
||||||
|
|
||||||
tbb::parallel_invoke([&]{ box_intersection_d( begin, mid, i.begin(), midi,
|
|
||||||
callback, box_traits, cutoff, topology,
|
|
||||||
Box_intersection_d::COMPLETE); },
|
|
||||||
[&]{ box_intersection_d( mid, end, midi, i.end(),
|
|
||||||
callback, box_traits, cutoff, topology,
|
|
||||||
Box_intersection_d::COMPLETE); },
|
|
||||||
[&]{ box_intersection_d( j.begin(), midj, midk, k.end(),
|
|
||||||
callback, box_traits, cutoff, topology,
|
|
||||||
Box_intersection_d::COMPLETE); },
|
|
||||||
[&]{ box_intersection_d( midj, j.end(), k.begin(), midk,
|
|
||||||
callback, box_traits, cutoff, topology,
|
|
||||||
Box_intersection_d::COMPLETE); } );
|
|
||||||
#else // CGAL_BOX_INTER_FOUR_RANGES
|
|
||||||
RandomAccessIter mid = begin;
|
|
||||||
std::advance(mid, std::distance(begin,end)/2);
|
|
||||||
typename std::vector< val_t>::iterator midi = i.begin();
|
|
||||||
std::advance(midi, std::distance(begin,end)/2);
|
|
||||||
|
|
||||||
tbb::parallel_invoke([&]{ box_intersection_d( begin, mid, i.begin(), midi,
|
|
||||||
callback, box_traits, cutoff, topology,
|
|
||||||
Box_intersection_d::COMPLETE); },
|
|
||||||
[&]{ box_intersection_d( mid, end, midi, i.end(),
|
|
||||||
callback, box_traits, cutoff, topology,
|
|
||||||
Box_intersection_d::COMPLETE); } );
|
|
||||||
tbb::parallel_invoke([&]{box_intersection_d( begin, mid, midi, i.end(),
|
|
||||||
callback, box_traits, cutoff, topology,
|
|
||||||
Box_intersection_d::COMPLETE); },
|
|
||||||
[&]{ box_intersection_d( mid, end, i.begin(), midi,
|
|
||||||
callback, box_traits, cutoff, topology,
|
|
||||||
Box_intersection_d::COMPLETE); } );
|
|
||||||
#endif // CGAL_BOX_INTER_FOUR_RANGES
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif // CGAL_LINKED_WITH_TBB
|
|
||||||
{
|
|
||||||
// Copying rather than calling 'box_intersection_d(begin, end, begin, end, ...'
|
|
||||||
// is necessary because the 'std::partition' and range splits on the first range
|
|
||||||
// would be messed up by sorts on the second range otherwise.
|
|
||||||
typedef typename std::iterator_traits<RandomAccessIter>::value_type val_t;
|
|
||||||
std::vector< val_t> i( begin, end);
|
|
||||||
|
|
||||||
box_intersection_d( begin, end, i.begin(), i.end(),
|
|
||||||
callback, box_traits, cutoff, topology,
|
callback, box_traits, cutoff, topology,
|
||||||
Box_intersection_d::COMPLETE);
|
Box_intersection_d::COMPLETE);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template< class ConcurrencyTag = Sequential_tag, class RandomAccessIter, class Callback, class BoxTraits >
|
template< class ConcurrencyTag = Sequential_tag,
|
||||||
|
class RandomAccessIter, class Callback, class BoxTraits >
|
||||||
void box_self_intersection_d(
|
void box_self_intersection_d(
|
||||||
RandomAccessIter begin, RandomAccessIter end,
|
RandomAccessIter begin, RandomAccessIter end,
|
||||||
Callback callback,
|
Callback callback,
|
||||||
|
|
@ -269,7 +293,8 @@ void box_self_intersection_d(
|
||||||
Box_intersection_d::CLOSED);
|
Box_intersection_d::CLOSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
template< class ConcurrencyTag = Sequential_tag, class RandomAccessIter, class Callback, class BoxTraits >
|
template< class ConcurrencyTag = Sequential_tag,
|
||||||
|
class RandomAccessIter, class Callback, class BoxTraits >
|
||||||
void box_self_intersection_d(
|
void box_self_intersection_d(
|
||||||
RandomAccessIter begin, RandomAccessIter end,
|
RandomAccessIter begin, RandomAccessIter end,
|
||||||
Callback callback,
|
Callback callback,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue