You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I start, Size n, S stride, Rest&&... rest);
608
+
</ins>
551
609
<del>}</del>
552
610
}
553
611
}
554
612
<del>}</del>
555
613
</pre>
556
614
</cxx-section>
557
615
616
+
<cxx-sectionid="parallel.alg.reductions">
617
+
<h1><ins>Reductions</ins></h1>
618
+
619
+
<ins>
620
+
<p>
621
+
Each of the function templates in this subclause ([parallel.alg.reductions]) returns a <em>reduction object</em>
622
+
of unspecified type having a <em>reduction value type</em> and encapsulating a <em>reduction identity</em> value for the reduction, a
623
+
<em>combiner</em> function object, and a <em>live-out object</em> from which the initial value is obtained and into which the final
624
+
value is stored.
625
+
</p>
626
+
627
+
<p>
628
+
An algorithm uses reduction objects by allocating an unspecified number of instances, known as <em>accumulators</em>, of the reduction value
629
+
type. <cxx-note>An implementation might, for example, allocate an accumulator for each thread in its private thread pool.</cxx-note>
630
+
Each accumulator is initialized with the object’s reduction identity, except that the live-out object (which was initialized by the
631
+
caller) comprises one of the accumulators. The algorithm passes a reference to an accumulator to each application of an element-access
632
+
function, ensuring that no two concurrently executing invocations share the same accumulator. An accumulator can be shared between two
633
+
applications that do not execute concurrently, but initialization is performed only once per accumulator.
634
+
</p>
635
+
636
+
<p>
637
+
Modifications to the accumulator by the application of element access functions accrue as partial results. At some point before the algorithm
638
+
returns, the partial results are combined, two at a time, using the reduction object’s combiner operation until a single value remains, which
639
+
is then assigned back to the live-out object. <cxx-note> in order to produce useful results, modifications to the accumulator should be limited
640
+
to commutative operations closely related to the combiner operation. For example if the combiner is <code>plus<T></code>, incrementing
641
+
the accumulator would be consistent with the combiner but doubling it or assigning to it would not.</cxx-note>
642
+
</p>
643
+
</ins>
644
+
645
+
<cxx-function>
646
+
<cxx-signature><ins>template<class T, class BinaryOperation>
647
+
<em>unspecified</em> reduction(T& var, const T& identity, BinaryOperation combiner);</ins></cxx-signature>
648
+
649
+
<ins>
650
+
<cxx-requires><ins>T shall meet the requirements of <code>CopyConstructible</code> and <code>MoveAssignable</code>. The expression <code>var = combiner(var, var)</code> shall be well-formed.</ins></cxx-requires>
651
+
</ins>
652
+
653
+
<ins>
654
+
<cxx-returns><ins>a reduction object of unspecified type having reduction value type <code>T</code>, reduction identity <code>identity</code>, combiner function object <code>combiner</code>, and using the object referenced by <code>var</code> as its live-out object.</ins></cxx-returns>
<cxx-requires><ins>T shall meet the requirements of <code>CopyConstructible</code> and <code>MoveAssignable</code>.</ins></cxx-requires>
676
+
</ins>
677
+
678
+
<ins>
679
+
<cxx-returns><ins>a reduction object of unspecified type having reduction value type <code>T</code>, reduction identity and combiner operation as specified in table <cxx-refto="reduction-identities-and-combiner-operations"></cxx-ref> and using the object referenced by <code>var</code> as its live-out object.</ins></cxx-returns>
<cxx-example><ins>The following code updates each element of <code>y</code> and sets <code>s</code> ot the sum of the squares.
730
+
<pre>
731
+
extern int n;
732
+
extern float x[], y[], a;
733
+
float s = 0;
734
+
for_loop(execution::vec, 0, n,
735
+
reduction(s, 0.0f, plus<>()),
736
+
[&](int i, float& accum) {
737
+
y[i] += a*x[i];
738
+
accum += y[i]*y[i];
739
+
}
740
+
);
741
+
</pre>
742
+
</ins></cxx-example>
743
+
</ins>
744
+
</cxx-function>
745
+
</cxx-section>
746
+
747
+
<cxx-sectionid="parallel.alg.inductions">
748
+
<h1><ins>Inductions</ins></h1>
749
+
750
+
<ins>
751
+
<p>
752
+
Each of the function templates in this section return an <em>induction object</em> of unspecified type having an <em>induction
753
+
value type</em> and encapsulating an initial value <em>i</em> of that type and, optionally, a <em>stride</em>.
754
+
</p>
755
+
756
+
<p>
757
+
For each element in the input range, an algorithm over input sequence <em>S</em> computes an <em>induction value</em> from an induction variable
758
+
and ordinal position <em>p</em> within <em>S</em> by the formula <em>i + p * stride</em> if a stride was specified or <em>i + p</em> otherwise. This induction value is
759
+
passed to the element access function.
760
+
</p>
761
+
762
+
<p>
763
+
An induction object may refer to a <em>live-out</em> object to hold the final value of the induction sequence. When the algorithm using the induction
764
+
object completes, the live-out object is assigned the value <em>i + n * stride</em>, where <em>n</em> is the number of elements in the input range.
0 commit comments