Skip to content

Commit

Permalink
Move blocked_nd_range out of preview (#1449)
Browse files Browse the repository at this point in the history
---------

Signed-off-by: Tobias Weinzierl <[email protected]>
Co-authored-by: Johannes Bockhorst <[email protected]>
Co-authored-by: Alexey Kukanov <[email protected]>
Co-authored-by: Konstantin Boyarinov <[email protected]>
Co-authored-by: pavelkumbrasev <[email protected]>
  • Loading branch information
5 people authored Nov 7, 2024
1 parent ae2b801 commit d1d43ad
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 88 deletions.
6 changes: 2 additions & 4 deletions include/oneapi/tbb.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2005-2023 Intel Corporation
Copyright (c) 2005-2024 Intel Corporation
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 @@ -28,9 +28,7 @@
#include "oneapi/tbb/blocked_range.h"
#include "oneapi/tbb/blocked_range2d.h"
#include "oneapi/tbb/blocked_range3d.h"
#if TBB_PREVIEW_BLOCKED_RANGE_ND
#include "tbb/blocked_rangeNd.h"
#endif
#include "oneapi/tbb/blocked_nd_range.h"
#include "oneapi/tbb/cache_aligned_allocator.h"
#include "oneapi/tbb/combinable.h"
#include "oneapi/tbb/concurrent_hash_map.h"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2017-2021 Intel Corporation
Copyright (c) 2017-2024 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -14,12 +14,8 @@
limitations under the License.
*/

#ifndef __TBB_blocked_rangeNd_H
#define __TBB_blocked_rangeNd_H

#if !TBB_PREVIEW_BLOCKED_RANGE_ND
#error Set TBB_PREVIEW_BLOCKED_RANGE_ND to include blocked_rangeNd.h
#endif
#ifndef __TBB_blocked_nd_range_H
#define __TBB_blocked_nd_range_H

#include <algorithm> // std::any_of
#include <array>
Expand All @@ -28,6 +24,7 @@

#include "detail/_config.h"
#include "detail/_template_helpers.h" // index_sequence, make_index_sequence
#include "detail/_namespace_injection.h"
#include "detail/_range_common.h"

#include "blocked_range.h"
Expand All @@ -37,45 +34,56 @@ namespace detail {
namespace d1 {

/*
The blocked_rangeNd_impl uses make_index_sequence<N> to automatically generate a ctor with
The blocked_nd_range_impl uses make_index_sequence<N> to automatically generate a ctor with
exactly N arguments of the type tbb::blocked_range<Value>. Such ctor provides an opportunity
to use braced-init-list parameters to initialize each dimension.
Use of parameters, whose representation is a braced-init-list, but they're not
std::initializer_list or a reference to one, produces a non-deduced context
within template argument deduction.
NOTE: blocked_rangeNd must be exactly a templated alias to the blocked_rangeNd_impl
NOTE: blocked_nd_range must be exactly a templated alias to the blocked_nd_range_impl
(and not e.g. a derived class), otherwise it would need to declare its own ctor
facing the same problem that the impl class solves.
*/

template<typename Value, unsigned int N, typename = detail::make_index_sequence<N>>
__TBB_requires(blocked_range_value<Value>)
class blocked_rangeNd_impl;
class blocked_nd_range_impl;

template<typename Value, unsigned int N, std::size_t... Is>
__TBB_requires(blocked_range_value<Value>)
class blocked_rangeNd_impl<Value, N, detail::index_sequence<Is...>> {
class blocked_nd_range_impl<Value, N, detail::index_sequence<Is...>> {
public:
//! Type of a value.
using value_type = Value;

private:
//! Helper type to construct range with N tbb::blocked_range<value_type> objects.
template<std::size_t>
using dim_type_helper = tbb::blocked_range<value_type>;
//! Type of a dimension range.
using dim_range_type = tbb::blocked_range<value_type>;

public:
blocked_rangeNd_impl() = delete;
//! Type for the size of a range.
using size_type = typename dim_range_type::size_type;

blocked_nd_range_impl() = delete;

//! Constructs N-dimensional range over N half-open intervals each represented as tbb::blocked_range<Value>.
blocked_rangeNd_impl(const dim_type_helper<Is>&... args) : my_dims{ {args...} } {}
blocked_nd_range_impl(const indexed_t<dim_range_type, Is>&... args) : my_dims{ {args...} } {}

#if __clang__ && __TBB_CLANG_VERSION < 140000
// On clang prior to version 14.0.0, passing a single braced init list to the constructor of blocked_nd_range<T, 1>
// matches better on the C array constructor and generates compile-time error because of unexpected size
// Adding constraints for this constructor to force the compiler to drop it from overload resolution if the size is unexpected
template <unsigned int M, typename = typename std::enable_if<M == N>::type>
blocked_nd_range_impl(const value_type (&size)[M], size_type grainsize = 1) :
#else
blocked_nd_range_impl(const value_type (&size)[N], size_type grainsize = 1) :
#endif
my_dims { dim_range_type(0, size[Is], grainsize)... } {}

//! Dimensionality of a range.
static constexpr unsigned int ndims() { return N; }
static constexpr unsigned int dim_count() { return N; }

//! Range in certain dimension.
const tbb::blocked_range<value_type>& dim(unsigned int dimension) const {
const dim_range_type& dim(unsigned int dimension) const {
__TBB_ASSERT(dimension < N, "out of bound");
return my_dims[dimension];
}
Expand All @@ -86,44 +94,45 @@ class blocked_rangeNd_impl<Value, N, detail::index_sequence<Is...>> {

//! True if at least one dimension is empty.
bool empty() const {
return std::any_of(my_dims.begin(), my_dims.end(), [](const tbb::blocked_range<value_type>& d) {
return std::any_of(my_dims.begin(), my_dims.end(), [](const dim_range_type& d) {
return d.empty();
});
}

//! True if at least one dimension is divisible.
bool is_divisible() const {
return std::any_of(my_dims.begin(), my_dims.end(), [](const tbb::blocked_range<value_type>& d) {
return std::any_of(my_dims.begin(), my_dims.end(), [](const dim_range_type& d) {
return d.is_divisible();
});
}

blocked_rangeNd_impl(blocked_rangeNd_impl& r, proportional_split proportion) : my_dims(r.my_dims) {
blocked_nd_range_impl(blocked_nd_range_impl& r, proportional_split proportion) : my_dims(r.my_dims) {
do_split(r, proportion);
}

blocked_rangeNd_impl(blocked_rangeNd_impl& r, split proportion) : my_dims(r.my_dims) {
blocked_nd_range_impl(blocked_nd_range_impl& r, split proportion) : my_dims(r.my_dims) {
do_split(r, proportion);
}

private:
static_assert(N != 0, "zero dimensional blocked_rangeNd can't be constructed");
static_assert(N != 0, "zero dimensional blocked_nd_range can't be constructed");

//! Ranges in each dimension.
std::array<tbb::blocked_range<value_type>, N> my_dims;
std::array<dim_range_type, N> my_dims;

template<typename split_type>
void do_split(blocked_rangeNd_impl& r, split_type proportion) {
static_assert((std::is_same<split_type, split>::value || std::is_same<split_type, proportional_split>::value), "type of split object is incorrect");
void do_split(blocked_nd_range_impl& r, split_type proportion) {
static_assert((std::is_same<split_type, split>::value || std::is_same<split_type, proportional_split>::value),
"type of split object is incorrect");
__TBB_ASSERT(r.is_divisible(), "can't split not divisible range");

auto my_it = std::max_element(my_dims.begin(), my_dims.end(), [](const tbb::blocked_range<value_type>& first, const tbb::blocked_range<value_type>& second) {
return (first.size() * second.grainsize() < second.size() * first.grainsize());
auto my_it = std::max_element(my_dims.begin(), my_dims.end(), [](const dim_range_type& first, const dim_range_type& second) {
return (first.size() * double(second.grainsize()) < second.size() * double(first.grainsize()));
});

auto r_it = r.my_dims.begin() + (my_it - my_dims.begin());

my_it->my_begin = tbb::blocked_range<value_type>::do_split(*r_it, proportion);
my_it->my_begin = dim_range_type::do_split(*r_it, proportion);

// (!(my_it->my_begin < r_it->my_end) && !(r_it->my_end < my_it->my_begin)) equals to
// (my_it->my_begin == r_it->my_end), but we can't use operator== due to Value concept
Expand All @@ -133,15 +142,14 @@ class blocked_rangeNd_impl<Value, N, detail::index_sequence<Is...>> {
};

template<typename Value, unsigned int N>
using blocked_rangeNd = blocked_rangeNd_impl<Value, N>;
using blocked_nd_range = blocked_nd_range_impl<Value, N>;

} // namespace d1
} // namespace detail

inline namespace v1 {
using detail::d1::blocked_rangeNd;
using detail::d1::blocked_nd_range;
} // namespace v1
} // namespace tbb

#endif /* __TBB_blocked_rangeNd_H */

#endif /* __TBB_blocked_nd_range_H */
4 changes: 2 additions & 2 deletions include/oneapi/tbb/blocked_range.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2005-2021 Intel Corporation
Copyright (c) 2005-2024 Intel Corporation
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 @@ -152,7 +152,7 @@ class blocked_range {

template<typename DimValue, unsigned int N, typename>
__TBB_requires(blocked_range_value<DimValue>)
friend class blocked_rangeNd_impl;
friend class blocked_nd_range_impl;
};

} // namespace d1
Expand Down
6 changes: 5 additions & 1 deletion include/oneapi/tbb/detail/_template_helpers.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2005-2023 Intel Corporation
Copyright (c) 2005-2024 Intel Corporation
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 @@ -106,6 +106,10 @@ using make_index_sequence = typename make_index_sequence_impl<N>::type;

#endif /* __TBB_CPP14_INTEGER_SEQUENCE_PRESENT */

//! Attach an index to a type to use it with an index sequence
template<typename T, std::size_t>
using indexed_t = T;

#if __TBB_CPP17_LOGICAL_OPERATIONS_PRESENT
using std::conjunction;
using std::disjunction;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2017-2021 Intel Corporation
Copyright (c) 2017-2024 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -14,4 +14,4 @@
limitations under the License.
*/

#include "../oneapi/tbb/blocked_rangeNd.h"
#include "../oneapi/tbb/blocked_nd_range.h"
2 changes: 1 addition & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ if (TARGET TBB::tbb)
tbb_add_test(SUBDIR conformance NAME conformance_blocked_range DEPENDENCIES TBB::tbb)
tbb_add_test(SUBDIR conformance NAME conformance_blocked_range2d DEPENDENCIES TBB::tbb)
tbb_add_test(SUBDIR conformance NAME conformance_blocked_range3d DEPENDENCIES TBB::tbb)
tbb_add_test(SUBDIR conformance NAME conformance_blocked_rangeNd DEPENDENCIES TBB::tbb)
tbb_add_test(SUBDIR conformance NAME conformance_blocked_nd_range DEPENDENCIES TBB::tbb)
tbb_add_test(SUBDIR conformance NAME conformance_concurrent_vector DEPENDENCIES TBB::tbb)
if (NOT TBB_TCM_TESTING)
tbb_add_test(SUBDIR conformance NAME conformance_global_control DEPENDENCIES TBB::tbb)
Expand Down
5 changes: 1 addition & 4 deletions test/common/config.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2005-2021 Intel Corporation
Copyright (c) 2005-2024 Intel Corporation
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 @@ -36,9 +36,6 @@
#ifndef TBB_PREVIEW_VARIADIC_PARALLEL_INVOKE
#define TBB_PREVIEW_VARIADIC_PARALLEL_INVOKE 1
#endif
#ifndef TBB_PREVIEW_BLOCKED_RANGE_ND
#define TBB_PREVIEW_BLOCKED_RANGE_ND 1
#endif
#ifndef TBB_PREVIEW_ISOLATED_TASK_GROUP
#define TBB_PREVIEW_ISOLATED_TASK_GROUP 1
#endif
Expand Down
Loading

0 comments on commit d1d43ad

Please sign in to comment.