Morpheus 1.0.0
Dynamic matrix type and algorithms for sparse matrices
Loading...
Searching...
No Matches
DenseVector/Serial/Morpheus_Scan_Impl.hpp
1
24#ifndef MORPHEUS_DENSEVECTOR_SERIAL_SCAN_IMPL_HPP
25#define MORPHEUS_DENSEVECTOR_SERIAL_SCAN_IMPL_HPP
26
27#include <Morpheus_Macros.hpp>
28#if defined(MORPHEUS_ENABLE_SERIAL)
29
30#include <Morpheus_SpaceTraits.hpp>
31#include <Morpheus_FormatTraits.hpp>
32#include <Morpheus_FormatTags.hpp>
33#include <Morpheus_Spaces.hpp>
34
35namespace Morpheus {
36namespace Impl {
37
38template <typename ExecSpace, typename Vector>
39void inclusive_scan(const Vector& in, Vector& out,
40 typename Vector::index_type size,
41 typename Vector::index_type start,
42 typename std::enable_if_t<
43 Morpheus::is_dense_vector_format_container_v<Vector> &&
44 Morpheus::has_custom_backend_v<ExecSpace> &&
45 Morpheus::has_serial_execution_space_v<ExecSpace> &&
46 Morpheus::has_access_v<ExecSpace, Vector>>* = nullptr) {
47 using IndexType = typename Vector::index_type;
48
49 out[start] = in[start];
50 for (IndexType i = start + 1; i < start + size; i++) {
51 out[i] = out[i - 1] + in[i];
52 }
53}
54
55template <typename ExecSpace, typename Vector>
56void exclusive_scan(const Vector& in, Vector& out,
57 typename Vector::index_type size,
58 typename Vector::index_type start,
59 typename std::enable_if_t<
60 Morpheus::is_dense_vector_format_container_v<Vector> &&
61 Morpheus::has_custom_backend_v<ExecSpace> &&
62 Morpheus::has_serial_execution_space_v<ExecSpace> &&
63 Morpheus::has_access_v<ExecSpace, Vector>>* = nullptr) {
64 using IndexType = typename Vector::index_type;
65 using ValueType = typename Vector::value_type;
66
67 if (size > 0) {
68 out[start] = ValueType(0);
69 for (IndexType i = start + 1; i < start + size; i++) {
70 out[i] = out[i - 1] + in[i - 1];
71 }
72 }
73}
74
75template <typename ExecSpace, typename Vector1, typename Vector2>
76void inclusive_scan_by_key(
77 const Vector1& keys, const Vector2& in, Vector2& out,
78 typename Vector2::index_type size, typename Vector2::index_type start,
79 typename std::enable_if_t<
80 Morpheus::is_dense_vector_format_container_v<Vector1> &&
81 Morpheus::is_dense_vector_format_container_v<Vector2> &&
82 Morpheus::has_custom_backend_v<ExecSpace> &&
83 Morpheus::has_serial_execution_space_v<ExecSpace> &&
84 Morpheus::has_access_v<ExecSpace, Vector1, Vector2>>* = nullptr) {
85 using IndexType = typename Vector2::index_type;
86 using KeyType = typename Vector1::value_type;
87 using ValueType = typename Vector2::value_type;
88
89 KeyType prev_key = keys[start];
90 ValueType prev_value = in[start];
91 out[start] = in[start];
92
93 for (IndexType i = start + 1; i < start + size; i++) {
94 KeyType key = keys[i];
95
96 if (prev_key == key)
97 out[i] = prev_value = prev_value + in[i];
98 else
99 out[i] = prev_value = in[i];
100
101 prev_key = key;
102 }
103}
104
105template <typename ExecSpace, typename Vector1, typename Vector2>
106void exclusive_scan_by_key(
107 const Vector1& keys, const Vector2& in, Vector2& out,
108 typename Vector2::index_type size, typename Vector2::index_type start,
109 typename std::enable_if_t<
110 Morpheus::is_dense_vector_format_container_v<Vector1> &&
111 Morpheus::is_dense_vector_format_container_v<Vector2> &&
112 Morpheus::has_custom_backend_v<ExecSpace> &&
113 Morpheus::has_serial_execution_space_v<ExecSpace> &&
114 Morpheus::has_access_v<ExecSpace, Vector1, Vector2>>* = nullptr) {
115 using IndexType = typename Vector2::index_type;
116 using KeyType = typename Vector1::value_type;
117 using ValueType = typename Vector2::value_type;
118
119 KeyType temp_key = keys[start];
120 ValueType temp_value = in[start];
121 ValueType next = ValueType(0);
122
123 // first one is init
124 out[start] = next;
125 next = next + temp_value;
126
127 for (IndexType i = start + 1; i < start + size; i++) {
128 KeyType key = keys[i];
129
130 // use temp to permit in-place scans
131 temp_value = in[i];
132
133 if (temp_key != key) next = ValueType(0); // reset sum
134
135 out[i] = next;
136 next = next + temp_value;
137
138 temp_key = key;
139 }
140}
141
142} // namespace Impl
143} // namespace Morpheus
144
145#endif // MORPHEUS_ENABLE_SERIAL
146#endif // MORPHEUS_DENSEVECTOR_SERIAL_SCAN_IMPL_HPP
Generic Morpheus interfaces.
Definition: dummy.cpp:24