NeoFOAM
WIP Prototype of a modern OpenFOAM core
Loading...
Searching...
No Matches
segmentedField.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2// SPDX-FileCopyrightText: 2023 NeoFOAM authors
3#pragma once
4
7
8namespace NeoFOAM
9{
10
23template<typename IndexType>
24IndexType segmentsFromIntervals(const Field<IndexType>& intervals, Field<IndexType>& offsets)
25{
26 IndexType finalValue = 0;
27 auto inSpan = intervals.span();
28 auto offsSpan = offsets.span();
29 NF_ASSERT_EQUAL(inSpan.size() + 1, offsSpan.size());
31 intervals.exec(),
32 {1, offsSpan.size()},
33 KOKKOS_LAMBDA(const std::size_t i, NeoFOAM::localIdx& update, const bool final) {
34 update += inSpan[i - 1];
35 if (final)
36 {
37 offsSpan[i] = update;
38 }
39 },
40 finalValue
41 );
42 return finalValue;
43}
44
50template<typename ValueType, typename IndexType = NeoFOAM::localIdx>
52{
53public:
54
58 std::span<ValueType> values;
59
63 std::span<IndexType> segments;
64
71 KOKKOS_INLINE_FUNCTION
72 Kokkos::pair<IndexType, IndexType> bounds(std::size_t segI) const
73 {
74 return Kokkos::pair<IndexType, IndexType> {segments[segI], segments[segI + 1]};
75 }
76
83 KOKKOS_INLINE_FUNCTION
84 Kokkos::pair<IndexType, IndexType> range(std::size_t segI) const
85 {
86 return Kokkos::pair<IndexType, IndexType> {
87 segments[segI], segments[segI + 1] - segments[segI]
88 };
89 }
90
98 KOKKOS_INLINE_FUNCTION std::span<ValueType> span(std::size_t segI) const
99 {
100 auto [start, length] = range(segI);
101 return values.subspan(start, length);
102 }
103
110 KOKKOS_INLINE_FUNCTION
111 IndexType operator[](std::size_t i) const { return segments[i]; }
112};
113
120template<typename ValueType, typename IndexType>
122{
123public:
124
125
133 : values_(exec, size), segments_(exec, numSegments + 1)
134 {}
135
136 /*
137 * @brief Create a segmented field from intervals.
138 * @param intervals The intervals to create the segmented field from.
139 * @note The intervals are the lengths of each segment
140 */
142 : values_(intervals.exec(), 0),
143 segments_(intervals.exec(), intervals.size() + 1, IndexType(0))
144 {
145 IndexType valueSize = segmentsFromIntervals(intervals, segments_);
146 values_ = Field<ValueType>(intervals.exec(), valueSize);
147 }
148
149
156 : values_(values), segments_(segments)
157 {
158 NF_ASSERT(values.exec() == segments.exec(), "Executors are not the same.");
159 }
160
161
166 const Executor& exec() const { return values_.exec(); }
167
172 size_t size() const { return values_.size(); }
173
178 size_t numSegments() const { return segments_.size() - 1; }
179
180
186 {
187 return SegmentedFieldView<ValueType, IndexType> {values_.span(), segments_.span()};
188 }
189
190 // ensures no return a span of a temporary object --> invalid memory access
192
197 [[nodiscard]] std::pair<std::span<ValueType>, std::span<IndexType>> spans() &
198 {
199 return {values_.span(), segments_.span()};
200 }
201
202 // ensures not to return a span of a temporary object --> invalid memory access
203 [[nodiscard]] std::pair<std::span<ValueType>, std::span<IndexType>> spans() && = delete;
204
205 const Field<ValueType>& values() const { return values_; }
206
207 const Field<IndexType>& segments() const { return segments_; }
208
209private:
210
211 Field<ValueType> values_;
212 Field<IndexType> segments_;
213};
214
215} // namespace NeoFOAM
A class to contain the data and executors for a field and define some basic operations.
Definition field.hpp:49
size_t size() const
Gets the size of the field.
Definition field.hpp:355
const Executor & exec() const
Gets the executor associated with the field.
Definition field.hpp:349
std::span< ValueType > span() &&=delete
A class representing a segment of indices.
KOKKOS_INLINE_FUNCTION IndexType operator[](std::size_t i) const
Access an element of the segments.
std::span< ValueType > values
A span with the values.
KOKKOS_INLINE_FUNCTION Kokkos::pair< IndexType, IndexType > bounds(std::size_t segI) const
Get the bounds of a segment.
KOKKOS_INLINE_FUNCTION std::span< ValueType > span(std::size_t segI) const
Get a subspan of values corresponding to a segment.
std::span< IndexType > segments
A span of indices representing the segments.
KOKKOS_INLINE_FUNCTION Kokkos::pair< IndexType, IndexType > range(std::size_t segI) const
Get the range, ie. [start,end), of a segment.
Data structure that stores a segmented fields or a vector of vectors.
const Executor & exec() const
Get the executor associated with the segmented field.
SegmentedFieldView< ValueType, IndexType > view() &
get a view of the segmented field
std::pair< std::span< ValueType >, std::span< IndexType > > spans() &
get the combined value and range spans of the segmented field
const Field< ValueType > & values() const
const Field< IndexType > & segments() const
SegmentedField(const Field< ValueType > &values, const Field< IndexType > &segments)
Constructor to create a segmentedField from values and the segments.
SegmentedFieldView< ValueType, IndexType > view() &&=delete
std::pair< std::span< ValueType >, std::span< IndexType > > spans() &&=delete
size_t numSegments() const
Get the number of segments in the segmented field.
SegmentedField(const Executor &exec, size_t size, size_t numSegments)
Create a segmented field with a given size and number of segments.
SegmentedField(const Field< IndexType > &intervals)
size_t size() const
Get the size of the segmented field.
#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:239
#define NF_ASSERT(condition, message)
Macro for asserting a condition and printing an error message if the condition is false.
Definition error.hpp:142
IndexType segmentsFromIntervals(const Field< IndexType > &intervals, Field< IndexType > &offsets)
Compute segment offsets from an input field corresponding to lengths by computing a prefix sum.
uint32_t localIdx
Definition label.hpp:14
std::variant< SerialExecutor, CPUExecutor, GPUExecutor > Executor
Definition executor.hpp:16
void parallelScan(const Executor &exec, std::pair< size_t, size_t > range, Kernel kernel)