All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
reduce.h
Go to the documentation of this file.
1//
2// Copyright 2018 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_REDUCE_H
8#define PXR_BASE_WORK_REDUCE_H
9
11#include "pxr/pxr.h"
13#include "pxr/base/work/api.h"
14
15#include <tbb/blocked_range.h>
16#include <tbb/parallel_reduce.h>
17#include <tbb/task_group.h>
18
19PXR_NAMESPACE_OPEN_SCOPE
20
21
81template <typename Fn, typename Rn, typename V>
82V
84 const V &identity,
85 size_t n,
86 Fn &&loopCallback,
87 Rn &&reductionCallback,
88 size_t grainSize)
89{
90 if (n == 0)
91 return identity;
92
93 // Don't bother with parallel_reduce, if concurrency is limited to 1.
94 if (WorkHasConcurrency()) {
95
96 class Work_Body_TBB
97 {
98 public:
99 Work_Body_TBB(Fn &fn) : _fn(fn) { }
100
101 V operator()(
102 const tbb::blocked_range<size_t> &r,
103 const V &value) const {
104 // Note that we std::forward _fn using Fn in order get the
105 // right operator().
106 // We maintain the right type in this way:
107 // If Fn is T&, then reference collapsing gives us T& for _fn
108 // If Fn is T, then std::forward correctly gives us T&& for _fn
109 return std::forward<Fn>(_fn)(r.begin(), r.end(), value);
110 }
111 private:
112 Fn &_fn;
113 };
114
115 // In most cases we do not want to inherit cancellation state from the
116 // parent context, so we create an isolated task group context.
117 tbb::task_group_context ctx(tbb::task_group_context::isolated);
118 return tbb::parallel_reduce(tbb::blocked_range<size_t>(0,n,grainSize),
119 identity,
120 Work_Body_TBB(loopCallback),
121 std::forward<Rn>(reductionCallback),
122 tbb::auto_partitioner(),
123 ctx);
124 }
125
126 // If concurrency is limited to 1, execute serially.
127 return std::forward<Fn>(loopCallback)(0, n, identity);
128}
129
138template <typename Fn, typename Rn, typename V>
139V
141 const V &identity,
142 size_t n,
143 Fn &&loopCallback,
144 Rn &&reductionCallback)
145{
146 return WorkParallelReduceN(identity, n, loopCallback, reductionCallback, 1);
147}
148
149PXR_NAMESPACE_CLOSE_SCOPE
150
151#endif // PXR_BASE_WORK_REDUCE_H
V WorkParallelReduceN(const V &identity, size_t n, Fn &&loopCallback, Rn &&reductionCallback, size_t grainSize)
Recursively splits the range [0, n) into subranges, which are then reduced by invoking loopCallback i...
Definition: reduce.h:83
WORK_API bool WorkHasConcurrency()
Return true if WorkGetPhysicalConcurrencyLimit() returns a number greater than 1 and PXR_WORK_THREAD_...