HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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 
10 /// \file work/reduce.h
11 #include "pxr/pxr.h"
12 #include "pxr/base/work/api.h"
13 #include "pxr/base/work/impl.h"
15 
17 
18 
19 ///////////////////////////////////////////////////////////////////////////////
20 ///
21 /// Recursively splits the range [0, \p n) into subranges, which are then
22 /// reduced by invoking \p loopCallback in parallel. Each invocation of
23 /// \p loopCallback returns a single value that is the result of joining the
24 /// elements in the respective subrange. These values are then further joined
25 /// using the binary operator \p reductionCallback, until only a single value
26 /// remains. This single value is then the result of joining all elements over
27 /// the entire range [0, \p n).
28 ///
29 /// The \p loopCallback must be of the form:
30 ///
31 /// V LoopCallback(size_t begin, size_t end, const V &identity);
32 ///
33 /// The \p reductionCallback must be of the form:
34 ///
35 /// V ReductionCallback(const V &lhs, const V &rhs);
36 ///
37 /// For example, the following code reduces an array of mesh points into a
38 /// single bounding box:
39 ///
40 /// ```{.cpp}
41 ///
42 /// // Get the mesh points from which we are going to generate the bounding box.
43 /// const std::vector<Vector3> &points = GetMeshPoints();
44 ///
45 /// // Generate the bounding box by parallel reducing the points.
46 /// BoundingBox bbox = WorkParallelReduceN(
47 /// BoundingBox(),
48 /// points.size(),
49 /// [&points](size_t b, size_t e, const BoundingBox &identity){
50 /// BoundingBox bbox(identity);
51 ///
52 /// // Insert each point in this subrange into the local bounding box.
53 /// for (size_t i = b; i != e; ++i) {
54 /// bbox.InsertPoint(points[i]);
55 /// }
56 ///
57 /// // Return the local bounding box, which now encapsulates all the
58 /// // points in this subrange.
59 /// return bbox;
60 /// },
61 /// [](const BoundingBox &lhs, const BoundingBox &rhs){
62 /// // Join two bounding boxes into a single bounding box. The
63 /// // algorithm will apply this reduction step recursively until there
64 /// // is only a single bounding box left.
65 /// BoundingBox bbox(lhs);
66 /// bbox.UnionWith(rhs);
67 /// return bbox;
68 /// }
69 /// );
70 ///
71 /// ```
72 ///
73 /// \p grainSize specifies a minimum amount of work to be done per-thread.
74 /// There is overhead to launching a task and a typical guideline is that
75 /// you want to have at least 10,000 instructions to count for the overhead of
76 /// launching that task.
77 ///
78 template <typename Fn, typename Rn, typename V>
79 V
81  const V &identity,
82  size_t n,
83  Fn &&loopCallback,
84  Rn &&reductionCallback,
85  size_t grainSize)
86 {
87  if (n == 0)
88  return identity;
89 
90  // Don't bother with parallel_reduce, if concurrency is limited to 1.
91  if (WorkHasConcurrency()) {
94  identity,
95  n,
96  std::forward<Fn>(loopCallback),
97  std::forward<Rn>(reductionCallback),
98  grainSize);
99  }
100 
101  // If concurrency is limited to 1, execute serially.
102  return std::forward<Fn>(loopCallback)(0, n, identity);
103 }
104 
105 ///////////////////////////////////////////////////////////////////////////////
106 ///
107 /// \overload
108 ///
109 /// This overload does not accept a grain size parameter and instead attempts
110 /// to automatically deduce a grain size that is optimal for the current
111 /// resource utilization and provided workload.
112 ///
113 template <typename Fn, typename Rn, typename V>
114 V
116  const V &identity,
117  size_t n,
118  Fn &&loopCallback,
119  Rn &&reductionCallback)
120 {
121  return WorkParallelReduceN(identity, n, loopCallback, reductionCallback, 1);
122 }
123 
125 
126 #endif // PXR_BASE_WORK_REDUCE_H
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
PXR_NAMESPACE_OPEN_SCOPE V WorkImpl_ParallelReduceN(const V &identity, size_t n, Fn &&loopCallback, Rn &&reductionCallback, size_t grainSize)
Definition: reduce_impl.h:24
GLdouble n
Definition: glcorearb.h:2008
PXR_NAMESPACE_OPEN_SCOPE V WorkParallelReduceN(const V &identity, size_t n, Fn &&loopCallback, Rn &&reductionCallback, size_t grainSize)
Definition: reduce.h:80
WORK_API bool WorkHasConcurrency()
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
#define PXR_WORK_IMPL_NAMESPACE_USING_DIRECTIVE
Definition: impl.h:17