124template <
typename C = DefaultClosureWrapper>
180 template <
typename F>
186 template <
typename F>
187 TF_FORCE_INLINE
decltype(
auto)
operator () (F&& callable) {
189 return std::forward<F>(callable);
193 return [
this, c=std::forward<F>(callable)]()
mutable {
_closure_wrapper(c); };
253template <
typename C = DefaultClosureWrapper>
288 template <
typename F>
289 requires std::invocable<F, size_t, size_t>
291 size_t N,
size_t W, std::atomic<size_t>& next, F&& func
297 float p2 = 0.5f /
static_cast<float>(W);
298 size_t curr_b = next.load(std::memory_order_relaxed);
302 size_t r = N - curr_b;
307 curr_b = next.fetch_add(
chunk_size, std::memory_order_relaxed);
311 func(curr_b, (std::min)(curr_b +
chunk_size, N));
317 size_t q =
static_cast<size_t>(p2 * r);
322 size_t curr_e = (std::min)(curr_b + q, N);
323 if(next.compare_exchange_strong(curr_b, curr_e, std::memory_order_relaxed,
324 std::memory_order_relaxed)) {
325 func(curr_b, curr_e);
326 curr_b = next.load(std::memory_order_relaxed);
335 template <
typename F>
336 requires (std::invocable<F, size_t, size_t> && std::same_as<std::invoke_result_t<F, size_t, size_t>,
bool>)
338 size_t N,
size_t W, std::atomic<size_t>& next, F&& func
344 float p2 = 0.5f /
static_cast<float>(W);
345 size_t curr_b = next.load(std::memory_order_relaxed);
349 size_t r = N - curr_b;
354 curr_b = next.fetch_add(
chunk_size, std::memory_order_relaxed);
358 if(func(curr_b, (std::min)(curr_b +
chunk_size, N))) {
366 size_t q =
static_cast<size_t>(p2 * r);
371 size_t curr_e = (std::min)(curr_b + q, N);
372 if(next.compare_exchange_strong(curr_b, curr_e, std::memory_order_relaxed,
373 std::memory_order_relaxed)) {
374 if(func(curr_b, curr_e)) {
377 curr_b = next.load(std::memory_order_relaxed);
428template <
typename C = DefaultClosureWrapper>
462 template <
typename F>
463 requires std::invocable<F, size_t, size_t>
465 size_t N,
size_t, std::atomic<size_t>& next, F&& func
469 size_t curr_b = next.fetch_add(
chunk_size, std::memory_order_relaxed);
472 func(curr_b, (std::min)(curr_b +
chunk_size, N));
473 curr_b = next.fetch_add(
chunk_size, std::memory_order_relaxed);
480 template <
typename F>
481 requires (std::invocable<F, size_t, size_t> && std::same_as<std::invoke_result_t<F, size_t, size_t>,
bool>)
483 size_t N,
size_t, std::atomic<size_t>& next, F&& func
487 size_t curr_b = next.fetch_add(
chunk_size, std::memory_order_relaxed);
490 if(func(curr_b, (std::min)(curr_b +
chunk_size, N))) {
493 curr_b = next.fetch_add(
chunk_size, std::memory_order_relaxed);
550template <
typename C = DefaultClosureWrapper>
595 template <
typename F>
596 requires std::invocable<F, size_t, size_t>
598 size_t N,
size_t W,
size_t curr_b,
size_t chunk_size, F&& func
602 size_t curr_e = (std::min)(curr_b +
chunk_size, N);
603 func(curr_b, curr_e);
611 template <
typename F>
612 requires (std::invocable<F, size_t, size_t> && std::same_as<std::invoke_result_t<F, size_t, size_t>,
bool>)
614 size_t N,
size_t W,
size_t curr_b,
size_t chunk_size, F&& func
618 size_t curr_e = (std::min)(curr_b +
chunk_size, N);
619 if(func(curr_b, curr_e)) {
670template <
typename C = DefaultClosureWrapper>
713 float alpha()
const {
return _alpha; }
718 float beta()
const {
return _beta; }
728 size_t b1 =
static_cast<size_t>(_alpha * N * W);
729 size_t b2 =
static_cast<size_t>(_beta * N * W);
735 b1 = (std::max)(b1,
size_t{1});
736 b2 = (std::max)(b2, b1 + 1);
748 template <
typename F>
749 requires std::invocable<F, size_t, size_t>
751 size_t N,
size_t W, std::atomic<size_t>& next, F&& func
756 std::default_random_engine engine {std::random_device{}()};
757 std::uniform_int_distribution<size_t> dist(b1, b2);
760 size_t curr_b = next.fetch_add(
chunk_size, std::memory_order_relaxed);
763 func(curr_b, (std::min)(curr_b +
chunk_size, N));
765 curr_b = next.fetch_add(
chunk_size, std::memory_order_relaxed);
772 template <
typename F>
773 requires (std::invocable<F, size_t, size_t> && std::same_as<std::invoke_result_t<F, size_t, size_t>,
bool>)
775 size_t N,
size_t W, std::atomic<size_t>& next, F&& func
780 std::default_random_engine engine {std::random_device{}()};
781 std::uniform_int_distribution<size_t> dist(b1, b2);
784 size_t curr_b = next.fetch_add(
chunk_size, std::memory_order_relaxed);
787 if(func(curr_b, (std::min)(curr_b +
chunk_size, N))){
791 curr_b = next.fetch_add(
chunk_size, std::memory_order_relaxed);
797 float _alpha {0.01f};
815concept Partitioner = std::derived_from<P, PartitionerBase<typename P::closure_wrapper_type>>;
class to create a default closure wrapper
Definition partitioner.hpp:51
DynamicPartitioner()=default
default constructor
DynamicPartitioner(size_t sz, C &&closure)
construct a dynamic partitioner with the given chunk size and the closure
Definition partitioner.hpp:451
static constexpr PartitionerType type()
queries the partition type (dynamic)
Definition partitioner.hpp:436
DynamicPartitioner(size_t sz)
construct a dynamic partitioner with the given chunk size
Definition partitioner.hpp:446
class to create a guided partitioner for scheduling parallel algorithms
Definition partitioner.hpp:254
GuidedPartitioner(size_t sz, C &&closure)
construct a guided partitioner with the given chunk size and the closure
Definition partitioner.hpp:277
GuidedPartitioner(size_t sz)
construct a guided partitioner with the given chunk size
Definition partitioner.hpp:272
GuidedPartitioner()=default
default constructor
static constexpr PartitionerType type()
queries the partition type (dynamic)
Definition partitioner.hpp:261
PartitionerBase(size_t chunk_size)
construct a partitioner with the given chunk size
Definition partitioner.hpp:147
static constexpr bool is_default_wrapper_v
indicating if the given closure wrapper is a default wrapper (i.e., empty)
Definition partitioner.hpp:132
C closure_wrapper_type
the closure type
Definition partitioner.hpp:137
void chunk_size(size_t cz)
update the chunk size of this partitioner
Definition partitioner.hpp:165
const C & closure_wrapper() const
acquire an immutable access to the closure wrapper object
Definition partitioner.hpp:170
void closure_wrapper(F &&fn)
modify the closure wrapper object
Definition partitioner.hpp:181
C _closure_wrapper
closure wrapper
Definition partitioner.hpp:207
PartitionerBase(size_t chunk_size, C &&closure_wrapper)
construct a partitioner with the given chunk size and closure wrapper
Definition partitioner.hpp:152
size_t _chunk_size
chunk size
Definition partitioner.hpp:202
C & closure_wrapper()
acquire a mutable access to the closure wrapper object
Definition partitioner.hpp:175
PartitionerBase()=default
default constructor
size_t chunk_size() const
query the chunk size of this partitioner
Definition partitioner.hpp:160
RandomPartitioner(size_t sz, C &&closure)
construct a random partitioner with the given chunk size and the closure
Definition partitioner.hpp:693
RandomPartitioner(float alpha, float beta, C &&closure)
constructs a random partitioner with the given parameters and the closure
Definition partitioner.hpp:705
std::pair< size_t, size_t > chunk_size_range(size_t N, size_t W) const
queries the range of chunk size
Definition partitioner.hpp:726
RandomPartitioner(float alpha, float beta)
constructs a random partitioner with the given parameters
Definition partitioner.hpp:700
RandomPartitioner()=default
default constructor
static constexpr PartitionerType type()
queries the partition type (dynamic)
Definition partitioner.hpp:678
float alpha() const
queries the alpha value
Definition partitioner.hpp:713
RandomPartitioner(size_t sz)
construct a dynamic partitioner with the given chunk size
Definition partitioner.hpp:688
float beta() const
queries the beta value
Definition partitioner.hpp:718
StaticPartitioner()=default
default constructor
size_t adjusted_chunk_size(size_t N, size_t W, size_t w) const
queries the adjusted chunk size
Definition partitioner.hpp:584
StaticPartitioner(size_t sz)
construct a static partitioner with the given chunk size
Definition partitioner.hpp:568
StaticPartitioner(size_t sz, C &&closure)
construct a static partitioner with the given chunk size and the closure
Definition partitioner.hpp:573
static constexpr PartitionerType type()
queries the partition type (static)
Definition partitioner.hpp:558
determines if a type is a partitioner
Definition partitioner.hpp:815
taskflow namespace
Definition small_vector.hpp:20
@ STATIC
static task type
Definition task.hpp:25
PartitionerType
enumeration of all partitioner types
Definition partitioner.hpp:19
@ DYNAMIC
dynamic partitioner type
Definition partitioner.hpp:23
@ STATIC
static partitioner type
Definition partitioner.hpp:21
constexpr bool is_partitioner_v
determines if a type is a partitioner (variable template)
Definition partitioner.hpp:825
GuidedPartitioner<> DefaultPartitioner
default partitioner set to tf::GuidedPartitioner
Definition partitioner.hpp:807