Loading...
Searching...
No Matches
reduce_impl.h
1//
2// Copyright 2025 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_BASE_WORK_TBB_REDUCE_IMPL_H
8#define PXR_BASE_WORK_TBB_REDUCE_IMPL_H
9
10#include "pxr/pxr.h"
11
12#include <tbb/blocked_range.h>
13#include <tbb/parallel_reduce.h>
14#include <tbb/task_group.h>
15
16PXR_NAMESPACE_OPEN_SCOPE
17
22template <typename Fn, typename Rn, typename V>
23V
24WorkImpl_ParallelReduceN(
25 const V &identity,
26 size_t n,
27 Fn &&loopCallback,
28 Rn &&reductionCallback,
29 size_t grainSize)
30{
31
32 class Work_Body_TBB
33 {
34 public:
35 Work_Body_TBB(Fn &fn) : _fn(fn) { }
36
37 V operator()(
38 const tbb::blocked_range<size_t> &r,
39 const V &value) const {
40 // Note that we std::forward _fn using Fn in order get the
41 // right operator().
42 // We maintain the right type in this way:
43 // If Fn is T&, then reference collapsing gives us T& for _fn
44 // If Fn is T, then std::forward correctly gives us T&& for _fn
45 return std::forward<Fn>(_fn)(r.begin(), r.end(), value);
46 }
47 private:
48 Fn &_fn;
49 };
50
51 // In most cases we do not want to inherit cancellation state from the
52 // parent context, so we create an isolated task group context.
53 tbb::task_group_context ctx(tbb::task_group_context::isolated);
54 return tbb::parallel_reduce(tbb::blocked_range<size_t>(0,n,grainSize),
55 identity,
56 Work_Body_TBB(loopCallback),
57 std::forward<Rn>(reductionCallback),
58 tbb::auto_partitioner(),
59 ctx);
60}
61
62PXR_NAMESPACE_CLOSE_SCOPE
63
64#endif // PXR_BASE_WORK_TBB_REDUCE_IMPL_H