GCC Code Coverage Report


Directory: gridformat/
File: gridformat/vtk/pxml_reader.hpp
Date: 2024-11-10 16:24:00
Exec Total Coverage
Lines: 227 261 87.0%
Functions: 238 284 83.8%
Branches: 491 2163 22.7%

Line Branch Exec Source
1 // SPDX-FileCopyrightText: 2022-2023 Dennis Gläser <dennis.glaeser@iws.uni-stuttgart.de>
2 // SPDX-License-Identifier: MIT
3 /*!
4 * \file
5 * \ingroup VTK
6 * \copydoc GridFormat::VTK::PXMLReader
7 */
8 #ifndef GRIDFORMAT_VTK_PXML_READER_HPP_
9 #define GRIDFORMAT_VTK_PXML_READER_HPP_
10
11 #include <array>
12 #include <string>
13 #include <optional>
14 #include <iterator>
15 #include <filesystem>
16 #include <algorithm>
17 #include <iterator>
18 #include <utility>
19 #include <cmath>
20
21 #include <gridformat/common/ranges.hpp>
22 #include <gridformat/common/field.hpp>
23 #include <gridformat/common/md_index.hpp>
24 #include <gridformat/common/md_layout.hpp>
25 #include <gridformat/common/flat_index_mapper.hpp>
26 #include <gridformat/common/empty_field.hpp>
27 #include <gridformat/common/field_transformations.hpp>
28 #include <gridformat/common/exceptions.hpp>
29
30 #include <gridformat/grid/reader.hpp>
31 #include <gridformat/parallel/communication.hpp>
32
33 #include <gridformat/vtk/common.hpp>
34 #include <gridformat/vtk/xml.hpp>
35
36 namespace GridFormat::VTK {
37
38 /*!
39 * \ingroup VTK
40 * \brief Base class for readers of parallel vtk-xml file formats.
41 * \details Constructors of derived classes for readers of unstructured
42 * grids may expose the `merge_exceeding_pieces` option. If set
43 * to true, then parallel I/O with less ranks than pieces in the
44 * PVTK file is done such that the last rank reads in and merges
45 * all remaining pieces. Otherwise, only as many pieces as ranks
46 * are read. On the other hand, if there are more ranks than pieces,
47 * some ranks will not read in any data (i.e. the grids are empty).
48 */
49 template<std::derived_from<GridReader> PieceReader>
50 class PXMLReaderBase : public GridReader {
51 public:
52 2612 virtual ~PXMLReaderBase() = default;
53
54 1032 PXMLReaderBase(PXMLReaderBase&&) = default;
55 PXMLReaderBase(const PXMLReaderBase&) = delete;
56 1 PXMLReaderBase& operator=(PXMLReaderBase&&) = default;
57 PXMLReaderBase& operator=(const PXMLReaderBase&) = delete;
58
59 1534 PXMLReaderBase(std::string vtk_grid_type)
60 1534 : _vtk_grid_type{std::move(vtk_grid_type)}
61 1534 {}
62
63 explicit PXMLReaderBase(std::string vtk_grid_type, const NullCommunicator&)
64 : PXMLReaderBase(std::move(vtk_grid_type))
65 {}
66
67 template<Concepts::Communicator C>
68 953 explicit PXMLReaderBase(std::string vtk_grid_type,
69 const C& comm,
70 std::optional<bool> merge_exceeding_pieces = {})
71
1/2
✓ Branch 3 taken 485 times.
✗ Branch 4 not taken.
953 : PXMLReaderBase(std::move(vtk_grid_type)) {
72
1/2
✓ Branch 1 taken 485 times.
✗ Branch 2 not taken.
953 _num_ranks = Parallel::size(comm);
73
1/2
✓ Branch 1 taken 485 times.
✗ Branch 2 not taken.
953 _rank = Parallel::rank(comm);
74 953 _merge_exceeding = merge_exceeding_pieces;
75 953 }
76
77 protected:
78 enum class FieldType { point, cell };
79
80 4065 const std::vector<PieceReader>& _readers() const {
81 4065 return _piece_readers;
82 }
83
84 633 const std::string _grid_type() const {
85 633 return _vtk_grid_type;
86 }
87
88 19690 std::size_t _num_process_pieces() const {
89 19690 return _piece_readers.size();
90 }
91
92 633 std::optional<bool> _merge_exceeding_pieces_option() const {
93 633 return _merge_exceeding;
94 }
95
96 1022 XMLReaderHelper _read_pvtk_file(const std::string& filename, typename GridReader::FieldNames& fields) {
97 1022 _filename = filename;
98 1022 auto helper = XMLReaderHelper::make_from(filename, _vtk_grid_type);
99
2/4
✓ Branch 1 taken 520 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 520 times.
✗ Branch 5 not taken.
1018 _num_pieces_in_file = Ranges::size(_pieces_paths(helper));
100
1/2
✓ Branch 1 taken 520 times.
✗ Branch 2 not taken.
1018 _read_pieces(helper);
101
2/2
✓ Branch 1 taken 519 times.
✓ Branch 2 taken 1 times.
1018 if (_piece_readers.size() > 0) {
102
3/6
✓ Branch 1 taken 519 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 519 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 519 times.
✗ Branch 9 not taken.
1017 std::ranges::copy(point_field_names(_piece_readers.front()), std::back_inserter(fields.point_fields));
103
3/6
✓ Branch 1 taken 519 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 519 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 519 times.
✗ Branch 9 not taken.
1017 std::ranges::copy(cell_field_names(_piece_readers.front()), std::back_inserter(fields.cell_fields));
104
3/6
✓ Branch 1 taken 519 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 519 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 519 times.
✗ Branch 9 not taken.
1017 std::ranges::copy(meta_data_field_names(_piece_readers.front()), std::back_inserter(fields.meta_data_fields));
105 }
106
107
4/8
✓ Branch 1 taken 520 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 520 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 520 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 520 times.
1050 if (std::ranges::any_of(_piece_readers | std::views::drop(1), [&] (const auto& reader) {
108
10/20
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 6 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 6 times.
✗ Branch 13 not taken.
✓ Branch 17 taken 6 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 6 times.
✗ Branch 21 not taken.
✓ Branch 25 taken 8 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 8 times.
✗ Branch 29 not taken.
✓ Branch 33 taken 6 times.
✗ Branch 34 not taken.
✓ Branch 36 taken 6 times.
✗ Branch 37 not taken.
39 return !std::ranges::equal(point_field_names(reader), fields.point_fields);
109 }))
110 throw IOError("All pieces must define the same point fields");
111
4/8
✓ Branch 1 taken 520 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 520 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 520 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 520 times.
1050 if (std::ranges::any_of(_piece_readers | std::views::drop(1), [&] (const auto& reader) {
112
10/20
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 6 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 6 times.
✗ Branch 13 not taken.
✓ Branch 17 taken 6 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 6 times.
✗ Branch 21 not taken.
✓ Branch 25 taken 8 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 8 times.
✗ Branch 29 not taken.
✓ Branch 33 taken 6 times.
✗ Branch 34 not taken.
✓ Branch 36 taken 6 times.
✗ Branch 37 not taken.
39 return !std::ranges::equal(cell_field_names(reader), fields.cell_fields);
113 }))
114 throw IOError("All pieces must define the same cell fields");
115 1018 return helper;
116 }
117
118 16 void _close_pvtk_file() {
119 16 _filename.reset();
120 16 _piece_readers.clear();
121 16 _num_pieces_in_file = 0;
122 16 }
123
124 private:
125 389 void _open(const std::string& filename, typename GridReader::FieldNames& fields) override {
126
2/2
✓ Branch 1 taken 199 times.
✓ Branch 2 taken 2 times.
389 _read_pvtk_file(filename, fields);
127 385 }
128
129 8 void _close() override {
130 8 _close_pvtk_file();
131 8 }
132
133 1922 std::size_t _number_of_cells() const override {
134
2/4
✓ Branch 1 taken 973 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 973 times.
✗ Branch 5 not taken.
2876 auto num_cells_view = _piece_readers | std::views::transform([] (const auto& reader) {
135 984 return reader.number_of_cells();
136 });
137
3/6
✓ Branch 1 taken 973 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 973 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 973 times.
✗ Branch 8 not taken.
1922 return std::accumulate(
138 std::ranges::begin(num_cells_view),
139 std::ranges::end(num_cells_view),
140 std::size_t{0}
141 3844 );
142 }
143
144 87 std::size_t _number_of_pieces() const override {
145 87 return _num_pieces_in_file;
146 }
147
148 16 bool _is_sequence() const override {
149 16 return false;
150 }
151
152 333 FieldPtr _meta_data_field(std::string_view name) const override {
153 333 return _piece_readers.front().meta_data_field(name);
154 }
155
156 527 FieldPtr _points() const override {
157
1/2
✓ Branch 1 taken 274 times.
✗ Branch 2 not taken.
1340 return _merge([] (const PieceReader& reader) { return reader.points(); }, FieldType::point);
158 }
159
160 3606 FieldPtr _cell_field(std::string_view name) const override {
161
1/2
✓ Branch 1 taken 1866 times.
✗ Branch 2 not taken.
9270 return _merge([&] (const PieceReader& reader) { return reader.cell_field(name); }, FieldType::cell);
162 }
163
164 3638 FieldPtr _point_field(std::string_view name) const override {
165
1/2
✓ Branch 1 taken 1882 times.
✗ Branch 2 not taken.
9350 return _merge([&] (const PieceReader& reader) { return reader.point_field(name); }, FieldType::point);
166 }
167
168 template<std::invocable<const PieceReader&> FieldGetter>
169 requires(std::same_as<std::invoke_result_t<FieldGetter, const PieceReader&>, FieldPtr>)
170 8044 FieldPtr _merge(const FieldGetter& get_field, FieldType type) const {
171
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4022 times.
8044 if (_num_process_pieces() == 0)
172 return make_field_ptr(EmptyField{float64});
173
2/2
✓ Branch 1 taken 3639 times.
✓ Branch 2 taken 383 times.
8044 if (_num_process_pieces() == 1)
174
1/2
✓ Branch 2 taken 3639 times.
✗ Branch 3 not taken.
7278 return get_field(_piece_readers.front());
175
176 766 std::vector<FieldPtr> field_pieces;
177
2/4
✓ Branch 1 taken 383 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 383 times.
✗ Branch 5 not taken.
1532 std::ranges::copy(
178 766 _piece_readers
179
2/4
✓ Branch 1 taken 383 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 383 times.
✗ Branch 5 not taken.
1545 | std::views::transform([&] (const PieceReader& reader) { return get_field(reader); }),
180 std::back_inserter(field_pieces)
181 );
182
1/2
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
766 return _merge_field_pieces(std::move(field_pieces), type);
183 766 }
184
185 virtual FieldPtr _merge_field_pieces(std::vector<FieldPtr>&&, FieldType) const = 0;
186
187 2986 std::ranges::range auto _pieces_paths(const XMLReaderHelper& helper) const {
188
1/2
✓ Branch 2 taken 1524 times.
✗ Branch 3 not taken.
2986 return children(helper.get(_vtk_grid_type))
189
2/4
✓ Branch 1 taken 1524 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1524 times.
✗ Branch 5 not taken.
13209 | std::views::filter([&] (const XMLElement& e) { return e.name() == "Piece"; })
190
4/8
✓ Branch 1 taken 1524 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1524 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 28 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 28 times.
✗ Branch 12 not taken.
10074 | std::views::transform([&] (const XMLElement& p) { return _get_piece_path(p.get_attribute("Source")); });
191 }
192
193 1088 std::filesystem::path _get_piece_path(const std::string& piece_filename) const {
194
1/2
✓ Branch 1 taken 558 times.
✗ Branch 2 not taken.
1088 std::filesystem::path piece_path{piece_filename};
195
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 558 times.
1088 if (piece_path.is_absolute())
196 return piece_path;
197
5/10
✓ Branch 1 taken 558 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 558 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 558 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 558 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 558 times.
✗ Branch 14 not taken.
1088 return std::filesystem::path{_filename.value()}.parent_path() / piece_filename;
198 1088 }
199
200 1018 void _read_pieces(const XMLReaderHelper& helper) {
201
2/2
✓ Branch 1 taken 483 times.
✓ Branch 2 taken 37 times.
1018 if (_num_ranks)
202 949 _read_parallel_piece(helper);
203 else
204
2/4
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
197 std::ranges::for_each(_pieces_paths(helper), [&] (const std::filesystem::path& path) {
205
20/40
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 23 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 23 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 23 times.
✗ Branch 11 not taken.
✓ Branch 17 taken 12 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 12 times.
✗ Branch 21 not taken.
✓ Branch 23 taken 12 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 12 times.
✗ Branch 27 not taken.
✓ Branch 33 taken 12 times.
✗ Branch 34 not taken.
✓ Branch 36 taken 12 times.
✗ Branch 37 not taken.
✓ Branch 39 taken 12 times.
✗ Branch 40 not taken.
✓ Branch 42 taken 12 times.
✗ Branch 43 not taken.
✓ Branch 49 taken 16 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 16 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 16 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 16 times.
✗ Branch 59 not taken.
✓ Branch 65 taken 12 times.
✗ Branch 66 not taken.
✓ Branch 68 taken 12 times.
✗ Branch 69 not taken.
✓ Branch 71 taken 12 times.
✗ Branch 72 not taken.
✓ Branch 74 taken 12 times.
✗ Branch 75 not taken.
75 _piece_readers.emplace_back(PieceReader{}).open(path);
206 });
207 1018 }
208
209 949 void _read_parallel_piece(const XMLReaderHelper& helper) {
210
2/4
✓ Branch 1 taken 483 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 483 times.
✗ Branch 5 not taken.
949 const auto num_pieces = Ranges::size(_pieces_paths(helper));
211
8/10
✓ Branch 1 taken 483 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 479 times.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 3 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 482 times.
949 if (num_pieces < _num_ranks.value() && _rank.value() == 0)
212
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 this->_log_warning(
213 "PVTK file defines less pieces than there are ranks. The grids on some ranks will be empty."
214 );
215
5/12
✓ Branch 1 taken 483 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 481 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 483 times.
949 if (num_pieces > _num_ranks.value() && !_merge_exceeding.has_value() && _rank.value() == 0)
216 this->_log_warning(
217 "PVTK file defines more pieces than used ranks. Will only read the first "
218 + std::to_string(_num_ranks.value()) + " pieces"
219 );
220
221
2/4
✓ Branch 1 taken 483 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 483 times.
✗ Branch 5 not taken.
949 const bool is_last_rank = _rank.value() == _num_ranks.value() - 1;
222
4/4
✓ Branch 0 taken 240 times.
✓ Branch 1 taken 243 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 239 times.
949 const bool merge_final_pieces = is_last_rank && _merge_exceeding.value_or(false);
223
5/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 482 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
949 const std::size_t my_num_pieces = merge_final_pieces ? Ranges::size(_pieces_paths(helper)) - _rank.value() : 1;
224
225
1/2
✓ Branch 1 taken 483 times.
✗ Branch 2 not taken.
949 std::ranges::for_each(
226
1/2
✓ Branch 1 taken 483 times.
✗ Branch 2 not taken.
949 _pieces_paths(helper)
227
3/6
✓ Branch 1 taken 483 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 483 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 483 times.
✗ Branch 8 not taken.
1898 | std::views::drop(_rank.value())
228
2/4
✓ Branch 1 taken 483 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 483 times.
✗ Branch 5 not taken.
1898 | std::views::take(my_num_pieces),
229 966 [&] (const std::filesystem::path& path) {
230
20/40
✓ Branch 1 taken 109 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 109 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 109 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 109 times.
✗ Branch 11 not taken.
✓ Branch 17 taken 82 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 82 times.
✗ Branch 21 not taken.
✓ Branch 23 taken 82 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 82 times.
✗ Branch 27 not taken.
✓ Branch 33 taken 80 times.
✗ Branch 34 not taken.
✓ Branch 36 taken 80 times.
✗ Branch 37 not taken.
✓ Branch 39 taken 80 times.
✗ Branch 40 not taken.
✓ Branch 42 taken 80 times.
✗ Branch 43 not taken.
✓ Branch 49 taken 82 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 82 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 82 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 82 times.
✗ Branch 59 not taken.
✓ Branch 65 taken 130 times.
✗ Branch 66 not taken.
✓ Branch 68 taken 130 times.
✗ Branch 69 not taken.
✓ Branch 71 taken 130 times.
✗ Branch 72 not taken.
✓ Branch 74 taken 130 times.
✗ Branch 75 not taken.
483 _piece_readers.emplace_back(PieceReader{}).open(path);
231 }
232 );
233 949 }
234
235 std::string _vtk_grid_type;
236
237 std::optional<unsigned int> _num_ranks;
238 std::optional<unsigned int> _rank;
239 std::optional<bool> _merge_exceeding;
240
241 std::optional<std::string> _filename;
242 std::vector<PieceReader> _piece_readers;
243 std::size_t _num_pieces_in_file = 0;
244 };
245
246
247 /*!
248 * \ingroup VTK
249 * \brief Base class for readers of parallel vtk-xml file formats for unstructured grids.
250 * \copydetails PXMLReaderBase
251 */
252 template<std::derived_from<GridReader> PieceReader>
253 class PXMLUnstructuredGridReader : public PXMLReaderBase<PieceReader> {
254 using ParentType = PXMLReaderBase<PieceReader>;
255 public:
256 using ParentType::ParentType;
257
258 private:
259 756 std::size_t _number_of_points() const override {
260
2/4
✓ Branch 1 taken 398 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 398 times.
✗ Branch 6 not taken.
1118 auto num_points_view = this->_readers() | std::views::transform([] (const auto& reader) {
261 412 return reader.number_of_points();
262 });
263
3/6
✓ Branch 1 taken 398 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 398 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 398 times.
✗ Branch 8 not taken.
756 return std::accumulate(
264 std::ranges::begin(num_points_view),
265 std::ranges::end(num_points_view),
266 std::size_t{0}
267 1512 );
268 }
269
270 473 void _visit_cells(const typename GridReader::CellVisitor& visitor) const override {
271 473 std::size_t offset = 0;
272
1/2
✓ Branch 2 taken 243 times.
✗ Branch 3 not taken.
937 std::ranges::for_each(this->_readers(), [&] (const PieceReader& reader) {
273
2/4
✓ Branch 2 taken 132 times.
✗ Branch 3 not taken.
✓ Branch 8 taken 116 times.
✗ Branch 9 not taken.
10568 reader.visit_cells([&] (CellType ct, std::vector<std::size_t> corners) {
274 25816 std::ranges::for_each(corners, [&] (auto& value) { value += offset; });
275 5176 visitor(ct, corners);
276 });
277 248 offset += reader.number_of_points();
278 });
279 473 }
280
281 283 FieldPtr _merge_field_pieces(std::vector<FieldPtr>&& pieces, ParentType::FieldType) const override {
282
2/4
✓ Branch 2 taken 161 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 161 times.
✗ Branch 6 not taken.
283 return make_field_ptr(MergedField{std::move(pieces)});
283 }
284 };
285
286
287 /*!
288 * \ingroup VTK
289 * \brief Base class for readers of parallel vtk-xml file formats for structured grids.
290 * \copydetails PXMLReaderBase
291 * \note This implementation does not support overlapping partitions
292 */
293 template<std::derived_from<GridReader> PieceReader>
294 class PXMLStructuredGridReader : public PXMLReaderBase<PieceReader> {
295 using ParentType = PXMLReaderBase<PieceReader>;
296 public:
297 using ParentType::ParentType;
298
299 protected:
300 struct StructuredGridSpecs {
301 std::array<std::size_t, 6> extents;
302 std::optional<std::array<double, 3>> spacing; // for image grids
303 std::optional<std::array<double, 3>> origin; // for image grids
304 std::array<double, 9> direction{ // for image grids
305 1., 0., 0., 0., 1., 0., 0., 0., 1.
306 };
307 };
308
309 453 const StructuredGridSpecs& _specs() const {
310
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 261 times.
453 if (!_grid_specs.has_value())
311 throw InvalidState("No data has been read");
312 453 return _grid_specs.value();
313 }
314
315 private:
316 633 void _open(const std::string& filename, typename GridReader::FieldNames& names) override {
317
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 321 times.
633 if (this->_merge_exceeding_pieces_option().value_or(false))
318 throw IOError("Parallel I/O of structured vtk files does not support the 'merge_exceeding_pieces' option");
319
320
1/2
✓ Branch 1 taken 321 times.
✗ Branch 2 not taken.
633 auto helper = ParentType::_read_pvtk_file(filename, names);
321
2/4
✓ Branch 1 taken 321 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 321 times.
✗ Branch 6 not taken.
633 const XMLElement& vtk_grid = helper.get(this->_grid_type());
322
2/4
✓ Branch 2 taken 321 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 321 times.
633 if (vtk_grid.get_attribute_or(std::size_t{0}, "GhostLevel") > 0)
323 throw IOError("GhostLevel > 0 not yet supported for parallel I/O of structured vtk files.");
324
325 633 StructuredGridSpecs& specs = _grid_specs.emplace();
326
2/4
✓ Branch 2 taken 321 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 321 times.
✗ Branch 6 not taken.
633 specs.extents = Ranges::array_from_string<std::size_t, 6>(vtk_grid.get_attribute("WholeExtent"));
327
4/8
✓ Branch 1 taken 321 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 321 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 321 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 321 times.
633 if (specs.extents[0] != 0 || specs.extents[2] != 0 || specs.extents[4] != 0)
328 throw ValueError("'WholeExtent' is expected to have no offset (e.g. have the shape 0 X 0 Y 0 Z)");
329
3/4
✓ Branch 2 taken 321 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 139 times.
✓ Branch 5 taken 182 times.
633 if (vtk_grid.has_attribute("Origin"))
330
2/4
✓ Branch 2 taken 139 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 139 times.
✗ Branch 6 not taken.
275 specs.origin = Ranges::array_from_string<double, 3>(vtk_grid.get_attribute("Origin"));
331
3/4
✓ Branch 2 taken 321 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 139 times.
✓ Branch 5 taken 182 times.
633 if (vtk_grid.has_attribute("Spacing"))
332
2/4
✓ Branch 2 taken 139 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 139 times.
✗ Branch 6 not taken.
275 specs.spacing = Ranges::array_from_string<double, 3>(vtk_grid.get_attribute("Spacing"));
333
3/4
✓ Branch 2 taken 321 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 139 times.
✓ Branch 5 taken 182 times.
633 if (vtk_grid.has_attribute("Direction"))
334
2/4
✓ Branch 2 taken 139 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 139 times.
✗ Branch 6 not taken.
275 specs.direction = Ranges::array_from_string<double, 9>(vtk_grid.get_attribute("Direction"));
335 633 }
336
337 8 void _close() override {
338 8 ParentType::_close_pvtk_file();
339 8 _grid_specs.reset();
340 8 }
341
342 3 typename GridReader::Vector _origin() const override {
343
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if (!_specs().origin.has_value())
344 throw ValueError("PVTK file does not define the origin for '" + this->_grid_type() + "'");
345
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (this->_num_process_pieces() == 1) {
346 const auto& specs = _specs();
347 return CommonDetail::compute_piece_origin(
348 specs.origin.value(),
349 _spacing(),
350 this->_readers().at(0).location().lower_left,
351 specs.direction
352 );
353 } else { // use global origin
354 3 return _specs().origin.value();
355 }
356 }
357
358 3 typename GridReader::Vector _spacing() const override {
359
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if (!_specs().spacing.has_value())
360 throw ValueError("PVTK file does not define the spacing for '" + this->_grid_type() + "'");
361 3 return _specs().spacing.value();
362 }
363
364 typename GridReader::Vector _basis_vector(unsigned int i) const override {
365 const auto& direction = _specs().direction;
366 return {direction.at(i), direction.at(i+3), direction.at(i+6)};
367 }
368
369 typename GridReader::PieceLocation _location() const override {
370 typename GridReader::PieceLocation result;
371
372 if (this->_num_process_pieces() == 1) {
373 result = this->_readers().at(0).location();
374 } else { // use "WholeExtent"
375 const auto& specs = _specs();
376 result.lower_left = {specs.extents[0], specs.extents[2], specs.extents[4]};
377 result.upper_right = {specs.extents[1], specs.extents[3], specs.extents[5]};
378 }
379
380 return result;
381 }
382
383 1667 std::size_t _number_of_points() const override {
384
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 847 times.
1667 if (this->_num_process_pieces() == 0)
385 return 0;
386
2/2
✓ Branch 1 taken 832 times.
✓ Branch 2 taken 15 times.
1667 if (this->_num_process_pieces() == 1)
387 1646 return this->_readers().at(0).number_of_points();
388
2/4
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
21 return CommonDetail::number_of_entities(_whole_point_extents());
389 }
390
391 775 void _visit_cells(const typename GridReader::CellVisitor& visitor) const override {
392
2/2
✓ Branch 1 taken 386 times.
✓ Branch 2 taken 6 times.
775 if (this->_num_process_pieces() == 1)
393 766 this->_readers().at(0).visit_cells(visitor);
394 else
395 9 CommonDetail::visit_structured_cells(visitor, _specs().extents);
396 775 }
397
398 405 FieldPtr _merge_field_pieces(std::vector<FieldPtr>&& pieces, ParentType::FieldType type) const override {
399
3/4
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 108 times.
✓ Branch 3 taken 114 times.
✗ Branch 4 not taken.
495 auto whole_grid_extents = type == ParentType::FieldType::point ? _whole_point_extents() : [&] () {
400 108 auto result = _specs().extents;
401 // avoid zeroes s.t. the index mappers map properly
402 108 result[1] = std::max(result[1], std::size_t{1});
403 108 result[3] = std::max(result[3], std::size_t{1});
404 108 result[5] = std::max(result[5], std::size_t{1});
405 108 return result;
406
1/2
✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
198 } ();
407
1/2
✓ Branch 1 taken 222 times.
✗ Branch 2 not taken.
405 auto num_entities = CommonDetail::number_of_entities(whole_grid_extents);
408
2/4
✓ Branch 1 taken 222 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 222 times.
✗ Branch 6 not taken.
405 auto precision = pieces.at(0)->precision();
409
1/2
✓ Branch 1 taken 222 times.
✗ Branch 2 not taken.
588 MDLayout whole_field_layout = [&] () {
410
6/12
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 100 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 61 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 61 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 61 times.
✗ Branch 16 not taken.
✓ Branch 19 taken 61 times.
✗ Branch 20 not taken.
222 const auto first_layout = pieces.at(0)->layout();
411
3/6
✓ Branch 3 taken 100 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 61 times.
✗ Branch 9 not taken.
✓ Branch 13 taken 61 times.
✗ Branch 14 not taken.
222 std::vector<std::size_t> dims(first_layout.begin(), first_layout.end());
412
3/6
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 61 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 61 times.
✗ Branch 8 not taken.
222 dims.at(0) = num_entities;
413
3/6
✓ Branch 2 taken 100 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 61 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 61 times.
✗ Branch 11 not taken.
444 return MDLayout{std::move(dims)};
414 222 } ();
415
1/2
✓ Branch 1 taken 222 times.
✗ Branch 2 not taken.
405 _check_fields_compatibility(pieces, whole_field_layout, precision);
416
417 405 std::vector<MDLayout> pieces_layouts;
418 405 std::vector<MDIndex> pieces_offsets;
419
1/2
✓ Branch 2 taken 222 times.
✗ Branch 3 not taken.
849 std::ranges::for_each(this->_readers(), [&] (const PieceReader& reader) {
420
9/18
✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 200 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 200 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 122 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 122 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 122 times.
✗ Branch 20 not taken.
✓ Branch 25 taken 122 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 122 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 122 times.
✗ Branch 32 not taken.
444 pieces_layouts.push_back(MDLayout{reader.extents()});
421
9/18
✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 200 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 200 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 122 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 122 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 122 times.
✗ Branch 19 not taken.
✓ Branch 23 taken 122 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 122 times.
✗ Branch 27 not taken.
✓ Branch 29 taken 122 times.
✗ Branch 30 not taken.
444 pieces_offsets.push_back(MDIndex{reader.location().lower_left});
422
6/6
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 96 times.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 60 times.
✓ Branch 4 taken 62 times.
✓ Branch 5 taken 60 times.
444 if (type == ParentType::FieldType::point)
423 786 std::ranges::for_each(pieces_layouts.back(), [] (auto& o) { o += 1; });
424 else
425 864 std::ranges::for_each(pieces_layouts.back(), [] (auto& o) { o = std::max(o, std::size_t{1}); });
426 });
427
428
1/2
✓ Branch 1 taken 222 times.
✗ Branch 2 not taken.
810 return make_field_ptr(LazyField{
429 int{}, // dummy source
430 whole_field_layout,
431 precision,
432
2/10
✓ Branch 1 taken 222 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 222 times.
✗ Branch 8 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
2208 [
433 405 _whole_ex=std::move(whole_grid_extents), _prec=precision, _field_layout=whole_field_layout,
434 1215 _pieces=std::move(pieces), _offsets=std::move(pieces_offsets), _piece_layouts=std::move(pieces_layouts)
435 ] (const int&) {
436
3/6
✓ Branch 1 taken 136 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 61 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 61 times.
✗ Branch 8 not taken.
258 const auto num_entities = _field_layout.extent(0);
437
12/18
✓ Branch 1 taken 136 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 92 times.
✓ Branch 4 taken 44 times.
✓ Branch 6 taken 92 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 61 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 41 times.
✓ Branch 12 taken 20 times.
✓ Branch 14 taken 41 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 61 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 41 times.
✓ Branch 20 taken 20 times.
✓ Branch 22 taken 41 times.
✗ Branch 23 not taken.
258 const auto num_comps = _field_layout.dimension() > 1 ? _field_layout.number_of_entries(1) : 1;
438
3/6
✓ Branch 4 taken 136 times.
✗ Branch 5 not taken.
✓ Branch 10 taken 61 times.
✗ Branch 11 not taken.
✓ Branch 16 taken 61 times.
✗ Branch 17 not taken.
258 const FlatIndexMapper global_mapper{std::array{_whole_ex[1], _whole_ex[3], _whole_ex[5]}};
439 591 return _prec.visit([&] <typename T> (const Precision<T>& prec) {
440
7/66
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✓ Branch 28 taken 70 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 36 times.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✓ Branch 58 taken 31 times.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✓ Branch 88 taken 31 times.
✗ Branch 89 not taken.
✓ Branch 91 taken 30 times.
✗ Branch 92 not taken.
✓ Branch 94 taken 30 times.
✗ Branch 95 not taken.
✓ Branch 97 taken 30 times.
✗ Branch 98 not taken.
258 Serialization result(num_entities*num_comps*sizeof(T));
441
7/66
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✓ Branch 28 taken 70 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 36 times.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✓ Branch 58 taken 31 times.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✓ Branch 88 taken 31 times.
✗ Branch 89 not taken.
✓ Branch 91 taken 30 times.
✗ Branch 92 not taken.
✓ Branch 94 taken 30 times.
✗ Branch 95 not taken.
✓ Branch 97 taken 30 times.
✗ Branch 98 not taken.
258 auto result_span = result.as_span_of(prec);
442
443
14/66
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✓ Branch 66 taken 140 times.
✓ Branch 67 taken 70 times.
✓ Branch 73 taken 72 times.
✓ Branch 74 taken 36 times.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 108 not taken.
✗ Branch 109 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✗ Branch 129 not taken.
✗ Branch 130 not taken.
✓ Branch 136 taken 62 times.
✓ Branch 137 taken 31 times.
✗ Branch 143 not taken.
✗ Branch 144 not taken.
✗ Branch 150 not taken.
✗ Branch 151 not taken.
✗ Branch 157 not taken.
✗ Branch 158 not taken.
✗ Branch 164 not taken.
✗ Branch 165 not taken.
✗ Branch 171 not taken.
✗ Branch 172 not taken.
✗ Branch 178 not taken.
✗ Branch 179 not taken.
✗ Branch 185 not taken.
✗ Branch 186 not taken.
✗ Branch 192 not taken.
✗ Branch 193 not taken.
✗ Branch 199 not taken.
✗ Branch 200 not taken.
✓ Branch 206 taken 62 times.
✓ Branch 207 taken 31 times.
✓ Branch 213 taken 60 times.
✓ Branch 214 taken 30 times.
✓ Branch 220 taken 60 times.
✓ Branch 221 taken 30 times.
✓ Branch 227 taken 60 times.
✓ Branch 228 taken 30 times.
774 for (unsigned int i = 0; i < _pieces.size(); ++i) {
444
14/132
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✓ Branch 64 taken 140 times.
✗ Branch 65 not taken.
✓ Branch 68 taken 140 times.
✗ Branch 69 not taken.
✓ Branch 71 taken 72 times.
✗ Branch 72 not taken.
✓ Branch 75 taken 72 times.
✗ Branch 76 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 92 not taken.
✗ Branch 93 not taken.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✗ Branch 99 not taken.
✗ Branch 100 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✗ Branch 117 not taken.
✗ Branch 118 not taken.
✗ Branch 120 not taken.
✗ Branch 121 not taken.
✗ Branch 124 not taken.
✗ Branch 125 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 131 not taken.
✗ Branch 132 not taken.
✓ Branch 134 taken 62 times.
✗ Branch 135 not taken.
✓ Branch 138 taken 62 times.
✗ Branch 139 not taken.
✗ Branch 141 not taken.
✗ Branch 142 not taken.
✗ Branch 145 not taken.
✗ Branch 146 not taken.
✗ Branch 148 not taken.
✗ Branch 149 not taken.
✗ Branch 152 not taken.
✗ Branch 153 not taken.
✗ Branch 155 not taken.
✗ Branch 156 not taken.
✗ Branch 159 not taken.
✗ Branch 160 not taken.
✗ Branch 162 not taken.
✗ Branch 163 not taken.
✗ Branch 166 not taken.
✗ Branch 167 not taken.
✗ Branch 169 not taken.
✗ Branch 170 not taken.
✗ Branch 173 not taken.
✗ Branch 174 not taken.
✗ Branch 176 not taken.
✗ Branch 177 not taken.
✗ Branch 180 not taken.
✗ Branch 181 not taken.
✗ Branch 183 not taken.
✗ Branch 184 not taken.
✗ Branch 187 not taken.
✗ Branch 188 not taken.
✗ Branch 190 not taken.
✗ Branch 191 not taken.
✗ Branch 194 not taken.
✗ Branch 195 not taken.
✗ Branch 197 not taken.
✗ Branch 198 not taken.
✗ Branch 201 not taken.
✗ Branch 202 not taken.
✓ Branch 204 taken 62 times.
✗ Branch 205 not taken.
✓ Branch 208 taken 62 times.
✗ Branch 209 not taken.
✓ Branch 211 taken 60 times.
✗ Branch 212 not taken.
✓ Branch 215 taken 60 times.
✗ Branch 216 not taken.
✓ Branch 218 taken 60 times.
✗ Branch 219 not taken.
✓ Branch 222 taken 60 times.
✗ Branch 223 not taken.
✓ Branch 225 taken 60 times.
✗ Branch 226 not taken.
✓ Branch 229 taken 60 times.
✗ Branch 230 not taken.
516 auto piece_serialization = _pieces.at(i)->serialized();
445
7/66
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✓ Branch 28 taken 140 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 72 times.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✓ Branch 58 taken 62 times.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✓ Branch 88 taken 62 times.
✗ Branch 89 not taken.
✓ Branch 91 taken 60 times.
✗ Branch 92 not taken.
✓ Branch 94 taken 60 times.
✗ Branch 95 not taken.
✓ Branch 97 taken 60 times.
✗ Branch 98 not taken.
516 auto piece_span = piece_serialization.as_span_of(prec);
446
447 516 std::size_t piece_offset = 0;
448
14/132
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✓ Branch 55 taken 140 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 140 times.
✗ Branch 59 not taken.
✓ Branch 61 taken 72 times.
✗ Branch 62 not taken.
✓ Branch 64 taken 72 times.
✗ Branch 65 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✓ Branch 115 taken 62 times.
✗ Branch 116 not taken.
✓ Branch 118 taken 62 times.
✗ Branch 119 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 124 not taken.
✗ Branch 125 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 130 not taken.
✗ Branch 131 not taken.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✗ Branch 139 not taken.
✗ Branch 140 not taken.
✗ Branch 142 not taken.
✗ Branch 143 not taken.
✗ Branch 145 not taken.
✗ Branch 146 not taken.
✗ Branch 148 not taken.
✗ Branch 149 not taken.
✗ Branch 151 not taken.
✗ Branch 152 not taken.
✗ Branch 154 not taken.
✗ Branch 155 not taken.
✗ Branch 157 not taken.
✗ Branch 158 not taken.
✗ Branch 160 not taken.
✗ Branch 161 not taken.
✗ Branch 163 not taken.
✗ Branch 164 not taken.
✗ Branch 166 not taken.
✗ Branch 167 not taken.
✗ Branch 169 not taken.
✗ Branch 170 not taken.
✗ Branch 172 not taken.
✗ Branch 173 not taken.
✓ Branch 175 taken 62 times.
✗ Branch 176 not taken.
✓ Branch 178 taken 62 times.
✗ Branch 179 not taken.
✓ Branch 181 taken 60 times.
✗ Branch 182 not taken.
✓ Branch 184 taken 60 times.
✗ Branch 185 not taken.
✓ Branch 187 taken 60 times.
✗ Branch 188 not taken.
✓ Branch 190 taken 60 times.
✗ Branch 191 not taken.
✓ Branch 193 taken 60 times.
✗ Branch 194 not taken.
✓ Branch 196 taken 60 times.
✗ Branch 197 not taken.
516 const auto local_to_global_offset = _offsets.at(i);
449
77/660
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✗ Branch 99 not taken.
✗ Branch 100 not taken.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 125 not taken.
✗ Branch 126 not taken.
✗ Branch 128 not taken.
✗ Branch 129 not taken.
✗ Branch 131 not taken.
✗ Branch 132 not taken.
✗ Branch 134 not taken.
✗ Branch 135 not taken.
✗ Branch 137 not taken.
✗ Branch 138 not taken.
✗ Branch 140 not taken.
✗ Branch 141 not taken.
✗ Branch 142 not taken.
✗ Branch 143 not taken.
✗ Branch 153 not taken.
✗ Branch 154 not taken.
✗ Branch 156 not taken.
✗ Branch 157 not taken.
✗ Branch 159 not taken.
✗ Branch 160 not taken.
✗ Branch 163 not taken.
✗ Branch 164 not taken.
✗ Branch 166 not taken.
✗ Branch 167 not taken.
✗ Branch 169 not taken.
✗ Branch 170 not taken.
✗ Branch 172 not taken.
✗ Branch 173 not taken.
✗ Branch 175 not taken.
✗ Branch 176 not taken.
✗ Branch 178 not taken.
✗ Branch 179 not taken.
✗ Branch 180 not taken.
✗ Branch 181 not taken.
✗ Branch 191 not taken.
✗ Branch 192 not taken.
✗ Branch 194 not taken.
✗ Branch 195 not taken.
✗ Branch 197 not taken.
✗ Branch 198 not taken.
✗ Branch 201 not taken.
✗ Branch 202 not taken.
✗ Branch 204 not taken.
✗ Branch 205 not taken.
✗ Branch 207 not taken.
✗ Branch 208 not taken.
✗ Branch 210 not taken.
✗ Branch 211 not taken.
✗ Branch 213 not taken.
✗ Branch 214 not taken.
✗ Branch 216 not taken.
✗ Branch 217 not taken.
✗ Branch 218 not taken.
✗ Branch 219 not taken.
✗ Branch 229 not taken.
✗ Branch 230 not taken.
✗ Branch 232 not taken.
✗ Branch 233 not taken.
✗ Branch 235 not taken.
✗ Branch 236 not taken.
✗ Branch 239 not taken.
✗ Branch 240 not taken.
✗ Branch 242 not taken.
✗ Branch 243 not taken.
✗ Branch 245 not taken.
✗ Branch 246 not taken.
✗ Branch 248 not taken.
✗ Branch 249 not taken.
✗ Branch 251 not taken.
✗ Branch 252 not taken.
✗ Branch 254 not taken.
✗ Branch 255 not taken.
✗ Branch 256 not taken.
✗ Branch 257 not taken.
✗ Branch 267 not taken.
✗ Branch 268 not taken.
✗ Branch 270 not taken.
✗ Branch 271 not taken.
✗ Branch 273 not taken.
✗ Branch 274 not taken.
✗ Branch 277 not taken.
✗ Branch 278 not taken.
✗ Branch 280 not taken.
✗ Branch 281 not taken.
✗ Branch 283 not taken.
✗ Branch 284 not taken.
✗ Branch 286 not taken.
✗ Branch 287 not taken.
✗ Branch 289 not taken.
✗ Branch 290 not taken.
✗ Branch 292 not taken.
✗ Branch 293 not taken.
✗ Branch 294 not taken.
✗ Branch 295 not taken.
✗ Branch 305 not taken.
✗ Branch 306 not taken.
✗ Branch 308 not taken.
✗ Branch 309 not taken.
✗ Branch 311 not taken.
✗ Branch 312 not taken.
✗ Branch 315 not taken.
✗ Branch 316 not taken.
✗ Branch 318 not taken.
✗ Branch 319 not taken.
✗ Branch 321 not taken.
✗ Branch 322 not taken.
✗ Branch 324 not taken.
✗ Branch 325 not taken.
✗ Branch 327 not taken.
✗ Branch 328 not taken.
✗ Branch 330 not taken.
✗ Branch 331 not taken.
✗ Branch 332 not taken.
✗ Branch 333 not taken.
✓ Branch 343 taken 140 times.
✗ Branch 344 not taken.
✓ Branch 346 taken 140 times.
✗ Branch 347 not taken.
✓ Branch 349 taken 140 times.
✗ Branch 350 not taken.
✓ Branch 353 taken 140 times.
✗ Branch 354 not taken.
✓ Branch 356 taken 140 times.
✗ Branch 357 not taken.
✓ Branch 359 taken 3540 times.
✗ Branch 360 not taken.
✓ Branch 362 taken 3540 times.
✗ Branch 363 not taken.
✓ Branch 365 taken 3540 times.
✗ Branch 366 not taken.
✓ Branch 368 taken 3680 times.
✗ Branch 369 not taken.
✓ Branch 370 taken 3540 times.
✓ Branch 371 taken 140 times.
✓ Branch 381 taken 72 times.
✗ Branch 382 not taken.
✓ Branch 384 taken 72 times.
✗ Branch 385 not taken.
✓ Branch 387 taken 72 times.
✗ Branch 388 not taken.
✓ Branch 391 taken 72 times.
✗ Branch 392 not taken.
✓ Branch 394 taken 72 times.
✗ Branch 395 not taken.
✓ Branch 397 taken 1800 times.
✗ Branch 398 not taken.
✓ Branch 400 taken 1800 times.
✗ Branch 401 not taken.
✓ Branch 403 taken 1800 times.
✗ Branch 404 not taken.
✓ Branch 406 taken 1872 times.
✗ Branch 407 not taken.
✓ Branch 408 taken 1800 times.
✓ Branch 409 taken 72 times.
✗ Branch 419 not taken.
✗ Branch 420 not taken.
✗ Branch 422 not taken.
✗ Branch 423 not taken.
✗ Branch 425 not taken.
✗ Branch 426 not taken.
✗ Branch 429 not taken.
✗ Branch 430 not taken.
✗ Branch 432 not taken.
✗ Branch 433 not taken.
✗ Branch 435 not taken.
✗ Branch 436 not taken.
✗ Branch 438 not taken.
✗ Branch 439 not taken.
✗ Branch 441 not taken.
✗ Branch 442 not taken.
✗ Branch 444 not taken.
✗ Branch 445 not taken.
✗ Branch 446 not taken.
✗ Branch 447 not taken.
✗ Branch 457 not taken.
✗ Branch 458 not taken.
✗ Branch 460 not taken.
✗ Branch 461 not taken.
✗ Branch 463 not taken.
✗ Branch 464 not taken.
✗ Branch 467 not taken.
✗ Branch 468 not taken.
✗ Branch 470 not taken.
✗ Branch 471 not taken.
✗ Branch 473 not taken.
✗ Branch 474 not taken.
✗ Branch 476 not taken.
✗ Branch 477 not taken.
✗ Branch 479 not taken.
✗ Branch 480 not taken.
✗ Branch 482 not taken.
✗ Branch 483 not taken.
✗ Branch 484 not taken.
✗ Branch 485 not taken.
✗ Branch 495 not taken.
✗ Branch 496 not taken.
✗ Branch 498 not taken.
✗ Branch 499 not taken.
✗ Branch 501 not taken.
✗ Branch 502 not taken.
✗ Branch 505 not taken.
✗ Branch 506 not taken.
✗ Branch 508 not taken.
✗ Branch 509 not taken.
✗ Branch 511 not taken.
✗ Branch 512 not taken.
✗ Branch 514 not taken.
✗ Branch 515 not taken.
✗ Branch 517 not taken.
✗ Branch 518 not taken.
✗ Branch 520 not taken.
✗ Branch 521 not taken.
✗ Branch 522 not taken.
✗ Branch 523 not taken.
✗ Branch 533 not taken.
✗ Branch 534 not taken.
✗ Branch 536 not taken.
✗ Branch 537 not taken.
✗ Branch 539 not taken.
✗ Branch 540 not taken.
✗ Branch 543 not taken.
✗ Branch 544 not taken.
✗ Branch 546 not taken.
✗ Branch 547 not taken.
✗ Branch 549 not taken.
✗ Branch 550 not taken.
✗ Branch 552 not taken.
✗ Branch 553 not taken.
✗ Branch 555 not taken.
✗ Branch 556 not taken.
✗ Branch 558 not taken.
✗ Branch 559 not taken.
✗ Branch 560 not taken.
✗ Branch 561 not taken.
✗ Branch 571 not taken.
✗ Branch 572 not taken.
✗ Branch 574 not taken.
✗ Branch 575 not taken.
✗ Branch 577 not taken.
✗ Branch 578 not taken.
✗ Branch 581 not taken.
✗ Branch 582 not taken.
✗ Branch 584 not taken.
✗ Branch 585 not taken.
✗ Branch 587 not taken.
✗ Branch 588 not taken.
✗ Branch 590 not taken.
✗ Branch 591 not taken.
✗ Branch 593 not taken.
✗ Branch 594 not taken.
✗ Branch 596 not taken.
✗ Branch 597 not taken.
✗ Branch 598 not taken.
✗ Branch 599 not taken.
✗ Branch 609 not taken.
✗ Branch 610 not taken.
✗ Branch 612 not taken.
✗ Branch 613 not taken.
✗ Branch 615 not taken.
✗ Branch 616 not taken.
✗ Branch 619 not taken.
✗ Branch 620 not taken.
✗ Branch 622 not taken.
✗ Branch 623 not taken.
✗ Branch 625 not taken.
✗ Branch 626 not taken.
✗ Branch 628 not taken.
✗ Branch 629 not taken.
✗ Branch 631 not taken.
✗ Branch 632 not taken.
✗ Branch 634 not taken.
✗ Branch 635 not taken.
✗ Branch 636 not taken.
✗ Branch 637 not taken.
✗ Branch 647 not taken.
✗ Branch 648 not taken.
✗ Branch 650 not taken.
✗ Branch 651 not taken.
✗ Branch 653 not taken.
✗ Branch 654 not taken.
✗ Branch 657 not taken.
✗ Branch 658 not taken.
✗ Branch 660 not taken.
✗ Branch 661 not taken.
✗ Branch 663 not taken.
✗ Branch 664 not taken.
✗ Branch 666 not taken.
✗ Branch 667 not taken.
✗ Branch 669 not taken.
✗ Branch 670 not taken.
✗ Branch 672 not taken.
✗ Branch 673 not taken.
✗ Branch 674 not taken.
✗ Branch 675 not taken.
✗ Branch 685 not taken.
✗ Branch 686 not taken.
✗ Branch 688 not taken.
✗ Branch 689 not taken.
✗ Branch 691 not taken.
✗ Branch 692 not taken.
✗ Branch 695 not taken.
✗ Branch 696 not taken.
✗ Branch 698 not taken.
✗ Branch 699 not taken.
✗ Branch 701 not taken.
✗ Branch 702 not taken.
✗ Branch 704 not taken.
✗ Branch 705 not taken.
✗ Branch 707 not taken.
✗ Branch 708 not taken.
✗ Branch 710 not taken.
✗ Branch 711 not taken.
✗ Branch 712 not taken.
✗ Branch 713 not taken.
✓ Branch 723 taken 62 times.
✗ Branch 724 not taken.
✓ Branch 726 taken 62 times.
✗ Branch 727 not taken.
✓ Branch 729 taken 62 times.
✗ Branch 730 not taken.
✓ Branch 733 taken 62 times.
✗ Branch 734 not taken.
✓ Branch 736 taken 62 times.
✗ Branch 737 not taken.
✓ Branch 739 taken 1560 times.
✗ Branch 740 not taken.
✓ Branch 742 taken 1560 times.
✗ Branch 743 not taken.
✓ Branch 745 taken 1560 times.
✗ Branch 746 not taken.
✓ Branch 748 taken 1622 times.
✗ Branch 749 not taken.
✓ Branch 750 taken 1560 times.
✓ Branch 751 taken 62 times.
✗ Branch 761 not taken.
✗ Branch 762 not taken.
✗ Branch 764 not taken.
✗ Branch 765 not taken.
✗ Branch 767 not taken.
✗ Branch 768 not taken.
✗ Branch 771 not taken.
✗ Branch 772 not taken.
✗ Branch 774 not taken.
✗ Branch 775 not taken.
✗ Branch 777 not taken.
✗ Branch 778 not taken.
✗ Branch 780 not taken.
✗ Branch 781 not taken.
✗ Branch 783 not taken.
✗ Branch 784 not taken.
✗ Branch 786 not taken.
✗ Branch 787 not taken.
✗ Branch 788 not taken.
✗ Branch 789 not taken.
✗ Branch 799 not taken.
✗ Branch 800 not taken.
✗ Branch 802 not taken.
✗ Branch 803 not taken.
✗ Branch 805 not taken.
✗ Branch 806 not taken.
✗ Branch 809 not taken.
✗ Branch 810 not taken.
✗ Branch 812 not taken.
✗ Branch 813 not taken.
✗ Branch 815 not taken.
✗ Branch 816 not taken.
✗ Branch 818 not taken.
✗ Branch 819 not taken.
✗ Branch 821 not taken.
✗ Branch 822 not taken.
✗ Branch 824 not taken.
✗ Branch 825 not taken.
✗ Branch 826 not taken.
✗ Branch 827 not taken.
✗ Branch 837 not taken.
✗ Branch 838 not taken.
✗ Branch 840 not taken.
✗ Branch 841 not taken.
✗ Branch 843 not taken.
✗ Branch 844 not taken.
✗ Branch 847 not taken.
✗ Branch 848 not taken.
✗ Branch 850 not taken.
✗ Branch 851 not taken.
✗ Branch 853 not taken.
✗ Branch 854 not taken.
✗ Branch 856 not taken.
✗ Branch 857 not taken.
✗ Branch 859 not taken.
✗ Branch 860 not taken.
✗ Branch 862 not taken.
✗ Branch 863 not taken.
✗ Branch 864 not taken.
✗ Branch 865 not taken.
✗ Branch 875 not taken.
✗ Branch 876 not taken.
✗ Branch 878 not taken.
✗ Branch 879 not taken.
✗ Branch 881 not taken.
✗ Branch 882 not taken.
✗ Branch 885 not taken.
✗ Branch 886 not taken.
✗ Branch 888 not taken.
✗ Branch 889 not taken.
✗ Branch 891 not taken.
✗ Branch 892 not taken.
✗ Branch 894 not taken.
✗ Branch 895 not taken.
✗ Branch 897 not taken.
✗ Branch 898 not taken.
✗ Branch 900 not taken.
✗ Branch 901 not taken.
✗ Branch 902 not taken.
✗ Branch 903 not taken.
✗ Branch 913 not taken.
✗ Branch 914 not taken.
✗ Branch 916 not taken.
✗ Branch 917 not taken.
✗ Branch 919 not taken.
✗ Branch 920 not taken.
✗ Branch 923 not taken.
✗ Branch 924 not taken.
✗ Branch 926 not taken.
✗ Branch 927 not taken.
✗ Branch 929 not taken.
✗ Branch 930 not taken.
✗ Branch 932 not taken.
✗ Branch 933 not taken.
✗ Branch 935 not taken.
✗ Branch 936 not taken.
✗ Branch 938 not taken.
✗ Branch 939 not taken.
✗ Branch 940 not taken.
✗ Branch 941 not taken.
✗ Branch 951 not taken.
✗ Branch 952 not taken.
✗ Branch 954 not taken.
✗ Branch 955 not taken.
✗ Branch 957 not taken.
✗ Branch 958 not taken.
✗ Branch 961 not taken.
✗ Branch 962 not taken.
✗ Branch 964 not taken.
✗ Branch 965 not taken.
✗ Branch 967 not taken.
✗ Branch 968 not taken.
✗ Branch 970 not taken.
✗ Branch 971 not taken.
✗ Branch 973 not taken.
✗ Branch 974 not taken.
✗ Branch 976 not taken.
✗ Branch 977 not taken.
✗ Branch 978 not taken.
✗ Branch 979 not taken.
✗ Branch 989 not taken.
✗ Branch 990 not taken.
✗ Branch 992 not taken.
✗ Branch 993 not taken.
✗ Branch 995 not taken.
✗ Branch 996 not taken.
✗ Branch 999 not taken.
✗ Branch 1000 not taken.
✗ Branch 1002 not taken.
✗ Branch 1003 not taken.
✗ Branch 1005 not taken.
✗ Branch 1006 not taken.
✗ Branch 1008 not taken.
✗ Branch 1009 not taken.
✗ Branch 1011 not taken.
✗ Branch 1012 not taken.
✗ Branch 1014 not taken.
✗ Branch 1015 not taken.
✗ Branch 1016 not taken.
✗ Branch 1017 not taken.
✗ Branch 1027 not taken.
✗ Branch 1028 not taken.
✗ Branch 1030 not taken.
✗ Branch 1031 not taken.
✗ Branch 1033 not taken.
✗ Branch 1034 not taken.
✗ Branch 1037 not taken.
✗ Branch 1038 not taken.
✗ Branch 1040 not taken.
✗ Branch 1041 not taken.
✗ Branch 1043 not taken.
✗ Branch 1044 not taken.
✗ Branch 1046 not taken.
✗ Branch 1047 not taken.
✗ Branch 1049 not taken.
✗ Branch 1050 not taken.
✗ Branch 1052 not taken.
✗ Branch 1053 not taken.
✗ Branch 1054 not taken.
✗ Branch 1055 not taken.
✗ Branch 1065 not taken.
✗ Branch 1066 not taken.
✗ Branch 1068 not taken.
✗ Branch 1069 not taken.
✗ Branch 1071 not taken.
✗ Branch 1072 not taken.
✗ Branch 1075 not taken.
✗ Branch 1076 not taken.
✗ Branch 1078 not taken.
✗ Branch 1079 not taken.
✗ Branch 1081 not taken.
✗ Branch 1082 not taken.
✗ Branch 1084 not taken.
✗ Branch 1085 not taken.
✗ Branch 1087 not taken.
✗ Branch 1088 not taken.
✗ Branch 1090 not taken.
✗ Branch 1091 not taken.
✗ Branch 1092 not taken.
✗ Branch 1093 not taken.
✓ Branch 1103 taken 62 times.
✗ Branch 1104 not taken.
✓ Branch 1106 taken 62 times.
✗ Branch 1107 not taken.
✓ Branch 1109 taken 62 times.
✗ Branch 1110 not taken.
✓ Branch 1113 taken 62 times.
✗ Branch 1114 not taken.
✓ Branch 1116 taken 62 times.
✗ Branch 1117 not taken.
✓ Branch 1119 taken 1560 times.
✗ Branch 1120 not taken.
✓ Branch 1122 taken 1560 times.
✗ Branch 1123 not taken.
✓ Branch 1125 taken 1560 times.
✗ Branch 1126 not taken.
✓ Branch 1128 taken 1622 times.
✗ Branch 1129 not taken.
✓ Branch 1130 taken 1560 times.
✓ Branch 1131 taken 62 times.
✓ Branch 1141 taken 60 times.
✗ Branch 1142 not taken.
✓ Branch 1144 taken 60 times.
✗ Branch 1145 not taken.
✓ Branch 1147 taken 60 times.
✗ Branch 1148 not taken.
✓ Branch 1151 taken 60 times.
✗ Branch 1152 not taken.
✓ Branch 1154 taken 60 times.
✗ Branch 1155 not taken.
✓ Branch 1157 taken 1500 times.
✗ Branch 1158 not taken.
✓ Branch 1160 taken 1500 times.
✗ Branch 1161 not taken.
✓ Branch 1163 taken 1500 times.
✗ Branch 1164 not taken.
✓ Branch 1166 taken 1560 times.
✗ Branch 1167 not taken.
✓ Branch 1168 taken 1500 times.
✓ Branch 1169 taken 60 times.
✓ Branch 1179 taken 60 times.
✗ Branch 1180 not taken.
✓ Branch 1182 taken 60 times.
✗ Branch 1183 not taken.
✓ Branch 1185 taken 60 times.
✗ Branch 1186 not taken.
✓ Branch 1189 taken 60 times.
✗ Branch 1190 not taken.
✓ Branch 1192 taken 60 times.
✗ Branch 1193 not taken.
✓ Branch 1195 taken 1500 times.
✗ Branch 1196 not taken.
✓ Branch 1198 taken 1500 times.
✗ Branch 1199 not taken.
✓ Branch 1201 taken 1500 times.
✗ Branch 1202 not taken.
✓ Branch 1204 taken 1560 times.
✗ Branch 1205 not taken.
✓ Branch 1206 taken 1500 times.
✓ Branch 1207 taken 60 times.
✓ Branch 1217 taken 60 times.
✗ Branch 1218 not taken.
✓ Branch 1220 taken 60 times.
✗ Branch 1221 not taken.
✓ Branch 1223 taken 60 times.
✗ Branch 1224 not taken.
✓ Branch 1227 taken 60 times.
✗ Branch 1228 not taken.
✓ Branch 1230 taken 60 times.
✗ Branch 1231 not taken.
✓ Branch 1233 taken 1500 times.
✗ Branch 1234 not taken.
✓ Branch 1236 taken 1500 times.
✗ Branch 1237 not taken.
✓ Branch 1239 taken 1500 times.
✗ Branch 1240 not taken.
✓ Branch 1242 taken 1560 times.
✗ Branch 1243 not taken.
✓ Branch 1244 taken 1500 times.
✓ Branch 1245 taken 60 times.
26436 for (auto piece_index : MDIndexRange{_piece_layouts.at(i)}) {
450
7/66
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✓ Branch 28 taken 3540 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 1800 times.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✓ Branch 58 taken 1560 times.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✓ Branch 88 taken 1560 times.
✗ Branch 89 not taken.
✓ Branch 91 taken 1500 times.
✗ Branch 92 not taken.
✓ Branch 94 taken 1500 times.
✗ Branch 95 not taken.
✓ Branch 97 taken 1500 times.
✗ Branch 98 not taken.
12960 piece_index += local_to_global_offset;
451
7/66
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✓ Branch 28 taken 3540 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 1800 times.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✓ Branch 58 taken 1560 times.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✓ Branch 88 taken 1560 times.
✗ Branch 89 not taken.
✓ Branch 91 taken 1500 times.
✗ Branch 92 not taken.
✓ Branch 94 taken 1500 times.
✗ Branch 95 not taken.
✓ Branch 97 taken 1500 times.
✗ Branch 98 not taken.
12960 const auto global_offset = global_mapper.map(piece_index)*num_comps;
452
7/66
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 3540 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 1800 times.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 77 not taken.
✓ Branch 78 taken 1560 times.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 105 not taken.
✗ Branch 106 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✗ Branch 117 not taken.
✓ Branch 118 taken 1560 times.
✗ Branch 121 not taken.
✓ Branch 122 taken 1500 times.
✗ Branch 125 not taken.
✓ Branch 126 taken 1500 times.
✗ Branch 129 not taken.
✓ Branch 130 taken 1500 times.
12960 assert(global_offset + num_comps <= result_span.size());
453
7/66
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 3540 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 1800 times.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 77 not taken.
✓ Branch 78 taken 1560 times.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 105 not taken.
✗ Branch 106 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✗ Branch 117 not taken.
✓ Branch 118 taken 1560 times.
✗ Branch 121 not taken.
✓ Branch 122 taken 1500 times.
✗ Branch 125 not taken.
✓ Branch 126 taken 1500 times.
✗ Branch 129 not taken.
✓ Branch 130 taken 1500 times.
12960 assert(piece_offset + num_comps <= piece_span.size());
454 std::copy_n(
455
7/49
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 22 taken 3540 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 1800 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✓ Branch 46 taken 1560 times.
✗ Branch 47 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✓ Branch 70 taken 1560 times.
✗ Branch 71 not taken.
✓ Branch 73 taken 1500 times.
✗ Branch 74 not taken.
✓ Branch 76 taken 1500 times.
✗ Branch 77 not taken.
✓ Branch 79 taken 1500 times.
✗ Branch 80 not taken.
12960 piece_span.data() + piece_offset,
456 num_comps,
457 12960 result_span.data() + global_offset
458 );
459 12960 piece_offset += num_comps;
460 }
461 }
462 258 return result;
463
4/8
✓ Branch 12 taken 75 times.
✗ Branch 13 not taken.
✓ Branch 32 taken 61 times.
✗ Branch 33 not taken.
✓ Branch 36 taken 61 times.
✗ Branch 37 not taken.
✓ Branch 40 taken 61 times.
✗ Branch 41 not taken.
516 });
464 }
465
1/2
✓ Branch 1 taken 222 times.
✗ Branch 2 not taken.
810 });
466 405 }
467
468 405 void _check_fields_compatibility(const std::vector<FieldPtr>& pieces,
469 const MDLayout& whole_field_layout,
470 const DynamicPrecision& precision) const {
471 849 const auto has_compatible_layout = [&] (const FieldPtr& piece_field) {
472
3/6
✓ Branch 2 taken 200 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 122 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 122 times.
✗ Branch 11 not taken.
444 const auto piece_layout = piece_field->layout();
473
9/18
✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 200 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 200 times.
✓ Branch 9 taken 122 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 122 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 122 times.
✓ Branch 17 taken 122 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 122 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 122 times.
444 if (piece_layout.dimension() != whole_field_layout.dimension())
474 return false;
475
9/12
✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 136 times.
✓ Branch 4 taken 64 times.
✓ Branch 6 taken 122 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 82 times.
✓ Branch 9 taken 40 times.
✓ Branch 11 taken 122 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 82 times.
✓ Branch 14 taken 40 times.
444 if (whole_field_layout.dimension() > 1)
476
9/18
✓ Branch 1 taken 136 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 136 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 136 times.
✗ Branch 8 not taken.
✓ Branch 14 taken 82 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 82 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 82 times.
✗ Branch 21 not taken.
✓ Branch 27 taken 82 times.
✗ Branch 28 not taken.
✓ Branch 30 taken 82 times.
✗ Branch 31 not taken.
✓ Branch 33 taken 82 times.
✗ Branch 34 not taken.
300 return whole_field_layout.sub_layout(1) == piece_layout.sub_layout(1);
477 144 return true;
478 444 };
479
2/4
✓ Branch 1 taken 222 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 222 times.
405 if (!std::ranges::all_of(pieces, has_compatible_layout))
480 throw ValueError("Fields to be merged have incompatible layouts");
481
482 849 const auto has_compatible_precision = [&] (const FieldPtr& piece_field) {
483
3/6
✓ Branch 2 taken 200 times.
✗ Branch 3 not taken.
✓ Branch 7 taken 122 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 122 times.
✗ Branch 13 not taken.
444 return piece_field->precision() == precision;
484 };
485
2/4
✓ Branch 1 taken 222 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 222 times.
405 if (!std::ranges::all_of(pieces, has_compatible_precision))
486 throw ValueError("Fields to be merged have incompatible precisions");
487 405 }
488
489 129 std::array<std::size_t, 6> _whole_point_extents() const {
490 129 auto result = _specs().extents;
491 129 result[1] += 1;
492 129 result[3] += 1;
493 129 result[5] += 1;
494 129 return result;
495 }
496
497 std::optional<StructuredGridSpecs> _grid_specs;
498 };
499
500 } // namespace GridFormat::VTK
501
502 #endif // GRIDFORMAT_VTK_PXML_READER_HPP_
503