Skip to content
Open
Show file tree
Hide file tree
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
149 changes: 0 additions & 149 deletions doc/main/reference/blocked_nd_range_ctad.rst

This file was deleted.

61 changes: 0 additions & 61 deletions doc/main/reference/examples/blocked_nd_range_ctad_example.cpp

This file was deleted.

1 change: 0 additions & 1 deletion doc/main/reference/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,3 @@ The key properties of a preview feature are:
custom_mutex_chmap
try_put_and_wait
parallel_phase_for_task_arena
blocked_nd_range_ctad
5 changes: 3 additions & 2 deletions include/oneapi/tbb/blocked_nd_range.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright (c) 2017-2025 Intel Corporation
Copyright (c) 2025 UXL Foundation Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -147,7 +148,7 @@ class blocked_nd_range : public blocked_nd_range_impl<Value, N> {
using base::base;
};

#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT && __TBB_PREVIEW_BLOCKED_ND_RANGE_DEDUCTION_GUIDES
#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
// blocked_nd_range(const dim_range_type& dim0, const dim_range_type& dim1, ...)
// while the arguments are passed as braced-init-lists
// Works only for 2 and more arguments since the deduction from
Expand Down Expand Up @@ -182,7 +183,7 @@ template <typename Value, unsigned int N>
blocked_nd_range(blocked_nd_range<Value, N>, oneapi::tbb::proportional_split)
-> blocked_nd_range<Value, N>;

#endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT && __TBB_PREVIEW_BLOCKED_ND_RANGE_DEDUCTION_GUIDES
#endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT

} // namespace d1
} // namespace detail
Expand Down
4 changes: 0 additions & 4 deletions include/oneapi/tbb/detail/_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -542,10 +542,6 @@
#define __TBB_PREVIEW_PARALLEL_PHASE 1
#endif

#if TBB_PREVIEW_BLOCKED_ND_RANGE_DEDUCTION_GUIDES
#define __TBB_PREVIEW_BLOCKED_ND_RANGE_DEDUCTION_GUIDES 1
#endif

#if !__TBB_DISABLE_SPEC_EXTENSIONS
#define TBB_EXT_CUSTOM_ASSERTION_HANDLER 202510
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Introduction

`oneapi::tbb::blocked_nd_range` class was introduced as a representation for recursively divisible N-dimensional range for oneTBB parallel algorithms.
This document proposes extending its API with the deduction guides since C++17 to allow dropping the explicit template arguments specification while
This document describes extending its API with the deduction guides since C++17 that allows dropping the explicit template arguments specification while
creating the object if they can be determined using the arguments provided:

```cpp
Expand All @@ -16,7 +16,7 @@ oneapi::tbb::blocked_range<int> range3(0, 300);
oneapi::tbb::blocked_nd_range nd_range(range1, range2, range3);
```

## Proposal
## Design description

### Supported constructors

Expand Down Expand Up @@ -78,9 +78,9 @@ the number of elements in the braced-init list equal to the number of dimensions
Constructors `[3]` and `[4]` are intended to split the range into two parts. They are part of _Range_ Named Requirements and used internally in the
implementation of oneTBB parallel algorithms.

### Proposed deduction guides
### Deduction guides

This paper proposes to add explicit deduction guides for `blocked_nd_range` class:
The following explicit deduction guides for ``blocked_nd_range`` class are supported by oneTBB implementation:

```cpp
// [g1]
Expand All @@ -92,8 +92,8 @@ blocked_nd_range(blocked_range<Value>, blocked_range<Values>...)
This deduction guide corresponds to the constructor `[1]` for the case of passing _N_ `blocked_range` objects itself.
It only participates in overload resolution if all of the types in `Values` are same as `Value`.

To cover the case while blocked_ranges are passed as braced-init-lists, it is proposed to add a deduction guide taking
a set of C-array objects.
To cover the case when blocked_ranges are passed as braced-init-lists, a deduction guide is added that takes a set of C-array objects.


There are currently two options how to define the deduction guide (or a function) taking the braced-init-list
of any type- C-array and `std::initializer_list`. The issue with `std::initializer_list` is that it does not allow
Expand All @@ -107,7 +107,7 @@ blocked_nd_range(const Value (&...)[Ns])
```

This deduction guide only participates in overload resolution if
1. the number of C-arrays provided is more than 1 (`sizeof...(Ns) > 1`),
1. the number of C-arrays provided is $>=2$ (`sizeof...(Ns) >= 2`),
2. Each C-array has the size 2 or 3.

The first constraint is intended to disambiguate between `[1]` and `[2]`.
Expand All @@ -132,15 +132,15 @@ blocked_nd_range range1({vector.begin(), vector.end()});
blocked_nd_range range({vector.begin(), vector.end(), /*grainsize = */5});
```

For the constructor `[2]`, the following deduction guide is proposed:
For the constructor `[2]`, the following deduction guide is provided:

```cpp
// [g3]
template <typename Value, unsigned int N>
blocked_nd_range(const Value (&)[N])
```

For service constructors `[3]` and `[4]`, the following guides are proposed:
For service constructors `[3]` and `[4]`, the following guides are provided:

```cpp
// [g4]
Expand All @@ -156,9 +156,9 @@ blocked_nd_range(blocked_nd_range<Value, N>, proportional_split)

From the specification perspective, such a deduction guides can be generated as implicit deduction guides, in the same manner as copy and move constructors.
But the current oneTBB implementation, these deduction guides are not generated implicitly, so the explicit guides are required.
Guides `[g4]` and `[g5]` are not proposed to be a part of the spec, only a part of oneTBB implementation.
Guides `[g4]` and `[g5]` are no part of the spec, only a part of oneTBB implementation.

## Open Questions
## Design conclusions

### Ambiguity while passing the single braced-init-list of size 2 or 3

Expand All @@ -175,8 +175,8 @@ Since the template arguments for `blocked_nd_range` are not specified, there can
2. Be interpreted as two (or three) dimensional range _[0, 10)_, _[0, 20)_ (and _[0, 5)_). In this case it should be deduced as `blocked_nd_range<int, 3>`
and constructed using the constructor `[2]`.

Since it is unclear which resolution should be chosen, current proposal is not to support such use-case in CTAD and require the user to either explicitly
specialize the template arguments, or to use array or `blocked_range` type itself to initialize the object.
The current oneTBB implementation prefers the second option since the multi-dimensional ranges are more practical and for consistency with the behavior described
in [Passing single C-array object of size 2 or 3](#passing-single-c-array-object-of-size-2-or-3) section.

### Passing single C-array object of size 2 or 3

Expand All @@ -190,38 +190,19 @@ tbb::blocked_nd_range range(array);
Since the `blocked_range` is not constructible from C-array and the braced-init-list is not used, the user expects the range to be deduced as
`blocked_nd_range<int, 2>` and the constructor `[2]` to be used.

If we add one more explicit deduction guide to support the code above, the single braced-init-list of size 2 or 3 would also match on this guide.

There are the following options how this issue can be resolved:
* Add a new deduction guide to support the code above. The downside of this approach is that it makes the ambiguity, discussed in the
[previous section](#ambiguity-while-passing-the-single-braced-init-list-of-size-2-or-3) to be resolved also and always result in 2 or 3-dimensional
range. If the user provided the single braced-init-list to have one-dimensional range, he would face the unexpected behavior without any diagnostics.
* Document the code above as limitation and do not support it. The downside is that the code above is considered valid, but
cannot be supported because of the implementation of CTAD and current set of constructors.
* Support the use-case above but do not support CTAD for braced-init-lists at all. The major downside is that the user would
need to always specify the exact type `tbb::blocked_range` while using the braced-init-list construction.
Current oneTBB implementation supports such a behavior constraining a braced-init-list deduction guide to allow 2 or more lists and hence
by resolving an ambiguity described in
[Ambiguity while passing the single braced-init-list of size 2 or 3](#ambiguity-while-passing-the-single-braced-init-list-of-size-2-or-3)
to always prefer a multi-dimensional range.

### Using the constructor `[1]` with "mixed" arguments

There is a limitation of the deduction guides proposed if the constructor `[1]` is used with both arguments of exact `tbb::blocked_range` type
There is a limitation of the deduction guides if the constructor `[1]` is used with both arguments of exact `tbb::blocked_range` type
and the braced-init-lists:

```cpp
tbb::blocked_range<int> dim_range(0, 100);
tbb::blocked_nd_range nd_range(dim_range, {0, 200}, {0, 300}, dim_range);
```

These arguments would not match nether on the `[g1]` not `[g2]` and it is unclear how to define the deduction guide that covers this case.
Current proposal is to keep this scenario a limitation for using the CTAD and always require using the consistent set of parameters - or
the set of braced-init-lists or the set of `tbb::blocked_range` objects.

## Exit criteria

The following conditions need to be met to move the feature from experimental to fully supported:
* Collecting feedback on user experience confirming the choices made on the open questions and limitations:
* Preference of multi-dimensional range while deducing from the C-array or braced-init-list of size 2 or 3.
See [separate section](#passing-single-c-array-object-of-size-2-or-3) for more details.
* Limitation for the deduction from the braced-init-list to accept only the lists of items of the same type.
* Limitation for the deduction guide `1` in case of mixing `blocked_range` objects and braced-init-lists.
See [separate section](#using-the-constructor-1-with-mixed-arguments) for more details.
* The corresponding oneTBB specification update should be done backed by the user feedback provided.
These arguments would not match neither on the `[g1]` not `[g2]` and it is unclear how to define the deduction guide that covers this case.
Loading