-
Notifications
You must be signed in to change notification settings - Fork 0
/
cpu-all-noarr-bag.cpp
91 lines (73 loc) · 2.53 KB
/
cpu-all-noarr-bag.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#define CPU
#include "histomain.hpp"
#include <noarr/structures_extended.hpp>
#include <noarr/structures/extra/traverser.hpp>
#include <noarr/structures/interop/traverser_iter.hpp>
#include <noarr/structures/interop/bag.hpp>
#ifndef HISTO_IMPL
#error Add -DHISTO_IMPL=(histo_loop|histo_range|histo_foreach|histo_tbbreduce) to compiler commandline
#define HISTO_IMPL histo_undefined
#endif
#ifdef HISTO_HAVE_TBB
#include <noarr/structures/interop/tbb.hpp>
#endif
enum {
histo_loop,
histo_range,
histo_foreach,
histo_tbbreduce,
histo_undefined
};
void run_histogram(value_t *in_ptr, std::size_t size, std::size_t *out_ptr) {
if constexpr (HISTO_IMPL == histo_loop) {
auto in = noarr::make_bag(noarr::scalar<value_t>() ^ noarr::sized_vector<'i'>(size), in_ptr);
auto out = noarr::make_bag(noarr::scalar<std::size_t>() ^ noarr::array<'v', 256>(), out_ptr);
for(std::size_t i = 0; i < size; ++i) {
value_t value = in[noarr::idx<'i'>(i)];
out[noarr::idx<'v'>(value)] += 1;
}
}
else if constexpr (HISTO_IMPL == histo_range) {
auto in = noarr::make_bag(noarr::scalar<value_t>() ^ noarr::sized_vector<'i'>(size), in_ptr);
auto out = noarr::make_bag(noarr::scalar<std::size_t>() ^ noarr::array<'v', 256>(), out_ptr);
for(auto elem : noarr::traverser(in)) {
value_t value = in[elem.state()];
out[noarr::idx<'v'>(value)] += 1;
}
}
else if constexpr (HISTO_IMPL == histo_foreach) {
auto in = noarr::make_bag(noarr::scalar<value_t>() ^ noarr::sized_vector<'i'>(size), in_ptr);
auto out = noarr::make_bag(noarr::scalar<std::size_t>() ^ noarr::array<'v', 256>(), out_ptr);
// PAPER 3.2 First example
noarr::traverser(in).for_each([in, out](auto in_state) {
value_t value = in[in_state];
out[noarr::idx<'v'>(value)] += 1;
});
}
#ifdef HISTO_HAVE_TBB
else if constexpr (HISTO_IMPL == histo_tbbreduce) {
auto in = noarr::make_bag(noarr::scalar<value_t>() ^ noarr::sized_vector<'i'>(size), in_ptr);
auto out = noarr::make_bag(noarr::scalar<std::size_t>() ^ noarr::array<'v', 256>(), out_ptr);
// PAPER 3.2 Second example
noarr::tbb_reduce_bag(
// Input traverser.
noarr::traverser(in),
// Neutralizing function, OutElem := 0
[](auto out_state, auto &out_left) {
out_left[out_state] = 0;
},
// Accumulation function, Out += InElem
[in](auto in_state, auto &out_left) {
value_t value = in[in_state];
out_left[noarr::idx<'v'>(value)] += 1;
},
// Joining function, OutElem += OutElem
[](auto out_state, auto &out_left, const auto &out_right) {
out_left[out_state] += out_right[out_state];
},
// Output bag.
out
);
}
#endif
}