NeoN
A framework for CFD software
Loading...
Searching...
No Matches
segmentedVector.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2023 - 2026 NeoN authors
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include "NeoN/core/view.hpp"
12
13namespace NeoN
14{
15
16namespace detail
17{
18
19/* @brief Prefix-sum kernel of segmentsFromIntervals.
20 *
21 * A named functor rather than a NEON_LAMBDA: under nvcc a NEON_LAMBDA is an
22 * extended lambda whose host-side callable is registered per translation unit,
23 * and for an enclosing *function template* the registration belongs to a comdat
24 * group the linker may drop while keeping the body. The surviving copy then
25 * calls a null pointer — every segmentsFromIntervals<localIdx> call inside
26 * libNeoN segfaults (e.g. CellToFaceStencil::computeInternalStencil, the
27 * stencil CellLimitedGrad builds). A functor carries no such registration.
28 */
29template<typename IndexType>
31{
32 using value_type = IndexType;
33
36
37 KOKKOS_INLINE_FUNCTION
38 void operator()(const localIdx i, IndexType& update, const bool final) const
39 {
40 update += intervals[i];
41 if (final)
42 {
43 // offsets is a view, thus [] takes unsigned idx
44 offsets[i] = update;
45 }
46 }
47};
48
49} // namespace detail
50
63template<typename IndexType>
64IndexType segmentsFromIntervals(const Vector<IndexType>& intervals, Vector<IndexType>& offsets)
65{
66 IndexType finalValue = 0;
67 const auto inView = intervals.view();
68 // skip the first element of the offsets
69 // assumed to be zero
70 auto offsView = offsets.view().subview(1);
71 // NOTE avoid compiler warning by static_casting to localIdx since offsView
72 // is a View
73 NF_ASSERT_EQUAL(inView.size(), offsView.size());
75 intervals.exec(),
76 {0, offsView.size()},
78 finalValue
79 );
80 return finalValue;
81}
82
88template<typename ValueType, typename IndexType = NeoN::localIdx>
90{
91public:
92
97
102
109 KOKKOS_INLINE_FUNCTION
110 Kokkos::pair<IndexType, IndexType> bounds(localIdx segI) const
111 {
112 return Kokkos::pair<IndexType, IndexType> {segments[segI], segments[segI + 1]};
113 }
114
121 KOKKOS_INLINE_FUNCTION
122 Kokkos::pair<IndexType, IndexType> range(localIdx segI) const
123 {
124 return Kokkos::pair<IndexType, IndexType> {
125 segments[segI], segments[segI + 1] - segments[segI]
126 };
127 }
128
136 KOKKOS_INLINE_FUNCTION View<ValueType> view(localIdx segI) const
137 {
138 auto [start, length] = range(segI);
139 return values.subview(start, length);
140 }
141
148 KOKKOS_INLINE_FUNCTION
149 IndexType operator[](localIdx i) const { return segments[i]; }
150};
151
158template<typename ValueType, typename IndexType>
159class SegmentedVector : public SupportsCopyTo<SegmentedVector<ValueType, IndexType>>
160{
161public:
162
163
171 : values_(exec, size), segments_(exec, numSegments + 1)
172 {}
173
174 /*
175 * @brief Create a segmented vector from intervals.
176 * @param intervals The intervals to create the segmented vector from.
177 * @note The intervals are the lengths of each segment
178 */
180 : values_(intervals.exec(), 0),
181 segments_(intervals.exec(), intervals.size() + 1, IndexType(0))
182 {
183 IndexType valueSize = segmentsFromIntervals(intervals, segments_);
184 values_ = Vector<ValueType>(intervals.exec(), valueSize, ValueType(0));
185 }
186
187
194 : values_(values), segments_(segments)
195 {
196 NF_ASSERT(values.exec() == segments.exec(), "Executors are not the same.");
197 }
198
199
204 const Executor& exec() const { return values_.exec(); }
205
210 localIdx size() const { return values_.size(); }
211
216 localIdx numSegments() const { return segments_.size() - 1; }
217
219 {
221 values_.copyToExecutor(exec), segments_.copyToExecutor(exec)
222 );
223 }
224
225
231 {
232 return SegmentedVectorView<ValueType, IndexType> {values_.view(), segments_.view()};
233 }
234
235 // ensures no return a view of a temporary object --> invalid memory access
237
242 [[nodiscard]] std::pair<View<ValueType>, View<IndexType>> views() &
243 {
244 return {values_.view(), segments_.view()};
245 }
246
247
248 // ensures not to return a view of a temporary object --> invalid memory access
249 [[nodiscard]] std::pair<View<ValueType>, View<IndexType>> views() && = delete;
250
251 const Vector<ValueType>& values() const { return values_; }
252
253 const Vector<IndexType>& segments() const { return segments_; }
254
255private:
256
257 Vector<ValueType> values_;
258 Vector<IndexType> segments_;
259};
260
261} // namespace NeoN
A class representing a segment of indices.
View< IndexType > segments
A View of indices representing the segments.
KOKKOS_INLINE_FUNCTION View< ValueType > view(localIdx segI) const
Get a subview of values corresponding to a segment.
KOKKOS_INLINE_FUNCTION Kokkos::pair< IndexType, IndexType > range(localIdx segI) const
Get the range, ie. [start,end), of a segment.
KOKKOS_INLINE_FUNCTION IndexType operator[](localIdx i) const
Access an element of the segments.
View< ValueType > values
A View with the values.
KOKKOS_INLINE_FUNCTION Kokkos::pair< IndexType, IndexType > bounds(localIdx segI) const
Get the bounds of a segment.
Data structure that stores a segmented fields or a vector of vectors.
SegmentedVector(const Vector< ValueType > &values, const Vector< IndexType > &segments)
Constructor to create a segmentedVector from values and the segments.
const Vector< ValueType > & values() const
SegmentedVector(const Vector< IndexType > &intervals)
std::pair< View< ValueType >, View< IndexType > > views() &
get the combined value and range views of the segmented vector
SegmentedVector< ValueType, IndexType > copyToExecutor(Executor exec) const override
const Vector< IndexType > & segments() const
std::pair< View< ValueType >, View< IndexType > > views() &&=delete
SegmentedVectorView< ValueType, IndexType > view() &
get a view of the segmented vector
SegmentedVector(const Executor &exec, localIdx size, localIdx numSegments)
Create a segmented vector with a given size and number of segments.
localIdx numSegments() const
Get the number of segments in the segmented vector.
const Executor & exec() const
Get the executor associated with the segmented vector.
SegmentedVectorView< ValueType, IndexType > view() &&=delete
localIdx size() const
Get the size of the segmented vector.
MixinClass signaling copyTo is supported.
Definition copyTo.hpp:20
A class to contain the data and executors for a field and define some basic operations.
Definition vector.hpp:27
localIdx size() const
Gets the size of the field.
Definition vector.hpp:268
Vector< ValueType > copyToExecutor(Executor dstExec) const
Copies the data to a new field on a specific executor.
const Executor & exec() const
Gets the executor associated with the field.
Definition vector.hpp:262
View< ValueType > view() &&=delete
#define NF_ASSERT_EQUAL(a, b)
Macro for asserting that two values are equal and printing an error message if they are not.
Definition error.hpp:218
#define NF_ASSERT(condition, message)
Macro for asserting a condition and printing an error message if the condition is false.
Definition error.hpp:118
Integer types used throughout NeoN.
Definition array.hpp:18
int32_t localIdx
Definition label.hpp:50
IndexType segmentsFromIntervals(const Vector< IndexType > &intervals, Vector< IndexType > &offsets)
Compute segment offsets from an input field corresponding to lengths by computing a prefix sum.
void parallelScan(const Executor &exec, std::pair< localIdx, localIdx > range, const Kernel &kernel)
std::variant< SerialExecutor, CPUExecutor, GPUExecutor > Executor
Definition executor.hpp:20
KOKKOS_INLINE_FUNCTION void operator()(const localIdx i, IndexType &update, const bool final) const
View< const IndexType > intervals