Skip to content

[SYCL][Doc] Deprecate reduction extension #4941

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 12, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion sycl/doc/extensions/Reduction/Reduction.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SYCL(TM) Proposals: Reductions for ND-Range Parallelism

**IMPORTANT**: This specification is a draft.
**IMPORTANT**: The functionality introduced by this extension is deprecated in favor of the standard reduction functionality outlined in [Section 4.9.2 "Reduction variables"](https://www.khronos.org/registry/SYCL/specs/sycl-2020/html/sycl-2020.html#sec:reduction) of the SYCL 2020 Specification, Revision 3.

**NOTE**: Khronos(R) is a registered trademark and SYCL(TM) is a trademark of the Khronos Group, Inc.

Expand All @@ -17,6 +17,9 @@ It should also be noted that reductions are not limited to scalar values: the be
# `reduction` Objects

```c++
namespace sycl {
namespace ext {
namespace oneapi {
template <class T, class BinaryOperation>
unspecified reduction(accessor<T>& var, BinaryOperation combiner);

Expand All @@ -34,12 +37,18 @@ unspecified reduction(span<T, Extent> var, BinaryOperation combiner);

template <class T, class Extent, class BinaryOperation>
unspecified reduction(span<T, Extent> var, const T& identity, BinaryOperation combiner);
}
}
}
```

The exact behavior of a reduction is specific to an implementation; the only interface exposed to the user is the set of functions above, which construct an unspecified `reduction` object encapsulating the reduction variable, an optional operator identity and the reduction operator. For user-defined binary operations, an implementation should issue a compile-time warning if an identity is not specified and this is known to negatively impact performance (e.g. as a result of the implementation choosing a different reduction algorithm). For standard binary operations (e.g. `std::plus`) on arithmetic types, the implementation must determine the correct identity automatically in order to avoid performance penalties.

If an implementation can identify the identity value for a given combination of accumulator type `AccumulatorT` and function object type `BinaryOperation`, the value is defined as a member of the `known_identity` trait class:
```c++
namespace sycl {
namespace ext {
namespace oneapi {
template <typename BinaryOperation, typename AccumulatorT>
struct known_identity {
static constexpr AccumulatorT value;
Expand All @@ -48,11 +57,17 @@ struct known_identity {
// Available if C++17
template <typename BinaryOperation, typename AccumulatorT>
inline constexpr AccumulatorT known_identity_v = known_identity<BinaryOperation, AccumulatorT>::value;
}
}
}
```

Whether `known_identity<BinaryOperation, AccumulatorT>::value` exists can be tested using the `has_known_identity` trait class:

```c++
namespace sycl {
namespace ext {
namespace oneapi {
template <typename BinaryOperation, typename AccumulatorT>
struct has_known_identity {
static constexpr bool value;
Expand All @@ -61,6 +76,9 @@ struct has_known_identity {
// Available if C++17
template <typename BinaryOperation, typename AccumulatorT>
inline constexpr bool has_known_identity_v = has_known_identity<BinaryOperation, AccumulatorT>::value;
}
}
}
```

The dimensionality of the `accessor` passed to the `reduction` function specifies the dimensionality of the reduction variable: a 0-dimensional `accessor` represents a scalar reduction, and any other dimensionality represents an array reduction. Specifying an array reduction of size N is functionally equivalent to specifying N independent scalar reductions. The access mode of the accessor determines whether the reduction variable's original value is included in the reduction (i.e. for `access::mode::read_write` it is included, and for `access::mode::discard_write` it is not). Multiple reductions aliasing the same output results in undefined behavior.
Expand All @@ -70,6 +88,9 @@ The dimensionality of the `accessor` passed to the `reduction` function specifie
# `reducer` Objects

```c++
namespace sycl {
namespace ext {
namespace oneapi {
// Exposition only
template <class T, class BinaryOperation, int Dimensions, /* implementation-defined */>
class reducer
Expand All @@ -91,6 +112,9 @@ class reducer

// other operators should be made available for standard functors
template <typename T> auto& operator+=(reducer<T,std::plus<T>,0>&, const T&);
}
}
}
```

The `reducer` class is not user-constructible, and can only be constructed by an implementation given a `reduction` object. The `combine` function uses the specified `BinaryOperation` to combine the `partial` result with the value held (or referenced) by an instance of `reducer`, and is the only way to update the reducer value for user-supplied combination functions. Other convenience operators should be defined for standard combination functions (e.g. `+=` for `std::plus`).
Expand Down