17 #ifndef __TBB_parallel_reduce_H 18 #define __TBB_parallel_reduce_H 28 namespace interface9 {
44 template<
typename Body>
52 has_right_zombie(false),
58 if( has_right_zombie )
59 zombie_space.
begin()->~Body();
62 if( has_right_zombie ) {
64 Body*
s = zombie_space.
begin();
72 template<
typename Range,
typename Body_,
typename Partitioner>
81 template<
typename Range,
typename Body,
typename Partitioner>
91 my_partition.note_affinity(
id );
93 template<
typename Body_>
98 start_reduce(
const Range& range, Body* body, Partitioner& partitioner ) :
101 my_partition(partitioner),
108 my_body(parent_.my_body),
109 my_range(parent_.my_range, split_obj),
110 my_partition(parent_.my_partition, split_obj),
113 my_partition.set_affinity(*
this);
119 my_body(parent_.my_body),
121 my_partition(parent_.my_partition,
split()),
124 my_partition.set_affinity(*
this);
125 my_partition.align_depth(
d );
128 static void run(
const Range& range, Body& body, Partitioner& partitioner ) {
129 if( !range.empty() ) {
130 #if !__TBB_TASK_GROUP_CONTEXT || TBB_JOIN_OUTER_TASK_GROUP 140 #if __TBB_TASK_GROUP_CONTEXT 146 void run_body( Range &r ) { (*my_body)( r ); }
151 void offer_work(
typename Partitioner::split_type& split_obj) {
177 template<
typename Range,
typename Body,
typename Partitioner>
179 my_partition.check_being_stolen( *
this );
187 my_partition.execute(*
this, my_range);
198 template<
typename Body>
204 my_left_body( body ),
205 my_right_body( body,
split() )
209 my_left_body.join( my_right_body );
212 template<
typename Range,
typename Body_,
typename Partitioner>
218 template<
typename Range,
typename Body,
typename Partitioner>
230 my_partition( partitioner )
236 my_body( c.my_right_body ),
237 my_range( parent_.my_range, split_obj ),
238 my_partition( parent_.my_partition, split_obj )
243 static void run(
const Range& range, Body& body, Partitioner& partitioner ) {
244 if( !range.empty() ) {
245 #if !__TBB_TASK_GROUP_CONTEXT || TBB_JOIN_OUTER_TASK_GROUP 255 #if __TBB_TASK_GROUP_CONTEXT 262 void offer_work(
typename Partitioner::split_type& split_obj) {
273 template<
typename Range,
typename Body,
typename Partitioner>
275 my_partition.
execute(*
this, my_range);
291 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
358 template<
typename Range,
typename Body>
365 template<
typename Range,
typename Body>
372 template<
typename Range,
typename Body>
379 template<
typename Range,
typename Body>
386 template<
typename Range,
typename Body>
391 #if __TBB_TASK_GROUP_CONTEXT 394 template<
typename Range,
typename Body>
401 template<
typename Range,
typename Body>
408 template<
typename Range,
typename Body>
415 template<
typename Range,
typename Body>
422 template<
typename Range,
typename Body>
433 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
434 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction ) {
435 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
436 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const __TBB_DEFAULT_PARTITIONER>
438 return body.result();
443 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
444 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
446 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
447 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const simple_partitioner>
448 ::run(range, body, partitioner );
449 return body.result();
454 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
455 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
457 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
458 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const auto_partitioner>
459 ::run( range, body, partitioner );
460 return body.result();
465 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
466 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
468 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
469 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const static_partitioner>
470 ::run( range, body, partitioner );
471 return body.result();
476 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
477 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
479 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
480 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
affinity_partitioner>
481 ::run( range, body, partitioner );
482 return body.result();
485 #if __TBB_TASK_GROUP_CONTEXT 488 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
489 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
491 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
492 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const __TBB_DEFAULT_PARTITIONER>
494 return body.result();
499 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
500 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
502 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
503 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const simple_partitioner>
504 ::run( range, body, partitioner, context );
505 return body.result();
510 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
511 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
513 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
514 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const auto_partitioner>
515 ::run( range, body, partitioner, context );
516 return body.result();
521 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
522 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
524 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
525 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const static_partitioner>
526 ::run( range, body, partitioner, context );
527 return body.result();
532 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
533 Value
parallel_reduce(
const Range& range,
const Value& identity,
const RealBody& real_body,
const Reduction& reduction,
535 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
536 internal::start_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
affinity_partitioner>
537 ::run( range, body, partitioner, context );
538 return body.result();
544 template<
typename Range,
typename Body>
551 template<
typename Range,
typename Body>
558 template<
typename Range,
typename Body>
563 #if __TBB_TASK_GROUP_CONTEXT 566 template<
typename Range,
typename Body>
573 template<
typename Range,
typename Body>
580 template<
typename Range,
typename Body>
592 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
599 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
601 internal::lambda_reduce_body<Range,Value,RealBody,Reduction> body(identity, real_body, reduction);
602 internal::start_deterministic_reduce<Range,internal::lambda_reduce_body<Range,Value,RealBody,Reduction>,
const simple_partitioner>
603 ::run(range, body, partitioner);
604 return body.result();
609 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
611 internal::lambda_reduce_body<Range, Value, RealBody, Reduction> body(identity, real_body, reduction);
612 internal::start_deterministic_reduce<Range, internal::lambda_reduce_body<Range, Value, RealBody, Reduction>,
const static_partitioner>
613 ::run(range, body, partitioner);
614 return body.result();
616 #if __TBB_TASK_GROUP_CONTEXT 619 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
627 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
630 internal::lambda_reduce_body<Range, Value, RealBody, Reduction> body(identity, real_body, reduction);
631 internal::start_deterministic_reduce<Range, internal::lambda_reduce_body<Range, Value, RealBody, Reduction>,
const simple_partitioner>
632 ::run(range, body, partitioner, context);
633 return body.result();
638 template<
typename Range,
typename Value,
typename RealBody,
typename Reduction>
641 internal::lambda_reduce_body<Range, Value, RealBody, Reduction> body(identity, real_body, reduction);
642 internal::start_deterministic_reduce<Range, internal::lambda_reduce_body<Range, Value, RealBody, Reduction>,
const static_partitioner>
643 ::run(range, body, partitioner, context);
644 return body.result();
void set_parent(task *p)
sets parent task pointer to specified value
finish_reduce(reduction_context context_)
lambda_reduce_body & operator=(const lambda_reduce_body &other)
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
reduction_context my_context
void offer_work(typename Partitioner::split_type &split_obj)
void parallel_reduce(const Range &range, Body &body)
Parallel iteration with reduction and default partitioner.
finish_deterministic_reduce< Body > finish_type
Dummy type that distinguishes splitting constructor from copy constructor.
internal::affinity_id affinity_id
An id as used for specifying affinity.
Partitioner::task_partition_type my_partition
void * allocate_sibling(task *start_for_task, size_t bytes)
allocate right task with new parent
internal::allocate_continuation_proxy & allocate_continuation()
Returns proxy for overloaded new that allocates a continuation task of *this.
void const char const char int ITT_FORMAT __itt_group_sync s
start_reduce(start_reduce &parent_, typename Partitioner::split_type &split_obj)
Splitting constructor used to generate children.
Used to form groups of tasks.
Task type used to split the work of parallel_deterministic_reduce.
static void run(const Range &range, Body &body, Partitioner &partitioner, task_group_context &context)
Task type used to combine the partial results of parallel_reduce.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
finish_reduce< Body > finish_type
static void run(const Range &range, Body &body, Partitioner &partitioner)
Base class for user-defined tasks.
start_reduce(const Range &range, Body *body, Partitioner &partitioner)
Constructor used for root task.
aligned_space< Body > zombie_space
Task type used to combine the partial results of parallel_deterministic_reduce.
void offer_work(typename Partitioner::split_type &split_obj)
spawn right task, serves as callback for partitioner
const Value & identity_element
task * execute() __TBB_override
Should be overridden by derived classes.
lambda_reduce_body(const lambda_reduce_body &other)
void itt_store_word_with_release(tbb::atomic< T > &dst, U src)
Auxiliary class for parallel_reduce; for internal use only.
#define __TBB_DEFAULT_PARTITIONER
start_deterministic_reduce(start_deterministic_reduce &parent_, finish_type &c, typename Partitioner::split_type &split_obj)
Splitting constructor used to generate children.
const Reduction & my_reduction
start_reduce(start_reduce &parent_, const Range &r, depth_t d)
Construct right child from the given range as response to the demand.
finish_deterministic_reduce(Body &body)
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 offer_work(const Range &r, depth_t d=0)
spawn right task, serves as callback for partitioner
bool has_right_zombie
Pointer to body, or NULL if the left child has not yet finished.
T * begin() const
Pointer to beginning of array.
task * execute() __TBB_override
Should be overridden by derived classes.
const RealBody & my_real_body
static void spawn_root_and_wait(task &root)
Spawn task allocated by allocate_root, wait for it to complete, and deallocate it.
const reduction_context my_context
Partitioner::task_partition_type my_partition
task * execute() __TBB_override
Should be overridden by derived classes.
T itt_load_word_with_acquire(const tbb::atomic< T > &src)
lambda_reduce_body(const Value &identity, const RealBody &body, const Reduction &reduction)
lambda_reduce_body(lambda_reduce_body &other, tbb::split)
Join task node that contains shared flag for stealing feedback.
internal::allocate_child_proxy & allocate_child()
Returns proxy for overloaded new that allocates a child task of *this.
void set_ref_count(int count)
Set reference count.
static void run(const Range &range, Body &body, Partitioner &partitioner)
task * execute() __TBB_override
Should be overridden by derived classes.
void parallel_deterministic_reduce(const Range &range, Body &body)
Parallel iteration with deterministic reduction and default simple partitioner.
static internal::allocate_root_proxy allocate_root()
Returns proxy for overloaded new that allocates a root task.
void operator()(Range &range)
static void run(const Range &range, Body &body, Partitioner &partitioner, task_group_context &context)
Task type used to split the work of parallel_reduce.
virtual task * execute()=0
Should be overridden by derived classes.
Identifiers declared inside namespace internal should never be used directly by client code.
void join(lambda_reduce_body &rhs)