21 #ifndef __TBB_parallel_reduce_H 22 #define __TBB_parallel_reduce_H 32 namespace interface9 {
48 template<
typename Body>
56 has_right_zombie(false),
62 if( has_right_zombie )
63 zombie_space.
begin()->~Body();
66 if( has_right_zombie ) {
68 Body*
s = zombie_space.
begin();
76 template<
typename Range,
typename Body_,
typename Partitioner>
85 template<
typename Range,
typename Body,
typename Partitioner>
95 my_partition.note_affinity(
id );
97 template<
typename Body_>
102 start_reduce(
const Range& range, Body* body, Partitioner& partitioner ) :
105 my_partition(partitioner),
112 my_body(parent_.my_body),
113 my_range(parent_.my_range, split_obj),
114 my_partition(parent_.my_partition, split_obj),
117 my_partition.set_affinity(*
this);
123 my_body(parent_.my_body),
125 my_partition(parent_.my_partition,
split()),
128 my_partition.set_affinity(*
this);
129 my_partition.align_depth(
d );
132 static void run(
const Range& range, Body& body, Partitioner& partitioner ) {
133 if( !range.empty() ) {
134 #if !__TBB_TASK_GROUP_CONTEXT || TBB_JOIN_OUTER_TASK_GROUP 144 #if __TBB_TASK_GROUP_CONTEXT 150 void run_body( Range &r ) { (*my_body)( r ); }
155 void offer_work(
typename Partitioner::split_type& split_obj) {
181 template<
typename Range,
typename Body,
typename Partitioner>
183 my_partition.check_being_stolen( *
this );
191 my_partition.execute(*
this, my_range);
202 template<
typename Body>
208 my_left_body( body ),
209 my_right_body( body,
split() )
213 my_left_body.join( my_right_body );
216 template<
typename Range,
typename Body_,
typename Partitioner>
222 template<
typename Range,
typename Body,
typename Partitioner>
234 my_partition( partitioner )
240 my_body( c.my_right_body ),
241 my_range( parent_.my_range, split_obj ),
242 my_partition( parent_.my_partition, split_obj )
247 static void run(
const Range& range, Body& body, Partitioner& partitioner ) {
248 if( !range.empty() ) {
249 #if !__TBB_TASK_GROUP_CONTEXT || TBB_JOIN_OUTER_TASK_GROUP 259 #if __TBB_TASK_GROUP_CONTEXT 266 void offer_work(
typename Partitioner::split_type& split_obj) {
277 template<
typename Range,
typename Body,
typename Partitioner>
279 my_partition.
execute(*
this, my_range);
295 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
362 template<
typename Range,
typename Body>
369 template<
typename Range,
typename Body>
376 template<
typename Range,
typename Body>
383 template<
typename Range,
typename Body>
390 template<
typename Range,
typename Body>
395 #if __TBB_TASK_GROUP_CONTEXT 398 template<
typename Range,
typename Body>
405 template<
typename Range,
typename Body>
412 template<
typename Range,
typename Body>
419 template<
typename Range,
typename Body>
426 template<
typename Range,
typename Body>
437 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
438 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction ) {
439 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
440 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const __TBB_DEFAULT_PARTITIONER>
442 return body.result();
447 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
448 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
450 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
451 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const simple_partitioner>
452 ::run(range, body, partitioner );
453 return body.result();
458 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
459 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
461 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
462 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const auto_partitioner>
463 ::run( range, body, partitioner );
464 return body.result();
469 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
470 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
472 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
473 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const static_partitioner>
474 ::run( range, body, partitioner );
475 return body.result();
480 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
481 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
483 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
484 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
affinity_partitioner>
485 ::run( range, body, partitioner );
486 return body.result();
489 #if __TBB_TASK_GROUP_CONTEXT 492 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
493 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
495 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
496 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const __TBB_DEFAULT_PARTITIONER>
498 return body.result();
503 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
504 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
506 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
507 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const simple_partitioner>
508 ::run( range, body, partitioner, context );
509 return body.result();
514 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
515 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
517 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
518 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const auto_partitioner>
519 ::run( range, body, partitioner, context );
520 return body.result();
525 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
526 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
528 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
529 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const static_partitioner>
530 ::run( range, body, partitioner, context );
531 return body.result();
536 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
537 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
539 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
540 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
affinity_partitioner>
541 ::run( range, body, partitioner, context );
542 return body.result();
548 template<
typename Range,
typename Body>
555 template<
typename Range,
typename Body>
562 template<
typename Range,
typename Body>
567 #if __TBB_TASK_GROUP_CONTEXT 570 template<
typename Range,
typename Body>
577 template<
typename Range,
typename Body>
584 template<
typename Range,
typename Body>
596 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
603 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
605 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
606 internal::start_deterministic_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const simple_partitioner>
607 ::run(range, body, partitioner);
608 return body.result();
613 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
615 internal::lambda_reduce_body<Range, Value, RealBody, Reduction> body(identity, real_body, reduction);
616 internal::start_deterministic_reduce<Range, internal::lambda_reduce_body<Range, Value, RealBody, Reduction>,
const static_partitioner>
617 ::run(range, body, partitioner);
618 return body.result();
620 #if __TBB_TASK_GROUP_CONTEXT 623 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
631 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
634 internal::lambda_reduce_body<Range, Value, RealBody, Reduction> body(identity, real_body, reduction);
635 internal::start_deterministic_reduce<Range, internal::lambda_reduce_body<Range, Value, RealBody, Reduction>,
const simple_partitioner>
636 ::run(range, body, partitioner, context);
637 return body.result();
642 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
645 internal::lambda_reduce_body<Range, Value, RealBody, Reduction> body(identity, real_body, reduction);
646 internal::start_deterministic_reduce<Range, internal::lambda_reduce_body<Range, Value, RealBody, Reduction>,
const static_partitioner>
647 ::run(range, body, partitioner, context);
648 return body.result();
internal::allocate_child_proxy & allocate_child()
Returns proxy for overloaded new that allocates a child task of *this.
Partitioner::task_partition_type my_partition
T * begin() const
Pointer to beginning of array.
start_reduce(start_reduce &parent_, const Range &r, depth_t d)
Construct right child from the given range as response to the demand.
virtual task * execute()=0
Should be overridden by derived classes.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
task * execute() __TBB_override
Should be overridden by derived classes.
void itt_store_word_with_release(tbb::atomic< T > &dst, U src)
task * execute() __TBB_override
Should be overridden by derived classes.
Used to form groups of tasks.
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d
Task type used to split the work of parallel_deterministic_reduce.
static void spawn_root_and_wait(task &root)
Spawn task allocated by allocate_root, wait for it to complete, and deallocate it.
task * execute() __TBB_override
Should be overridden by derived classes.
Task type used to combine the partial results of parallel_reduce.
void * allocate_sibling(task *start_for_task, size_t bytes)
allocate right task with new parent
T itt_load_word_with_acquire(const tbb::atomic< T > &src)
reduction_context my_context
Base class for user-defined tasks.
finish_reduce(reduction_context context_)
finish_deterministic_reduce< Body > finish_type
void set_parent(task *p)
sets parent task pointer to specified value
Task type used to combine the partial results of parallel_deterministic_reduce.
lambda_reduce_body(const lambda_reduce_body &other)
internal::affinity_id affinity_id
An id as used for specifying affinity.
void offer_work(const Range &r, depth_t d=0)
spawn right task, serves as callback for partitioner
internal::allocate_continuation_proxy & allocate_continuation()
Returns proxy for overloaded new that allocates a continuation task of *this.
bool has_right_zombie
Pointer to body, or NULL if the left child has not yet finished.
const Reduction & my_reduction
static void run(const Range &range, Body &body, Partitioner &partitioner, task_group_context &context)
start_reduce(start_reduce &parent_, typename Partitioner::split_type &split_obj)
Splitting constructor used to generate children.
void offer_work(typename Partitioner::split_type &split_obj)
void parallel_deterministic_reduce(const Range &range, Body &body)
Parallel iteration with deterministic reduction and default simple partitioner.
static void run(const Range &range, Body &body, Partitioner &partitioner)
void parallel_reduce(const Range &range, Body &body)
Parallel iteration with reduction and default partitioner.
task * execute() __TBB_override
Should be overridden by derived classes.
static void run(const Range &range, Body &body, Partitioner &partitioner)
const RealBody & my_real_body
Dummy type that distinguishes splitting constructor from copy constructor.
void offer_work(typename Partitioner::split_type &split_obj)
spawn right task, serves as callback for partitioner
Partitioner::task_partition_type my_partition
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id parent
aligned_space< Body > zombie_space
finish_deterministic_reduce(Body &body)
start_deterministic_reduce(start_deterministic_reduce &parent_, finish_type &c, typename Partitioner::split_type &split_obj)
Splitting constructor used to generate children.
lambda_reduce_body(lambda_reduce_body &other, tbb::split)
#define __TBB_DEFAULT_PARTITIONER
void const char const char int ITT_FORMAT __itt_group_sync s
const reduction_context my_context
finish_reduce< Body > finish_type
void set_ref_count(int count)
Set reference count.
lambda_reduce_body(const Value &identity, const RealBody &body, const Reduction &reduction)
void operator()(Range &range)
static internal::allocate_root_proxy allocate_root()
Returns proxy for overloaded new that allocates a root task.
void join(lambda_reduce_body &rhs)
Join task node that contains shared flag for stealing feedback.
lambda_reduce_body & operator=(const lambda_reduce_body &other)
const Value & identity_element
Identifiers declared inside namespace internal should never be used directly by client code.
start_reduce(const Range &range, Body *body, Partitioner &partitioner)
Constructor used for root task.
static void run(const Range &range, Body &body, Partitioner &partitioner, task_group_context &context)
Auxiliary class for parallel_reduce; for internal use only.
Task type used to split the work of parallel_reduce.