@@ -221,6 +221,20 @@ class reducer {
221
221
222
222
T getIdentity () const { return MIdentity; }
223
223
224
+ template <typename _T = T>
225
+ enable_if_t <IsReduPlus<_T, BinaryOperation>::value &&
226
+ sycl::detail::is_geninteger<_T>::value>
227
+ operator ++() {
228
+ combine (static_cast <T>(1 ));
229
+ }
230
+
231
+ template <typename _T = T>
232
+ enable_if_t <IsReduPlus<_T, BinaryOperation>::value &&
233
+ sycl::detail::is_geninteger<_T>::value>
234
+ operator ++(int ) {
235
+ combine (static_cast <T>(1 ));
236
+ }
237
+
224
238
template <typename _T = T>
225
239
enable_if_t <IsReduPlus<_T, BinaryOperation>::value>
226
240
operator +=(const _T &Partial) {
@@ -293,6 +307,20 @@ class reducer<T, BinaryOperation,
293
307
return known_identity_impl<_BinaryOperation, _T>::value;
294
308
}
295
309
310
+ template <typename _T = T>
311
+ enable_if_t <IsReduPlus<_T, BinaryOperation>::value &&
312
+ sycl::detail::is_geninteger<_T>::value>
313
+ operator ++() {
314
+ combine (static_cast <T>(1 ));
315
+ }
316
+
317
+ template <typename _T = T>
318
+ enable_if_t <IsReduPlus<_T, BinaryOperation>::value &&
319
+ sycl::detail::is_geninteger<_T>::value>
320
+ operator ++(int ) {
321
+ combine (static_cast <T>(1 ));
322
+ }
323
+
296
324
template <typename _T = T>
297
325
enable_if_t <IsReduPlus<_T, BinaryOperation>::value>
298
326
operator +=(const _T &Partial) {
@@ -419,7 +447,7 @@ class reduction_impl : private reduction_impl_base {
419
447
ONEAPI::accessor_property_list<>>;
420
448
using rw_accessor_type =
421
449
accessor<T, Dims, access::mode::read_write, access::target::global_buffer,
422
- IsPlaceholder , ONEAPI::accessor_property_list<>>;
450
+ access::placeholder:: false_t , ONEAPI::accessor_property_list<>>;
423
451
static constexpr access::mode accessor_mode = AccMode;
424
452
static constexpr int accessor_dim = Dims;
425
453
static constexpr int buffer_dim = (Dims == 0 ) ? 1 : Dims;
@@ -455,6 +483,20 @@ class reduction_impl : private reduction_impl_base {
455
483
return MIdentity;
456
484
}
457
485
486
+ // / SYCL-2020.
487
+ // / Constructs reduction_impl when the identity value is statically known.
488
+ template <typename _T, typename AllocatorT,
489
+ std::enable_if_t <IsKnownIdentityOp<_T, BinaryOperation>::value> * =
490
+ nullptr >
491
+ reduction_impl (buffer<_T, 1 , AllocatorT> Buffer, handler &CGH)
492
+ : MAcc(std::make_shared<accessor_type>(Buffer)),
493
+ MIdentity (getIdentity()) {
494
+ associateWithHandler (CGH);
495
+ if (Buffer.get_count () != 1 )
496
+ throw runtime_error (" Reduction variable must be a scalar." ,
497
+ PI_INVALID_VALUE);
498
+ }
499
+
458
500
// / Constructs reduction_impl when the identity value is statically known.
459
501
// Note that aliasing constructor was used to initialize MAcc to avoid
460
502
// destruction of the object referenced by the parameter Acc.
@@ -465,8 +507,36 @@ class reduction_impl : private reduction_impl_base {
465
507
: MAcc(shared_ptr_class<accessor_type>(shared_ptr_class<accessor_type>{},
466
508
&Acc)),
467
509
MIdentity(getIdentity()) {
468
- assert (Acc.get_count () == 1 &&
469
- " Only scalar/1-element reductions are supported now." );
510
+ if (Acc.get_count () != 1 )
511
+ throw runtime_error (" Reduction variable must be a scalar." ,
512
+ PI_INVALID_VALUE);
513
+ }
514
+
515
+ // / SYCL-2020.
516
+ // / Constructs reduction_impl when the identity value is statically known,
517
+ // / and user still passed the identity value.
518
+ template <
519
+ typename _T, typename AllocatorT,
520
+ enable_if_t <IsKnownIdentityOp<_T, BinaryOperation>::value> * = nullptr >
521
+ reduction_impl (buffer<_T, 1 , AllocatorT> Buffer, handler &CGH,
522
+ const T & /* Identity*/ , BinaryOperation)
523
+ : MAcc(std::make_shared<accessor_type>(Buffer)),
524
+ MIdentity(getIdentity()) {
525
+ associateWithHandler (CGH);
526
+ if (Buffer.get_count () != 1 )
527
+ throw runtime_error (" Reduction variable must be a scalar." ,
528
+ PI_INVALID_VALUE);
529
+ // For now the implementation ignores the identity value given by user
530
+ // when the implementation knows the identity.
531
+ // The SPEC could prohibit passing identity parameter to operations with
532
+ // known identity, but that could have some bad consequences too.
533
+ // For example, at some moment the implementation may NOT know the identity
534
+ // for COMPLEX-PLUS reduction. User may create a program that would pass
535
+ // COMPLEX value (0,0) as identity for PLUS reduction. At some later moment
536
+ // when the implementation starts handling COMPLEX-PLUS as known operation
537
+ // the existing user's program remains compilable and working correctly.
538
+ // I.e. with this constructor here, adding more reduction operations to the
539
+ // list of known operations does not break the existing programs.
470
540
}
471
541
472
542
// / Constructs reduction_impl when the identity value is statically known,
@@ -476,13 +546,13 @@ class reduction_impl : private reduction_impl_base {
476
546
template <
477
547
typename _T = T, class _BinaryOperation = BinaryOperation,
478
548
enable_if_t <IsKnownIdentityOp<_T, _BinaryOperation>::value> * = nullptr >
479
- reduction_impl (accessor_type &Acc, const T &Identity, BinaryOperation)
549
+ reduction_impl (accessor_type &Acc, const T & /* Identity*/ , BinaryOperation)
480
550
: MAcc(shared_ptr_class<accessor_type>(shared_ptr_class<accessor_type>{},
481
551
&Acc)),
482
552
MIdentity(getIdentity()) {
483
- ( void )Identity;
484
- assert (Acc. get_count () == 1 &&
485
- " Only scalar/1-element reductions are supported now. " );
553
+ if (Acc. get_count () != 1 )
554
+ throw runtime_error ( " Reduction variable must be a scalar. " ,
555
+ PI_INVALID_VALUE );
486
556
// For now the implementation ignores the identity value given by user
487
557
// when the implementation knows the identity.
488
558
// The SPEC could prohibit passing identity parameter to operations with
@@ -496,6 +566,21 @@ class reduction_impl : private reduction_impl_base {
496
566
// list of known operations does not break the existing programs.
497
567
}
498
568
569
+ // / SYCL-2020.
570
+ // / Constructs reduction_impl when the identity value is NOT known statically.
571
+ template <
572
+ typename _T, typename AllocatorT,
573
+ enable_if_t <!IsKnownIdentityOp<_T, BinaryOperation>::value> * = nullptr >
574
+ reduction_impl (buffer<_T, 1 , AllocatorT> Buffer, handler &CGH,
575
+ const T &Identity, BinaryOperation BOp)
576
+ : MAcc(std::make_shared<accessor_type>(Buffer)), MIdentity(Identity),
577
+ MBinaryOp(BOp) {
578
+ associateWithHandler (CGH);
579
+ if (Buffer.get_count () != 1 )
580
+ throw runtime_error (" Reduction variable must be a scalar." ,
581
+ PI_INVALID_VALUE);
582
+ }
583
+
499
584
// / Constructs reduction_impl when the identity value is unknown.
500
585
// Note that aliasing constructor was used to initialize MAcc to avoid
501
586
// destruction of the object referenced by the parameter Acc.
@@ -506,8 +591,9 @@ class reduction_impl : private reduction_impl_base {
506
591
: MAcc(shared_ptr_class<accessor_type>(shared_ptr_class<accessor_type>{},
507
592
&Acc)),
508
593
MIdentity(Identity), MBinaryOp(BOp) {
509
- assert (Acc.get_count () == 1 &&
510
- " Only scalar/1-element reductions are supported now." );
594
+ if (Acc.get_count () != 1 )
595
+ throw runtime_error (" Reduction variable must be a scalar." ,
596
+ PI_INVALID_VALUE);
511
597
}
512
598
513
599
// / Constructs reduction_impl when the identity value is statically known.
@@ -587,15 +673,29 @@ class reduction_impl : private reduction_impl_base {
587
673
}
588
674
589
675
// / Constructs a new temporary buffer to hold partial sums and returns
590
- // / the accessor that that buffer.
591
- template <bool IsOneWG>
592
- std::enable_if_t <!IsOneWG, accessor_type>
676
+ // / the accessor for that buffer. Non-placeholder case.
677
+ template <bool IsOneWG, access::placeholder _IsPlaceholder = IsPlaceholder>
678
+ std::enable_if_t <!IsOneWG && _IsPlaceholder == access::placeholder::false_t ,
679
+ accessor_type>
593
680
getWriteMemForPartialReds (size_t Size, handler &CGH) {
594
681
MOutBufPtr = std::make_shared<buffer<T, buffer_dim>>(range<1 >(Size));
595
682
CGH.addReduction (MOutBufPtr);
596
683
return accessor_type (*MOutBufPtr, CGH);
597
684
}
598
685
686
+ // / Constructs a new temporary buffer to hold partial sums and returns
687
+ // / the accessor for that buffer. Placeholder case.
688
+ template <bool IsOneWG, access::placeholder _IsPlaceholder = IsPlaceholder>
689
+ std::enable_if_t <!IsOneWG && _IsPlaceholder == access::placeholder::true_t ,
690
+ accessor_type>
691
+ getWriteMemForPartialReds (size_t Size, handler &CGH) {
692
+ MOutBufPtr = std::make_shared<buffer<T, buffer_dim>>(range<1 >(Size));
693
+ CGH.addReduction (MOutBufPtr);
694
+ accessor_type Acc (*MOutBufPtr);
695
+ CGH.require (Acc);
696
+ return Acc;
697
+ }
698
+
599
699
template <access::placeholder _IsPlaceholder = IsPlaceholder>
600
700
enable_if_t <_IsPlaceholder == access::placeholder::false_t , accessor_type>
601
701
getWriteAccForPartialReds (size_t Size, handler &CGH) {
@@ -624,8 +724,7 @@ class reduction_impl : private reduction_impl_base {
624
724
625
725
// / Creates 1-element global buffer initialized with identity value and
626
726
// / returns an accessor to that buffer.
627
- accessor<T, Dims, access::mode::read_write, access::target::global_buffer>
628
- getReadWriteScalarAcc (handler &CGH) const {
727
+ rw_accessor_type getReadWriteScalarAcc (handler &CGH) const {
629
728
auto RWReduVal = std::make_shared<T>(MIdentity);
630
729
CGH.addReduction (RWReduVal);
631
730
auto RWReduBuf =
@@ -1576,7 +1675,6 @@ template <typename T, class BinaryOperation, int Dims, access::mode AccMode,
1576
1675
detail::reduction_impl<T, BinaryOperation, Dims, false , AccMode, IsPH>
1577
1676
reduction (accessor<T, Dims, AccMode, access::target::global_buffer, IsPH> &Acc,
1578
1677
const T &Identity, BinaryOperation BOp) {
1579
- // The Combiner argument was needed only to define the BinaryOperation param.
1580
1678
return detail::reduction_impl<T, BinaryOperation, Dims, false , AccMode, IsPH>(
1581
1679
Acc, Identity, BOp);
1582
1680
}
@@ -1592,7 +1690,6 @@ std::enable_if_t<
1592
1690
detail::reduction_impl<T, BinaryOperation, Dims, false , AccMode, IsPH>>
1593
1691
reduction (accessor<T, Dims, AccMode, access::target::global_buffer, IsPH> &Acc,
1594
1692
BinaryOperation) {
1595
- // The Combiner argument was needed only to define the BinaryOperation param.
1596
1693
return detail::reduction_impl<T, BinaryOperation, Dims, false , AccMode, IsPH>(
1597
1694
Acc);
1598
1695
}
@@ -1643,29 +1740,5 @@ inline constexpr AccumulatorT known_identity_v =
1643
1740
known_identity<BinaryOperation, AccumulatorT>::value;
1644
1741
#endif
1645
1742
} // namespace ONEAPI
1646
-
1647
- // Currently, the type traits defined below correspond to SYCL 1.2.1 ONEAPI
1648
- // reduction extension. That may be changed later when SYCL 2020 reductions
1649
- // are implemented.
1650
- template <typename BinaryOperation, typename AccumulatorT>
1651
- struct has_known_identity
1652
- : ONEAPI::has_known_identity<BinaryOperation, AccumulatorT> {};
1653
-
1654
- #if __cplusplus >= 201703L
1655
- template <typename BinaryOperation, typename AccumulatorT>
1656
- inline constexpr bool has_known_identity_v =
1657
- has_known_identity<BinaryOperation, AccumulatorT>::value;
1658
- #endif
1659
-
1660
- template <typename BinaryOperation, typename AccumulatorT>
1661
- struct known_identity : ONEAPI::known_identity<BinaryOperation, AccumulatorT> {
1662
- };
1663
-
1664
- #if __cplusplus >= 201703L
1665
- template <typename BinaryOperation, typename AccumulatorT>
1666
- inline constexpr AccumulatorT known_identity_v =
1667
- known_identity<BinaryOperation, AccumulatorT>::value;
1668
- #endif
1669
-
1670
1743
} // namespace sycl
1671
1744
} // __SYCL_INLINE_NAMESPACE(cl)
0 commit comments