OpenVDB
13.0.0
Toggle main menu visibility
Loading...
Searching...
No Matches
PrefixSum.h
Go to the documentation of this file.
1
// Copyright Contributors to the OpenVDB Project
2
// SPDX-License-Identifier: Apache-2.0
3
4
/*!
5
\file nanovdb/util/PrefixSum.h
6
7
\author Ken Museth
8
9
\date March 12, 2023
10
11
\brief Multi-threaded implementations of inclusive prefix sum
12
13
\note An exclusive prefix sum is simply an array starting with zero
14
followed by the elements in the inclusive prefix sum, minus its
15
last entry which is the sum of all the input elements.
16
*/
17
18
#ifndef NANOVDB_UTIL_PREFIX_SUM_H_HAS_BEEN_INCLUDED
19
#define NANOVDB_UTIL_PREFIX_SUM_H_HAS_BEEN_INCLUDED
20
21
#include <
nanovdb/util/Range.h
>
// for Range1D
22
#include <vector>
23
#include <functional>
// for std::plus
24
25
#ifdef NANOVDB_USE_TBB
26
#include <tbb/parallel_scan.h>
27
#endif
28
29
namespace
nanovdb
{
30
31
namespace
util
{
32
33
/// @brief Computes inclusive prefix sum of a vector
34
/// @tparam T Type of the elements in the input/out vector
35
/// @tparam OpT Type of operation performed on each element (defaults to sum)
36
/// @param vec input and output vector
37
/// @param threaded if true multi-threading is used
38
/// @note Inclusive prefix sum: for (i=1; i<N; ++i) vec[i] += vec[i-1]
39
/// @return sum of all input elements, which is also the last element of the inclusive prefix sum
40
template
<
typename
T,
typename
OpT = std::plus<T>>
41
T
prefixSum
(std::vector<T> &vec,
bool
threaded =
true
, OpT op = OpT());
42
43
/// @brief An inclusive scan includes in[i] when computing out[i]
44
/// @note Inclusive prefix operation: for (i=1; i<N; ++i) vec[i] = Op(vec[i],vec[i-1])
45
template
<
typename
T,
typename
Op>
46
void
inclusiveScan
(T *array,
size_t
size,
const
T &identity,
bool
threaded, Op op)
47
{
48
#ifndef NANOVDB_USE_TBB
49
threaded =
false
;
50
(void)identity;
// avoids compiler warning
51
#endif
52
53
if
(threaded) {
54
#ifdef NANOVDB_USE_TBB
55
using
RangeT = tbb::blocked_range<size_t>;
56
tbb::parallel_scan(RangeT(0, size), identity,
57
[&](
const
RangeT &r, T sum,
bool
is_final_scan)->T {
58
T tmp = sum;
59
for
(
size_t
i = r.begin(); i < r.end(); ++i) {
60
tmp = op(tmp, array[i]);
61
if
(is_final_scan) array[i] = tmp;
62
}
63
return
tmp;
64
},[&](
const
T &a,
const
T &b) {
return
op(a, b);}
65
);
66
#endif
67
}
else
{
// serial inclusive prefix operation
68
for
(
size_t
i=1; i<size; ++i) array[i] = op(array[i], array[i-1]);
69
}
70
}
// inclusiveScan
71
72
template
<
typename
T,
typename
OpT>
73
T
prefixSum
(std::vector<T> &vec,
bool
threaded, OpT op)
74
{
75
inclusiveScan
(vec.data(), vec.size(), T(0), threaded, op);
76
return
vec.back();
// sum of all input elements
77
}
// prefixSum
78
79
}
// namespace util
80
81
template
<
typename
T,
typename
OpT = std::plus<T>>
82
[[deprecated(
"Use nanovdb::util::prefixSum instead"
)]]
83
T
prefixSum
(std::vector<T> &vec,
bool
threaded =
true
, OpT op = OpT())
84
{
85
return
util::prefixSum<T, OpT>
(vec, threaded, op);
86
}
// prefixSum
87
88
}
// namespace nanovdb
89
90
#endif
// NANOVDB_UTIL_PREFIX_SUM_H_HAS_BEEN_INCLUDED
Range.h
Custom Range class that is compatible with the tbb::blocked_range classes.
nanovdb::util
Definition
ForEach.h:29
nanovdb::util::prefixSum
T prefixSum(std::vector< T > &vec, bool threaded=true, OpT op=OpT())
Computes inclusive prefix sum of a vector.
Definition
PrefixSum.h:73
nanovdb::util::inclusiveScan
void inclusiveScan(T *array, size_t size, const T &identity, bool threaded, Op op)
An inclusive scan includes in[i] when computing out[i].
Definition
PrefixSum.h:46
nanovdb
Definition
GridHandle.h:27
nanovdb::prefixSum
T prefixSum(std::vector< T > &vec, bool threaded=true, OpT op=OpT())
Definition
PrefixSum.h:83
nanovdb
util
PrefixSum.h
Generated by
1.18.0