@@ -422,6 +422,13 @@ class ReductionIdentityContainer<
422
422
static constexpr bool has_identity = false ;
423
423
};
424
424
425
+ // Token class to help with the in-place construction of reducers.
426
+ template <class BinaryOperation , typename IdentityContainerT>
427
+ struct ReducerToken {
428
+ const IdentityContainerT &IdentityContainer;
429
+ const BinaryOperation BOp;
430
+ };
431
+
425
432
} // namespace detail
426
433
427
434
// / Specialization of the generic class 'reducer'. It is used for reductions
@@ -458,6 +465,14 @@ class reducer<
458
465
reducer (const IdentityContainerT &IdentityContainer, BinaryOperation BOp)
459
466
: MValue(GetInitialValue(IdentityContainer)),
460
467
MIdentity (IdentityContainer), MBinaryOp(BOp) {}
468
+ reducer (
469
+ const detail::ReducerToken<BinaryOperation, IdentityContainerT> &Token)
470
+ : reducer(Token.IdentityContainer, Token.BOp) {}
471
+
472
+ reducer (const reducer &) = delete;
473
+ reducer (reducer &&) = delete;
474
+ reducer &operator =(const reducer &) = delete ;
475
+ reducer &operator =(reducer &&) = delete ;
461
476
462
477
reducer &combine (const T &Partial) {
463
478
if constexpr (has_identity)
@@ -515,6 +530,14 @@ class reducer<
515
530
reducer () : MValue(getIdentity()) {}
516
531
reducer (const IdentityContainerT & /* Identity */ , BinaryOperation)
517
532
: MValue(getIdentity()) {}
533
+ reducer (
534
+ const detail::ReducerToken<BinaryOperation, IdentityContainerT> &Token)
535
+ : reducer(Token.IdentityContainer, Token.BOp) {}
536
+
537
+ reducer (const reducer &) = delete ;
538
+ reducer (reducer &&) = delete ;
539
+ reducer &operator =(const reducer &) = delete ;
540
+ reducer &operator =(reducer &&) = delete ;
518
541
519
542
reducer &combine (const T &Partial) {
520
543
BinaryOperation BOp;
@@ -553,6 +576,14 @@ class reducer<T, BinaryOperation, Dims, Extent, IdentityContainerT, View,
553
576
public:
554
577
reducer (internal_value_type &Ref, BinaryOperation BOp)
555
578
: MElement(Ref), MBinaryOp(BOp) {}
579
+ reducer (
580
+ const detail::ReducerToken<BinaryOperation, IdentityContainerT> &Token)
581
+ : reducer(Token.IdentityContainer, Token.BOp) {}
582
+
583
+ reducer (const reducer &) = delete ;
584
+ reducer (reducer &&) = delete ;
585
+ reducer &operator =(const reducer &) = delete ;
586
+ reducer &operator =(reducer &&) = delete ;
556
587
557
588
reducer &combine (const T &Partial) {
558
589
if constexpr (has_identity)
@@ -599,6 +630,14 @@ class reducer<
599
630
reducer (const IdentityContainerT &IdentityContainer, BinaryOperation BOp)
600
631
: MValue(GetInitialValue(IdentityContainer)),
601
632
MIdentity (IdentityContainer), MBinaryOp(BOp) {}
633
+ reducer (
634
+ const detail::ReducerToken<BinaryOperation, IdentityContainerT> &Token)
635
+ : reducer(Token.IdentityContainer, Token.BOp) {}
636
+
637
+ reducer (const reducer &) = delete;
638
+ reducer (reducer &&) = delete;
639
+ reducer &operator =(const reducer &) = delete ;
640
+ reducer &operator =(reducer &&) = delete ;
602
641
603
642
reducer<T, BinaryOperation, Dims - 1 , Extent, IdentityContainerT, true >
604
643
operator [](size_t Index) {
@@ -650,6 +689,14 @@ class reducer<
650
689
reducer () : MValue(getIdentity()) {}
651
690
reducer (const IdentityContainerT & /* Identity */ , BinaryOperation)
652
691
: MValue(getIdentity()) {}
692
+ reducer (
693
+ const detail::ReducerToken<BinaryOperation, IdentityContainerT> &Token)
694
+ : reducer(Token.IdentityContainer, Token.BOp) {}
695
+
696
+ reducer (const reducer &) = delete ;
697
+ reducer (reducer &&) = delete ;
698
+ reducer &operator =(const reducer &) = delete ;
699
+ reducer &operator =(reducer &&) = delete ;
653
700
654
701
// SYCL 2020 revision 4 says this should be const, but this is a bug
655
702
// see https://github.com/KhronosGroup/SYCL-Docs/pull/252
@@ -746,6 +793,8 @@ class reduction_impl_algo {
746
793
747
794
using identity_container_type =
748
795
ReductionIdentityContainer<T, BinaryOperation, ExplicitIdentity>;
796
+ using reducer_token_type =
797
+ detail::ReducerToken<BinaryOperation, identity_container_type>;
749
798
using reducer_type =
750
799
reducer<T, BinaryOperation, Dims, Extent, identity_container_type>;
751
800
using result_type = T;
@@ -2062,8 +2111,11 @@ void reduCGFuncMulti(handler &CGH, KernelType KernelFunc,
2062
2111
// Pass all reductions to user's lambda in the same order as supplied
2063
2112
// Each reducer initializes its own storage
2064
2113
auto ReduIndices = std::index_sequence_for<Reductions...>();
2065
- auto ReducersTuple = std::tuple{typename Reductions::reducer_type{
2066
- std::get<Is>(IdentitiesTuple), std::get<Is>(BOPsTuple)}...};
2114
+ auto ReducerTokensTuple =
2115
+ std::tuple{typename Reductions::reducer_token_type{
2116
+ std::get<Is>(IdentitiesTuple), std::get<Is>(BOPsTuple)}...};
2117
+ auto ReducersTuple = std::tuple<typename Reductions::reducer_type...>{
2118
+ std::get<Is>(ReducerTokensTuple)...};
2067
2119
std::apply ([&](auto &...Reducers ) { KernelFunc (NDIt, Reducers...); },
2068
2120
ReducersTuple);
2069
2121
0 commit comments