Fenix @develop
 
Loading...
Searching...
No Matches
subset.hpp
1/*
2//@HEADER
3// ************************************************************************
4//
5//
6// _|_|_|_| _|_|_|_| _| _| _|_|_| _| _|
7// _| _| _|_| _| _| _| _|
8// _|_|_| _|_|_| _| _| _| _| _|
9// _| _| _| _|_| _| _| _|
10// _| _|_|_|_| _| _| _|_|_| _| _|
11//
12//
13//
14//
15// Copyright (C) 2016 Rutgers University and Sandia Corporation
16//
17// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
18// the U.S. Government retains certain rights in this software.
19//
20// Redistribution and use in source and binary forms, with or without
21// modification, are permitted provided that the following conditions are
22// met:
23//
24// 1. Redistributions of source code must retain the above copyright
25// notice, this list of conditions and the following disclaimer.
26//
27// 2. Redistributions in binary form must reproduce the above copyright
28// notice, this list of conditions and the following disclaimer in the
29// documentation and/or other materials provided with the distribution.
30//
31// 3. Neither the name of the Corporation nor the names of the
32// contributors may be used to endorse or promote products derived from
33// this software without specific prior written permission.
34//
35// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
36// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
39// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
40// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
41// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
42// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
43// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
44// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46//
47// Author Marc Gamell, Eric Valenzuela, Keita Teranishi, Manish Parashar,
48// Michael Heroux, and Matthew Whitlock
49//
50// Questions? Contact Keita Teranishi (knteran@sandia.gov) and
51// Marc Gamell (mgamell@cac.rutgers.edu)
52//
53// ************************************************************************
54//@HEADER
55*/
56#ifndef __FENIX_DATA_SUBSET_HPP__
57#define __FENIX_DATA_SUBSET_HPP__
58
59#include "fenix.h"
60#include "fenix_opt.hpp"
61#include "fenix/data/util/buffer.hpp"
62
63#include <utility>
64#include <set>
65#include <optional>
66#include <limits>
67#include <string>
68#include <variant>
69
70namespace fenix {
71
72namespace detail {
73
74struct DataRegionIterator;
75
76struct DataRegion {
77 static constexpr size_t MAX = std::numeric_limits<size_t>::max();
78
79 DataRegion(std::pair<size_t, size_t> b) : DataRegion(b, 0, MAX) {};
80 DataRegion(std::pair<size_t, size_t> b, size_t m_reps, size_t m_stride)
81 : start(b.first), end(
82 (b.second != MAX && b.second + 1 == b.first + m_stride)
83 ? b.second + m_reps * m_stride
84 : b.second
85 ),
86 reps(
87 (b.second == MAX || b.second + 1 == b.first + m_stride) ? 0 : m_reps
88 ),
89 stride(reps == 0 ? MAX : m_stride) {
90 fenix_assert(start <= end);
91 fenix_assert(stride != MAX || reps == 0);
92 fenix_assert(reps == 0 || start + stride > end);
93 };
94
95 //Overall range of this region.
96 std::pair<size_t, size_t> range() const;
97
98 //Count of elements contained in this region
99 size_t count() const;
100
101 bool operator==(const DataRegion& other) const;
102 bool operator!=(const DataRegion& other) const;
103
104 //Order based on start
105 bool operator<(const DataRegion& other) const;
106
107 //Return true if these regions intersect
108 bool operator&&(const DataRegion& other) const;
109
110 //Returns intersection of two regions. Not defined when both regions are
111 //strided.
112 std::set<DataRegion> operator&(const DataRegion& other) const;
113
114 //This region w/o the overlap with other
115 std::set<DataRegion> operator-(const DataRegion& other) const;
116
117 //Get a region that is a single repetition of this one's, with bounds check
118 DataRegion get_rep(size_t n) const;
119 //As above, but multiple repetitions
120 DataRegion get_reps(size_t first, size_t last) const;
121
122 //For a strided region, returns region between repetitions
123 //Undefined for an unstrided region.
124 DataRegion inverted() const;
125
126 std::optional<DataRegion> try_merge(const DataRegion& other) const;
127
128 std::string str() const;
129
130 //Inclusive region bounds.
131 size_t start, end;
132
133 //Number of times to repeat this after the first
134 size_t reps;
135
136 //Distance between starts of each repetition
137 size_t stride;
138};
139} // namespace detail
140
141namespace data::util {
142// Forward declaration
143class Serializer;
144}
145
146namespace mpixx {
147// Forward declarations
148class Datatype;
149class DatatypeRef;
150}
151
153 static constexpr size_t MAX = detail::DataRegion::MAX;
154
156
157 enum SubsetType {
158 BasicSubset,
159 PrestagedSubset,
160 };
161
162 //DataSubset(const DataSubset&) = default;
163 //DataSubset(DataSubset&&) = default;
164 //Empty
165 DataSubset() = default;
166 //[0, end]
167 explicit DataSubset(size_t end);
168 //[bounds.first, bounds.second]
169 DataSubset(std::pair<size_t, size_t> bounds);
170 //[b.first, b.second], ..., [b.first+stride*(n-1), b.second+stride*(n-1)]
171 DataSubset(std::pair<size_t, size_t> b, size_t n, size_t stride);
172 //[bounds[0].first, bounds[0].second], ...
173 DataSubset(std::vector<std::pair<size_t, size_t>> bounds);
174 //[first[0], second[0]], ... [first[n-1], second[n-1]]
175 DataSubset(int n, int* first, int* second);
176 //Merge two subsets
177 DataSubset(const DataSubset& a, const DataSubset& b);
178 //Create from serialized subset object
180 explicit DataSubset(SubsetType special_type) : type(special_type) {};
181
182 DataSubset operator+(const DataSubset& other) const;
183 DataSubset& operator+=(const DataSubset& other);
184
185 DataSubset operator+(const Fenix_Data_subset& other) const;
186 DataSubset& operator+=(const Fenix_Data_subset& other);
187
188 DataSubset operator-(const DataSubset& other) const;
189 bool operator==(const DataSubset& other) const;
190 bool operator!=(const DataSubset& other) const;
191
192 bool empty() const;
193
194 //Overall range of this subset
195 std::pair<size_t, size_t> range() const;
196 //Equivalent to range().first and range().second, possibly more performant
197 size_t start() const;
198 size_t end() const;
199
200 //Count of elements in this subset from [0, max_index]
201 //Returns 0 if max_index==end()==MAX
202 size_t count(size_t max_index) const;
203
204 //Count of elements in this subset if it were full [0, end()]
205 //Returns 0 if end()==MAX
206 size_t max_count() const;
207
208 //Serialize this subset object into buf
209 //Will resize buf to fit exactly.
210 void serialize(data::util::DataBuffer& buf) const;
211
212 //Will reset dst to fit
213 void pack_data(
214 size_t elm_size, const data::util::DataBuffer& src,
216 ) const;
217 //If dst.size()==0, will resize dst to fit
218 void unpack_data(
219 size_t elm_size, const data::util::DataBuffer& src,
221 ) const;
222
223 //Copy data using given Serializer
224 //If src_len == 0, will assume src is a large as needed. May resize dst.
225 void copy_data(const Serializer& s) const;
226
227 //Whether this subset includes the element at index idx
228 bool includes(size_t idx) const;
229 //Whether this subset includes the entire range [0, end] without gaps
230 bool includes_all(size_t end) const;
231
232 bool is_bounded() const { return empty() || end() != MAX; }
233
234 //Create MPI datatype representing this subset's memory layout
235 //base: the datatype of each element in the array
236 //Returns a committed MPI datatype (wrapped in mpixx::Datatype)
237 mpixx::Datatype to_datatype(mpixx::DatatypeRef base) const;
238
239 //Return a DataSubset consisting of bounded_regions(max_index)
240 DataSubset bounded(size_t max_index) const;
241
242 //Bound this subset in place
243 DataSubset& bound(size_t max_index);
244
245 //Return equivalent of regions & [0, max_index]
246 std::set<detail::DataRegion> bounded_regions(size_t max_index) const;
247 //As above, but regions & [start, end]
248 std::set<detail::DataRegion> bounded_regions(size_t start, size_t end) const;
249
250 std::string str() const;
251
252 //Individual data regions in this subset
253 std::set<detail::DataRegion> regions;
254
255 SubsetType type = BasicSubset;
256
257 private:
258 //merge immediately adjacent regions to simplify
259 void merge_regions();
260};
261} // namespace fenix
262#endif // __FENIX_DATA_SUBSET_HPP_
Definition buffer.hpp:68
Definition serializer.hpp:14
Definition datatype.hpp:162
Definition datatype.hpp:20
Contains all API function calls and Fenix types. This is the only header file a user should include.
Represents a data subset that can be stored/recovered.
Definition fenix.h:625
Definition subset.hpp:152
Definition subset.hpp:76