IOSS 2.0
Ioss_Decomposition.h
Go to the documentation of this file.
1/*
2 * Copyright(C) 1999-2025 National Technology & Engineering Solutions
3 * of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
4 * NTESS, the U.S. Government retains certain rights in this software.
5 *
6 * See packages/seacas/LICENSE for details
7 */
8#pragma once
9
10#include "ioss_export.h"
11
12#include "Ioss_CodeTypes.h"
13#include "Ioss_Map.h"
14#include "Ioss_ParallelUtils.h"
16#include <algorithm>
17#include <cassert>
18#include <map>
19#include <string>
20#include <vector>
21
22#include "Ioss_ParallelUtils.h"
23#include "Ioss_Utils.h"
24
25#if !defined(NO_PARMETIS_SUPPORT)
26#include <parmetis.h>
27#endif
28
29#if !defined(NO_ZOLTAN_SUPPORT)
30#undef MPICPP
31#include <zoltan_cpp.h>
32#endif
33
34#define DC_USE_VECTOR
35#if defined DC_USE_HOPSCOTCH
36#include <hopscotch_map.h>
37#elif defined DC_USE_ROBIN
38#include <robin_map.h>
39#endif
40
41namespace Ioss {
42 IOSS_EXPORT const Ioss::NameList &valid_decomp_methods();
43
44 class IOSS_EXPORT BlockDecompositionData
45 {
46 public:
48
49 IOSS_NODISCARD const std::string &name() const { return name_; }
50 IOSS_NODISCARD int zone() const { return zone_; }
51 IOSS_NODISCARD int section() const { return section_; }
52 IOSS_NODISCARD int64_t id() const { return id_; }
53 IOSS_NODISCARD size_t file_count() const { return fileCount; }
54 IOSS_NODISCARD size_t ioss_count() const { return iossCount; }
55 IOSS_NODISCARD size_t global_count() const { return globalCount; }
56
57 std::string name_{};
58 int zone_{0};
59 int section_{0};
60
61 size_t fileSectionOffset{0}; // In partial read, where start
62 int64_t id_{0};
63 size_t fileCount{0};
64 size_t iossCount{0};
65 size_t globalCount{0};
66
67 size_t zoneNodeOffset{0};
68 std::string topologyType{"unknown"};
71
72 // maps from file-block data to ioss-block data
73 // The local_map.size() elements starting at localIossOffset are local.
74 // ioss[localIossOffset+i] = file[local_map[i]];
75 size_t localIossOffset{0};
76 std::vector<int> localMap;
77
78 // Maps from file-block data to export list.
79 // export[i] = file[export_map[i]
80 std::vector<int> exportMap;
81 std::vector<int> exportCount;
82 std::vector<int> exportIndex;
83
84 // Maps from import data to ioss-block data.
85 // ioss[import_map[i] = local_map[i];
86 std::vector<int> importMap;
87 std::vector<int> importCount;
88 std::vector<int> importIndex;
89 };
90
91 class IOSS_EXPORT SetDecompositionData
92 {
93 public:
97
99 {
101 MPI_Comm_free(&setComm_);
102 }
103 }
104
105 IOSS_NODISCARD const std::string &name() const { return name_; }
106 IOSS_NODISCARD const std::string &ss_name() const
107 {
108 return ss_name_.empty() ? name_ : ss_name_;
109 }
110 IOSS_NODISCARD int64_t id() const { return id_; }
111 IOSS_NODISCARD int zone() const { return zone_; }
112 IOSS_NODISCARD int section() const { return section_; }
113 IOSS_NODISCARD size_t file_count() const { return fileCount; }
114 IOSS_NODISCARD size_t ioss_count() const { return entitylist_map.size(); }
116
117 // contains global entity-list positions for all entities in this set on this processor.
118 std::vector<size_t> entitylist_map;
119 std::vector<bool> hasEntities; // T/F if this set exists on processor p
120
121 std::string name_{};
122 std::string ss_name_{};
123 int64_t id_{0};
124 int zone_{0}; // Zone of the element block that this set is on
125 int section_{0};
126 size_t fileCount{0}; // Number of nodes in nodelist for file decomposition
127 int root_{0}; // Lowest number processor that has nodes for this nodest
128 std::string topologyType{};
130
131 int distributionFactorValsPerEntity{-1}; // number of df / element or node. -1 if nonconstant.
134 0.0}; // If distributionFactorConstant == true, the constant value
136 bool distributionFactorConstant{false}; // T if all distribution factors the same value.
137 };
138
139 class IOSS_EXPORT ElementBlockBatchOffset
140 {
141 public:
142 explicit ElementBlockBatchOffset(const std::vector<BlockDecompositionData> &data) : m_data(data)
143 {
144 }
145
149
150 IOSS_NODISCARD size_t get_ioss_element_size(const std::vector<int64_t> &blockSubsetIndex) const;
151
152 IOSS_NODISCARD std::vector<size_t>
153 get_ioss_offset(const std::vector<int64_t> &blockSubsetIndex,
154 const std::vector<int> &blockComponentCount) const;
155
156 IOSS_NODISCARD std::vector<size_t>
157 get_import_offset(const std::vector<int64_t> &blockSubsetIndex,
158 const std::vector<int> &blockComponentCount) const;
159
160 IOSS_NODISCARD size_t
161 get_connectivity_ioss_offset_size(const std::vector<int64_t> &blockSubsetIndex) const;
162
163 IOSS_NODISCARD std::vector<int>
164 get_connectivity_ioss_component_count(const std::vector<int64_t> &blockSubsetIndex) const;
165
166 private:
167 const std::vector<BlockDecompositionData> &m_data;
168
169 IOSS_NODISCARD size_t get_ioss_offset_size(const std::vector<int64_t> &blockSubsetIndex,
170 const std::vector<int> &blockComponentCount) const;
171
172 IOSS_NODISCARD std::vector<size_t>
173 get_connectivity_ioss_offset(const std::vector<int64_t> &blockSubsetIndex) const;
174
175 IOSS_NODISCARD std::vector<size_t>
176 get_connectivity_import_offset(const std::vector<int64_t> &blockSubsetIndex) const;
177 };
178
179 template <typename INT> class Decomposition
180 {
181 public:
183 Decomposition(Decomposition const &) = default;
187
188 void set_block_omissions(const Ioss::NameList &omissions);
189
192 IOSS_NODISCARD size_t ioss_node_count() const { return nodeGTL.size(); }
194 {
195 return localElementMap.size() + importElementMap.size();
196 }
197 IOSS_NODISCARD size_t file_node_count() const { return m_nodeCount; }
201
203 {
204 return (m_method == "RCB" || m_method == "RIB" || m_method == "HSFC" ||
205 m_method == "GEOM_KWAY" || m_method == "KWAY_GEOM" || m_method == "METIS_SFC");
206 }
207
208 void generate_entity_distributions(size_t global_node_count, size_t global_element_count);
209
210 // T/F if node with global index node owned by this processors ioss-decomp.
211 IOSS_NODISCARD bool i_own_node(size_t global_index) const
212 {
213 // global_index is 1-based index into global list of nodes [1..global_node_count]
214 return std::binary_search(nodeGTL.begin(), nodeGTL.end(), global_index);
215 }
216
217 // T/F if element with global index elem owned by this processors ioss-decomp.
218 IOSS_NODISCARD bool i_own_elem(size_t global_index) const
219 {
220 // global_index is 1-based index into global list of elements [1..global_element_count]
221#if defined(DC_USE_VECTOR)
222 return std::binary_search(
223 elemGTL.begin(), elemGTL.end(), std::pair<INT, INT>{global_index, 0},
224 [](const std::pair<INT, INT> &lhs, const std::pair<INT, INT> &val) -> bool {
225 return lhs.first < val.first;
226 });
227#else
228 return elemGTL.find(global_index) != elemGTL.end();
229#endif
230 }
231
232 IOSS_NODISCARD size_t node_global_to_local(size_t global_index) const
233 {
234 // global_index is 1-based index into global list of nodes [1..global_node_count]
235 // return value is 1-based index into local list of nodes on this
236 // processor (ioss-decomposition)
237 // Note that for 'int', equivalence and equality are the same, so
238 // lower_bound is OK here (EffectiveSTL, Item 19)
239 typename std::vector<INT>::const_iterator I =
240 lower_bound(nodeGTL.begin(), nodeGTL.end(), global_index);
241 assert(I != nodeGTL.end());
242 return std::distance(nodeGTL.begin(), I) + 1; // Convert to 1-based index.
243 }
244
245 IOSS_NODISCARD size_t elem_global_to_local(size_t global_index) const
246 {
247 // global_index is 1-based index into global list of elements [1..global_node_count]
248 // return value is 1-based index into local list of elements on this
249 // processor (ioss-decomposition)
250#if defined(DC_USE_VECTOR)
251 auto I = lower_bound(
252 elemGTL.begin(), elemGTL.end(), global_index,
253 [](const std::pair<INT, INT> &lhs, INT val) -> bool { return lhs.first < val; });
254 assert(I != elemGTL.end() && I->first == (INT)global_index);
255#else
256 auto I = elemGTL.find(global_index);
257#endif
258 assert(I != elemGTL.end());
259 assert(I->first == (INT)global_index);
260 return I->second;
261 }
262
263 void show_progress(std::string_view message) const
264 {
265 if (m_showProgress) {
267 pu.progress(message);
268 }
269 }
270
271 // Zero out some large arrays usually not needed after decomposition
273 void decompose_model(
274#if !defined(NO_ZOLTAN_SUPPORT)
275 Zoltan &zz,
276#endif
277 std::vector<BlockDecompositionData> &element_blocks);
278
279 void simple_decompose();
281 void guided_decompose();
283
284 void calculate_element_centroids(const std::vector<double> &x, const std::vector<double> &y,
285 const std::vector<double> &z);
286
287#if !defined(NO_ZOLTAN_SUPPORT)
288 void zoltan_decompose(Zoltan &zz);
289
290 void get_local_element_list(const ZOLTAN_ID_PTR &export_global_ids, size_t export_count);
291#endif
292
293#if !defined(NO_PARMETIS_SUPPORT)
294 void metis_decompose(idx_t *pointer, idx_t *adjacency,
295 std::vector<BlockDecompositionData> &el_blocks);
296
297 void internal_metis_decompose(std::vector<BlockDecompositionData> &el_blocks,
298 idx_t *element_dist, idx_t *pointer, idx_t *adjacency,
299 idx_t *elem_partition);
300#endif
301
302 void get_node_entity_proc_data(INT *entity_proc, const Ioss::MapContainer &node_map,
303 bool do_map) const
304 {
305 show_progress(__func__);
306 size_t j = 0;
307 if (do_map) {
308 for (size_t i = 0; i < m_nodeCommMap.size(); i += 2) {
309 INT local_id = m_nodeCommMap[i];
310 entity_proc[j++] = node_map[local_id];
311 entity_proc[j++] = m_nodeCommMap[i + 1];
312 }
313 }
314 else {
315 for (size_t i = 0; i < m_nodeCommMap.size(); i += 2) {
316 entity_proc[j++] = m_nodeCommMap[i + 0];
317 entity_proc[j++] = m_nodeCommMap[i + 1];
318 }
319 }
320 }
321
322 void get_element_block_communication(std::vector<BlockDecompositionData> &el_blocks);
324 void get_local_node_list();
326
327 // The following function is used if reading all element data on a
328 // processor instead of just an element blocks worth...
329 template <typename T>
330 void communicate_element_data(T *file_data, T *ioss_data, size_t comp_count) const
331 {
332 show_progress(__func__);
333 if (m_method == "LINEAR") {
334 assert(m_importPreLocalElemIndex == 0);
335 assert(exportElementMap.size() == 0);
336 assert(importElementMap.size() == 0);
337 // For "LINEAR" decomposition method, the `file_data` is the
338 // same as `ioss_data` Transfer all local data from file_data
339 // to ioss_data...
340 auto size = localElementMap.size() * comp_count;
341 std::copy(file_data, file_data + size, ioss_data);
342 return;
343 }
344
345 // Transfer the file-decomposition based data in 'file_data' to
346 // the ioss-decomposition based data in 'ioss_data'
347 std::vector<T> export_data(exportElementMap.size() * comp_count);
348 std::vector<T> import_data(importElementMap.size() * comp_count);
349
350 if (comp_count == 1) {
351 for (size_t i = 0; i < exportElementMap.size(); i++) {
352 size_t index = exportElementMap[i] - m_elementOffset;
353 export_data[i] = file_data[index];
354 }
355
356 // Transfer all local data from file_data to ioss_data...
357 for (size_t i = 0; i < localElementMap.size(); i++) {
358 size_t index = localElementMap[i];
359 ioss_data[m_importPreLocalElemIndex + i] = file_data[index];
360 }
361
362 // Get my imported data and send my exported data...
365 show_progress("\tCommunication 1a finished");
366
367 // Copy the imported data into ioss_data...
368 // Some comes before the local data...
369 for (size_t i = 0; i < m_importPreLocalElemIndex; i++) {
370 ioss_data[i] = import_data[i];
371 }
372
373 // Some comes after the local data...
374 size_t offset = m_importPreLocalElemIndex + localElementMap.size();
375 for (size_t i = 0; i < importElementMap.size() - m_importPreLocalElemIndex; i++) {
376 ioss_data[offset + i] = import_data[m_importPreLocalElemIndex + i];
377 }
378 }
379 else {
380 for (size_t i = 0; i < exportElementMap.size(); i++) {
381 size_t index = exportElementMap[i] - m_elementOffset;
382 for (size_t j = 0; j < comp_count; j++) {
383 export_data[comp_count * i + j] = file_data[comp_count * index + j];
384 }
385 }
386
387 // Transfer all local data from file_data to ioss_data...
388 for (size_t i = 0; i < localElementMap.size(); i++) {
389 size_t index = localElementMap[i];
390 for (size_t j = 0; j < comp_count; j++) {
391 ioss_data[comp_count * (m_importPreLocalElemIndex + i) + j] =
392 file_data[comp_count * index + j];
393 }
394 }
395
396 std::vector<INT> export_count(exportElementCount.begin(), exportElementCount.end());
397 std::vector<INT> export_disp(exportElementIndex.begin(), exportElementIndex.end());
398 std::vector<INT> import_count(importElementCount.begin(), importElementCount.end());
399 std::vector<INT> import_disp(importElementIndex.begin(), importElementIndex.end());
400
401 for (int i = 0; i < m_processorCount; i++) {
402 export_count[i] *= comp_count;
403 export_disp[i] *= comp_count;
404 import_count[i] *= comp_count;
405 import_disp[i] *= comp_count;
406 }
407
408 // Get my imported data and send my exported data...
409 Ioss::MY_Alltoallv(export_data, export_count, export_disp, import_data, import_count,
410 import_disp, m_comm);
411 show_progress("\tCommunication 1b finished");
412
413 // Copy the imported data into ioss_data...
414 // Some comes before the local data...
415 for (size_t i = 0; i < m_importPreLocalElemIndex; i++) {
416 for (size_t j = 0; j < comp_count; j++) {
417 ioss_data[comp_count * i + j] = import_data[comp_count * i + j];
418 }
419 }
420
421 // Some comes after the local data...
422 size_t offset = m_importPreLocalElemIndex + localElementMap.size();
423 for (size_t i = 0; i < importElementMap.size() - m_importPreLocalElemIndex; i++) {
424 for (size_t j = 0; j < comp_count; j++) {
425 ioss_data[comp_count * (offset + i) + j] =
426 import_data[comp_count * (m_importPreLocalElemIndex + i) + j];
427 }
428 }
429 }
430 }
431
432 template <typename T>
433 void communicate_set_data(T *file_data, T *ioss_data, const SetDecompositionData &set,
434 size_t comp_count) const
435 {
436 show_progress(__func__);
437 std::vector<T> recv_data;
438
439 size_t size = set.file_count() * comp_count;
440 if (size == 0) {
441 return;
442 }
443
445 recv_data.resize(size);
446 if (m_processor == set.root_) {
447 std::copy(file_data, file_data + size, recv_data.begin());
448 }
449 // NOTE: This broadcast uses a split communicator, so possibly
450 // not all processors participating.
452 pu.broadcast(recv_data);
453 }
454 if (comp_count == 1) {
455 if (set.root_ == m_processor) {
456 for (size_t i = 0; i < set.ioss_count(); i++) {
457 size_t index = set.entitylist_map[i];
458 ioss_data[i] = file_data[index];
459 }
460 }
461 else {
462 // Receiving data from root...
463 for (size_t i = 0; i < set.ioss_count(); i++) {
464 size_t index = set.entitylist_map[i];
465 ioss_data[i] = recv_data[index];
466 }
467 }
468 }
469 else {
470 if (set.root_ == m_processor) {
471 for (size_t i = 0; i < set.ioss_count(); i++) {
472 size_t index = set.entitylist_map[i];
473 for (size_t j = 0; j < comp_count; j++) {
474 ioss_data[comp_count * i + j] = file_data[comp_count * index + j];
475 }
476 }
477 }
478 else {
479 // Receiving data from root...
480 for (size_t i = 0; i < set.ioss_count(); i++) {
481 size_t index = set.entitylist_map[i];
482 for (size_t j = 0; j < comp_count; j++) {
483 ioss_data[comp_count * i + j] = recv_data[comp_count * index + j];
484 }
485 }
486 }
487 }
488 }
489
490 template <typename T, typename U>
491 void communicate_block_data(T *file_data, U *ioss_data, const BlockDecompositionData &block,
492 size_t comp_count) const
493 {
494 show_progress(__func__);
495 if (m_method == "LINEAR") {
496 assert(block.localIossOffset == 0);
497 assert(block.exportMap.empty());
498 assert(block.importMap.empty());
499 // For "LINEAR" decomposition method, the `file_data` is the
500 // same as `ioss_data` Transfer all local data from file_data
501 // to ioss_data...
502 auto size = block.localMap.size() * comp_count;
503 std::copy(file_data, file_data + size, ioss_data);
504 return;
505 }
506
507 std::vector<U> exports;
508 exports.reserve(comp_count * block.exportMap.size());
509 std::vector<U> imports(comp_count * block.importMap.size());
510
511 if (comp_count == 1) {
512 for (int i : block.exportMap) {
513 exports.push_back(file_data[i]);
514 }
515
516 // Get my imported data and send my exported data...
517 Ioss::MY_Alltoallv(exports, block.exportCount, block.exportIndex, imports,
518 block.importCount, block.importIndex, m_comm);
519
520 // Map local and imported data to ioss_data.
521 for (size_t i = 0; i < block.localMap.size(); i++) {
522 ioss_data[i + block.localIossOffset] = file_data[block.localMap[i]];
523 }
524
525 for (size_t i = 0; i < block.importMap.size(); i++) {
526 ioss_data[block.importMap[i]] = imports[i];
527 }
528 }
529 else {
530 for (int i : block.exportMap) {
531 for (size_t j = 0; j < comp_count; j++) {
532 exports.push_back(file_data[i * comp_count + j]);
533 }
534 }
535
536 std::vector<int> export_count(block.exportCount.begin(), block.exportCount.end());
537 std::vector<int> export_disp(block.exportIndex.begin(), block.exportIndex.end());
538 std::vector<int> import_count(block.importCount.begin(), block.importCount.end());
539 std::vector<int> import_disp(block.importIndex.begin(), block.importIndex.end());
540
541 for (int i = 0; i < m_processorCount; i++) {
542 export_count[i] *= comp_count;
543 export_disp[i] *= comp_count;
544 import_count[i] *= comp_count;
545 import_disp[i] *= comp_count;
546 }
547
548 // Get my imported data and send my exported data...
549 Ioss::MY_Alltoallv(exports, export_count, export_disp, imports, import_count, import_disp,
550 m_comm);
551 show_progress("\tCommunication 1 finished");
552
553 // Map local and imported data to ioss_data.
554 for (size_t i = 0; i < block.localMap.size(); i++) {
555 for (size_t j = 0; j < comp_count; j++) {
556 ioss_data[(i + block.localIossOffset) * comp_count + j] =
557 file_data[block.localMap[i] * comp_count + j];
558 }
559 }
560
561 for (size_t i = 0; i < block.importMap.size(); i++) {
562 for (size_t j = 0; j < comp_count; j++) {
563 ioss_data[block.importMap[i] * comp_count + j] = imports[i * comp_count + j];
564 }
565 }
566 }
567 }
568
569 template <typename T, typename U>
571 T *file_data, U *ioss_data, const std::vector<BlockDecompositionData> &blocks,
572 const std::vector<int64_t> &blockSubsetIndex, const std::vector<size_t> &fileOffset,
573 const std::vector<int> &blockComponentCount) const
574 {
575 size_t export_size = 0;
576 size_t import_size = 0;
577
578 for (size_t bsi = 0; bsi < blockSubsetIndex.size(); bsi++) {
579 int64_t blk_seq = blockSubsetIndex[bsi];
580 const Ioss::BlockDecompositionData &blk = blocks[blk_seq];
581
582 size_t comp_count = blockComponentCount[bsi];
583 export_size += blk.exportMap.size() * comp_count;
584 import_size += blk.importMap.size() * comp_count;
585 }
586
587 std::vector<U> exports;
588 exports.reserve(export_size);
589
591 int nProc = util_.parallel_size();
592
593 for (int proc = 0; proc < nProc; proc++) {
594 for (size_t bsi = 0; bsi < blockSubsetIndex.size(); bsi++) {
595 int64_t blk_seq = blockSubsetIndex[bsi];
596 const Ioss::BlockDecompositionData &blk = blocks[blk_seq];
597 size_t comp_count = blockComponentCount[bsi];
598 size_t fileDataOffset = fileOffset[bsi];
599
600 for (int n = 0; n < blk.exportCount[proc]; n++) {
601 int exportIndex = blk.exportIndex[proc] + n;
602 int i = blk.exportMap[exportIndex];
603
604 for (size_t j = 0; j < comp_count; j++) {
605 size_t fileIndex = fileDataOffset + i * comp_count + j;
606 exports.push_back(file_data[fileIndex]);
607 }
608 }
609 }
610 }
611
612 std::vector<int64_t> export_count(nProc, 0);
613 std::vector<int64_t> export_disp(nProc, 0);
614 std::vector<int64_t> import_count(nProc, 0);
615 std::vector<int64_t> import_disp(nProc, 0);
616
617 for (size_t bsi = 0; bsi < blockSubsetIndex.size(); bsi++) {
618 int64_t blk_seq = blockSubsetIndex[bsi];
619 const Ioss::BlockDecompositionData &blk = blocks[blk_seq];
620 size_t comp_count = blockComponentCount[bsi];
621
622 int proc = 0;
623 for (int i : blk.exportCount) {
624 export_count[proc++] += comp_count * i;
625 }
626
627 proc = 0;
628 for (int i : blk.importCount) {
629 import_count[proc++] += comp_count * i;
630 }
631 }
632
633 std::copy(export_count.begin(), export_count.end(), export_disp.begin());
634 std::copy(import_count.begin(), import_count.end(), import_disp.begin());
635
636 Ioss::Utils::generate_index(export_disp);
637 Ioss::Utils::generate_index(import_disp);
638
639 std::vector<U> imports(import_size);
640 Ioss::MY_Alltoallv(exports, export_count, export_disp, imports, import_count, import_disp,
641 m_comm);
642 show_progress("\tCommunication 1 finished");
643
644 Ioss::ElementBlockBatchOffset batchOffset(blocks);
645 std::vector<size_t> iossOffset =
646 batchOffset.get_ioss_offset(blockSubsetIndex, blockComponentCount);
647 std::vector<size_t> importOffset =
648 batchOffset.get_import_offset(blockSubsetIndex, blockComponentCount);
649
650 // Map local and imported data to ioss_data.
651 for (size_t bsi = 0; bsi < blockSubsetIndex.size(); bsi++) {
652 int64_t blk_seq = blockSubsetIndex[bsi];
653 const Ioss::BlockDecompositionData &block = blocks[blk_seq];
654 size_t comp_count = blockComponentCount[bsi];
655
656 for (size_t i = 0; i < block.localMap.size(); i++) {
657 for (size_t j = 0; j < comp_count; j++) {
658 size_t fileIndex = fileOffset[bsi] + block.localMap[i] * comp_count + j;
659 size_t iossIndex = iossOffset[bsi] + (i + block.localIossOffset) * comp_count + j;
660 ioss_data[iossIndex] = file_data[fileIndex];
661 }
662 }
663
664 for (size_t i = 0; i < block.importMap.size(); i++) {
665 for (size_t j = 0; j < comp_count; j++) {
666 size_t importIndex = importOffset[bsi] + i * comp_count + j;
667
668 size_t dataOffset = iossOffset[bsi];
669 size_t iossIndex = dataOffset + block.importMap[i] * comp_count + j;
670
671 ioss_data[iossIndex] = imports[importIndex];
672 }
673 }
674 }
675
676 return iossOffset;
677 }
678
679 template <typename T, typename U>
681 T *file_data, U *ioss_data, const std::vector<BlockDecompositionData> &blocks,
682 const std::vector<int64_t> &blockSubsetIndex, const std::vector<size_t> &fileOffset,
683 const std::vector<int> &blockComponentCount) const
684 {
685 show_progress(__func__);
686 if (m_method == "LINEAR") {
687 // For "LINEAR" decomposition method, the `file_data` is the
688 // same as `ioss_data` Transfer all local data from file_data
689 // to ioss_data...
690 auto size = fileOffset[blockSubsetIndex.size()];
691 std::copy(file_data, file_data + size, ioss_data);
692
693 Ioss::ElementBlockBatchOffset batchOffset(blocks);
694 return batchOffset.get_ioss_offset(blockSubsetIndex, blockComponentCount);
695 ;
696 }
697
698 auto retval = do_communicate_entity_data(file_data, ioss_data, blocks, blockSubsetIndex,
699 fileOffset, blockComponentCount);
700
701 return retval;
702 }
703
704 template <typename T>
705 void communicate_node_data(T *file_data, T *ioss_data, size_t comp_count) const
706 {
707 show_progress(__func__);
708 // Transfer the file-decomposition based data in 'file_data' to
709 // the ioss-decomposition based data in 'ioss_data'
710 std::vector<T> export_data(exportNodeMap.size() * comp_count);
711 std::vector<T> import_data(importNodeMap.size() * comp_count);
712
713 if (comp_count == 1) {
714 for (size_t i = 0; i < exportNodeMap.size(); i++) {
715 size_t index = exportNodeMap[i] - m_nodeOffset;
716 assert(index < m_nodeCount);
717 export_data[i] = file_data[index];
718 }
719
720 // Transfer all local data from file_data to ioss_data...
721 for (size_t i = 0; i < localNodeMap.size(); i++) {
722 size_t index = localNodeMap[i] - m_nodeOffset;
723 assert(index < m_nodeCount);
724 ioss_data[m_importPreLocalNodeIndex + i] = file_data[index];
725 }
726
727 // Get my imported data and send my exported data...
728 Ioss::MY_Alltoallv(export_data, exportNodeCount, exportNodeIndex, import_data,
730 show_progress("\tCommunication 1a finished");
731
732 // Copy the imported data into ioss_data...
733 for (size_t i = 0; i < importNodeMap.size(); i++) {
734 size_t index = importNodeMap[i];
735 assert(index < ioss_node_count());
736 ioss_data[index] = import_data[i];
737 }
738 }
739 else { // Comp_count > 1
740 for (size_t i = 0; i < exportNodeMap.size(); i++) {
741 size_t index = exportNodeMap[i] - m_nodeOffset;
742 assert(index < m_nodeCount);
743 for (size_t j = 0; j < comp_count; j++) {
744 export_data[comp_count * i + j] = file_data[comp_count * index + j];
745 }
746 }
747
748 // Transfer all local data from file_data to ioss_data...
749 for (size_t i = 0; i < localNodeMap.size(); i++) {
750 size_t index = localNodeMap[i] - m_nodeOffset;
751 assert(index < m_nodeCount);
752 for (size_t j = 0; j < comp_count; j++) {
753 ioss_data[comp_count * (m_importPreLocalNodeIndex + i) + j] =
754 file_data[comp_count * index + j];
755 }
756 }
757
758 std::vector<INT> export_count(exportNodeCount.begin(), exportNodeCount.end());
759 std::vector<INT> export_disp(exportNodeIndex.begin(), exportNodeIndex.end());
760 std::vector<INT> import_count(importNodeCount.begin(), importNodeCount.end());
761 std::vector<INT> import_disp(importNodeIndex.begin(), importNodeIndex.end());
762
763 for (int i = 0; i < m_processorCount; i++) {
764 export_count[i] *= comp_count;
765 export_disp[i] *= comp_count;
766 import_count[i] *= comp_count;
767 import_disp[i] *= comp_count;
768 }
769
770 // Get my imported data and send my exported data...
771 Ioss::MY_Alltoallv(export_data, export_count, export_disp, import_data, import_count,
772 import_disp, m_comm);
773 show_progress("\tCommunication 1b finished");
774
775 // Copy the imported data into ioss_data...
776 for (size_t i = 0; i < importNodeMap.size(); i++) {
777 size_t index = importNodeMap[i];
778 assert(index < ioss_node_count());
779 for (size_t j = 0; j < comp_count; j++) {
780 ioss_data[comp_count * index + j] = import_data[comp_count * i + j];
781 }
782 }
783 }
784 }
785
790 std::string m_method{};
791 std::string m_decompExtra{};
792
793 // Values for the file decomposition
797 size_t m_elementCount{0};
800
802 size_t m_nodeCount{0};
803 size_t m_nodeOffset{0};
805
807 bool m_lineDecomp{false};
808 bool m_showProgress{false};
809 bool m_showHWM{false};
810
811 std::vector<int> m_elementToProc; // Used by "MAP" scheme...
812 std::vector<double> m_centroids;
813 std::vector<float> m_weights;
814 std::vector<INT> m_pointer; // Index into adjacency, processor list for each element...
815 std::vector<INT> m_adjacency; // Size is sum of element connectivity sizes
816
817 std::vector<INT> m_nodeCommMap; // node/processor pair of the
818 // nodes I communicate with. Stored node#,proc,node#,proc, ...
819
820 // The global element at index 'I' (0-based) is on block B in the
821 // file decomposition.
822 // if m_fileBlockIndex[B] <= I && m_fileBlockIndex[B+1] < I
823 std::vector<size_t> m_fileBlockIndex;
824 std::vector<int64_t> m_omittedBlocks;
825 std::vector<std::string> m_omittedBlockNames;
826
827 private:
828 // This processor "manages" the elements on the exodus mesh file from
829 // m_elementOffset to m_elementOffset+m_elementCount (0-based). This is
830 // 'file' data
831 //
832 // This processor also appears to the Ioss clients to own other
833 // element and node data based on the decomposition. This is the
834 // 'ioss' data.
835 //
836 // The indices in `localElementMap` are the elements that are
837 // common to both the 'file' data and the 'ioss' data.
838 // `localElementMap[i]` contains the location in 'file' data for
839 // the 'ioss' data at location `i+m_importPreLocalElemIndex`
840 //
841 // local_element_map[i]+m_elementOffset is the 0-based global index
842 //
843 // The indices in 'import_element_map' map the data received via
844 // mpi communication from other processors into 'ioss' data.
845 // if 'ind=import_element_map[i]', then ioss[ind] = comm_recv[i]
846 // Note that this is the reverse direction of the
847 // local_element_map mapping.
848 //
849 // The indices in 'export_element_map' are used to pull from
850 // 'file' data into the comm_send vector. if 'ind =
851 // export_element_map[i]', then 'comm_send[i] = file[ind]' for i =
852 // 0..#exported_elements
853 //
854 // local_element_map.size() + import_element_map.size() ==
855 // #ioss elements on this processor.
856 //
857 // local_element_map.size() + export_element_map.size() ==
858 // #file elements on this processor.
859 //
860 // export_element_map and import_element_map are sorted.
861 // The primary key is processor order followed by global id.
862 // The processor association is via 'export_proc_disp' and
863 // 'import_proc_disp' Both are of size '#processors+1' and
864 // the elements for processor p range from [X_proc_disp[p] to
865 // X_proc_disp[p+1])
866
867 std::vector<INT> localElementMap;
868
869 std::vector<INT> importElementMap;
870 std::vector<INT> importElementCount;
871 std::vector<INT> importElementIndex;
872
873 // The list of my `file decomp` elements that will be exported to some other rank.
874 std::vector<INT> exportElementMap;
875 // The number of elements that I will export to each other rank.
876 std::vector<INT> exportElementCount;
877 // The index into `exportElementMap` for the elements that will be exported to each rank.
878 std::vector<INT> exportElementIndex;
879
880 std::vector<INT> nodeIndex;
881
882 std::vector<INT> exportNodeMap;
883 std::vector<INT> exportNodeCount;
884 std::vector<INT> exportNodeIndex;
885
886 // Where to put each imported nodes data in the list of all data...
887 std::vector<INT> importNodeMap;
888 std::vector<INT> importNodeCount;
889 std::vector<INT> importNodeIndex;
890
891 std::vector<INT> localNodeMap;
892
893 std::vector<INT> m_elementDist;
894 std::vector<INT> m_nodeDist;
895
896 // Note that nodeGTL is a sorted vector.
897 std::vector<INT> nodeGTL; // Convert from global index to local index (1-based)
898
899#if defined DC_USE_HOPSCOTCH
900 tsl::hopscotch_pg_map<INT, INT> elemGTL; // Convert from global index to local index (1-based)
901#elif defined DC_USE_ROBIN
902 tsl::robin_pg_map<INT, INT> elemGTL; // Convert from global index to local index (1-based)
903#elif defined DC_USE_VECTOR
904 std::vector<std::pair<INT, INT>> elemGTL; // Convert from global index to local index (1-based)
905#else
906 // This is the original method that was used in IOSS prior to using hopscotch or robin map.
907 std::map<INT, INT> elemGTL; // Convert from global index to local index (1-based)
908#endif
909 };
910} // namespace Ioss
#define IOSS_NODISCARD
Definition Ioss_CodeTypes.h:56
MPI_Comm Ioss_MPI_Comm
Definition Ioss_CodeTypes.h:61
Definition Ioss_Decomposition.h:45
IOSS_NODISCARD size_t file_count() const
Definition Ioss_Decomposition.h:53
int attributeCount
Definition Ioss_Decomposition.h:70
IOSS_NODISCARD int64_t id() const
Definition Ioss_Decomposition.h:52
std::string name_
Definition Ioss_Decomposition.h:57
std::string topologyType
Definition Ioss_Decomposition.h:68
IOSS_NODISCARD int zone() const
Definition Ioss_Decomposition.h:50
IOSS_NODISCARD const std::string & name() const
Definition Ioss_Decomposition.h:49
std::vector< int > localMap
Definition Ioss_Decomposition.h:76
IOSS_NODISCARD size_t global_count() const
Definition Ioss_Decomposition.h:55
size_t iossCount
Definition Ioss_Decomposition.h:64
std::vector< int > exportCount
Definition Ioss_Decomposition.h:81
IOSS_NODISCARD size_t ioss_count() const
Definition Ioss_Decomposition.h:54
IOSS_NODISCARD int section() const
Definition Ioss_Decomposition.h:51
size_t localIossOffset
Definition Ioss_Decomposition.h:75
std::vector< int > importIndex
Definition Ioss_Decomposition.h:88
std::vector< int > importMap
Definition Ioss_Decomposition.h:86
int64_t id_
Definition Ioss_Decomposition.h:62
size_t fileSectionOffset
Definition Ioss_Decomposition.h:61
std::vector< int > exportIndex
Definition Ioss_Decomposition.h:82
size_t fileCount
Definition Ioss_Decomposition.h:63
std::vector< int > importCount
Definition Ioss_Decomposition.h:87
size_t zoneNodeOffset
Definition Ioss_Decomposition.h:67
int zone_
Definition Ioss_Decomposition.h:58
int nodesPerEntity
Definition Ioss_Decomposition.h:69
int section_
Definition Ioss_Decomposition.h:59
size_t globalCount
Definition Ioss_Decomposition.h:65
std::vector< int > exportMap
Definition Ioss_Decomposition.h:80
IOSS_NODISCARD size_t global_elem_count() const
Definition Ioss_Decomposition.h:191
void metis_decompose(idx_t *pointer, idx_t *adjacency, std::vector< BlockDecompositionData > &el_blocks)
Definition Ioss_Decomposition.C:917
std::vector< INT > localElementMap
Definition Ioss_Decomposition.h:867
std::vector< INT > importNodeCount
Definition Ioss_Decomposition.h:888
std::vector< INT > exportElementMap
Definition Ioss_Decomposition.h:874
IOSS_NODISCARD size_t elem_global_to_local(size_t global_index) const
Definition Ioss_Decomposition.h:245
std::string m_method
Definition Ioss_Decomposition.h:790
void build_global_to_local_elem_map()
Definition Ioss_Decomposition.C:1296
IOSS_NODISCARD std::vector< size_t > communicate_entity_data(T *file_data, U *ioss_data, const std::vector< BlockDecompositionData > &blocks, const std::vector< int64_t > &blockSubsetIndex, const std::vector< size_t > &fileOffset, const std::vector< int > &blockComponentCount) const
Definition Ioss_Decomposition.h:680
std::vector< INT > exportNodeMap
Definition Ioss_Decomposition.h:882
std::vector< double > m_centroids
Definition Ioss_Decomposition.h:812
void communicate_element_data(T *file_data, T *ioss_data, size_t comp_count) const
Definition Ioss_Decomposition.h:330
bool m_retainFreeNodes
Definition Ioss_Decomposition.h:806
void guided_decompose()
Definition Ioss_Decomposition.C:727
std::vector< INT > importNodeIndex
Definition Ioss_Decomposition.h:889
std::vector< INT > m_elementDist
Definition Ioss_Decomposition.h:893
std::vector< INT > exportNodeCount
Definition Ioss_Decomposition.h:883
std::vector< int > m_elementToProc
Definition Ioss_Decomposition.h:811
IOSS_NODISCARD std::vector< size_t > do_communicate_entity_data(T *file_data, U *ioss_data, const std::vector< BlockDecompositionData > &blocks, const std::vector< int64_t > &blockSubsetIndex, const std::vector< size_t > &fileOffset, const std::vector< int > &blockComponentCount) const
Definition Ioss_Decomposition.h:570
std::vector< INT > nodeGTL
Definition Ioss_Decomposition.h:897
Ioss_MPI_Comm m_comm
Definition Ioss_Decomposition.h:786
bool m_showHWM
Definition Ioss_Decomposition.h:809
IOSS_NODISCARD size_t ioss_elem_count() const
Definition Ioss_Decomposition.h:193
void internal_metis_decompose(std::vector< BlockDecompositionData > &el_blocks, idx_t *element_dist, idx_t *pointer, idx_t *adjacency, idx_t *elem_partition)
Definition Ioss_Decomposition.C:1028
std::vector< INT > m_nodeCommMap
Definition Ioss_Decomposition.h:817
std::vector< size_t > m_fileBlockIndex
Definition Ioss_Decomposition.h:823
void set_block_omissions(const Ioss::NameList &omissions)
Definition Ioss_Decomposition.C:350
size_t m_elementOffset
Definition Ioss_Decomposition.h:798
std::vector< INT > exportNodeIndex
Definition Ioss_Decomposition.h:884
void simple_node_decompose()
Definition Ioss_Decomposition.C:882
void get_element_block_communication(std::vector< BlockDecompositionData > &el_blocks)
Definition Ioss_Decomposition.C:379
void get_node_entity_proc_data(INT *entity_proc, const Ioss::MapContainer &node_map, bool do_map) const
Definition Ioss_Decomposition.h:302
std::vector< int64_t > m_omittedBlocks
Definition Ioss_Decomposition.h:824
IOSS_NODISCARD size_t ioss_node_count() const
Definition Ioss_Decomposition.h:192
int m_processor
Definition Ioss_Decomposition.h:788
void get_local_element_list(const ZOLTAN_ID_PTR &export_global_ids, size_t export_count)
Definition Ioss_Decomposition.C:1258
int m_commonNodeCount
Definition Ioss_Decomposition.h:795
IOSS_NODISCARD bool i_own_elem(size_t global_index) const
Definition Ioss_Decomposition.h:218
size_t m_nodeOffset
Definition Ioss_Decomposition.h:803
void communicate_node_data(T *file_data, T *ioss_data, size_t comp_count) const
Definition Ioss_Decomposition.h:705
Decomposition(const Ioss::PropertyManager &props, Ioss_MPI_Comm comm)
Definition Ioss_Decomposition.C:283
size_t m_globalElementCount
Definition Ioss_Decomposition.h:796
void simple_decompose()
Definition Ioss_Decomposition.C:862
void decompose_model(Zoltan &zz, std::vector< BlockDecompositionData > &element_blocks)
Definition Ioss_Decomposition.C:461
std::vector< INT > m_nodeDist
Definition Ioss_Decomposition.h:894
size_t m_importPreLocalElemIndex
Definition Ioss_Decomposition.h:799
std::vector< INT > importElementMap
Definition Ioss_Decomposition.h:869
IOSS_NODISCARD size_t node_global_to_local(size_t global_index) const
Definition Ioss_Decomposition.h:232
IOSS_NODISCARD size_t file_elem_offset() const
Definition Ioss_Decomposition.h:200
Decomposition & operator=(Decomposition const &)=default
void generate_entity_distributions(size_t global_node_count, size_t global_element_count)
Definition Ioss_Decomposition.C:365
void communicate_block_data(T *file_data, U *ioss_data, const BlockDecompositionData &block, size_t comp_count) const
Definition Ioss_Decomposition.h:491
void show_progress(std::string_view message) const
Definition Ioss_Decomposition.h:263
Decomposition(Decomposition const &)=default
IOSS_NODISCARD size_t file_node_count() const
Definition Ioss_Decomposition.h:197
std::vector< INT > m_adjacency
Definition Ioss_Decomposition.h:815
IOSS_NODISCARD bool needs_centroids() const
Definition Ioss_Decomposition.h:202
bool m_showProgress
Definition Ioss_Decomposition.h:808
void communicate_set_data(T *file_data, T *ioss_data, const SetDecompositionData &set, size_t comp_count) const
Definition Ioss_Decomposition.h:433
std::vector< INT > importElementCount
Definition Ioss_Decomposition.h:870
IOSS_NODISCARD size_t file_elem_count() const
Definition Ioss_Decomposition.h:198
Ioss::ParallelUtils m_pu
Definition Ioss_Decomposition.h:787
size_t m_importPreLocalNodeIndex
Definition Ioss_Decomposition.h:804
std::vector< INT > exportElementIndex
Definition Ioss_Decomposition.h:878
std::string m_decompExtra
Definition Ioss_Decomposition.h:791
Decomposition(Decomposition &&)=default
std::vector< INT > nodeIndex
Definition Ioss_Decomposition.h:880
size_t m_nodeCount
Definition Ioss_Decomposition.h:802
std::vector< INT > m_pointer
Definition Ioss_Decomposition.h:814
std::vector< INT > localNodeMap
Definition Ioss_Decomposition.h:891
IOSS_NODISCARD bool i_own_node(size_t global_index) const
Definition Ioss_Decomposition.h:211
std::vector< std::pair< INT, INT > > elemGTL
Definition Ioss_Decomposition.h:904
bool m_lineDecomp
Definition Ioss_Decomposition.h:807
std::vector< INT > exportElementCount
Definition Ioss_Decomposition.h:876
void zoltan_decompose(Zoltan &zz)
Definition Ioss_Decomposition.C:1124
std::vector< std::string > m_omittedBlockNames
Definition Ioss_Decomposition.h:825
IOSS_NODISCARD size_t file_node_offset() const
Definition Ioss_Decomposition.h:199
void calculate_element_centroids(const std::vector< double > &x, const std::vector< double > &y, const std::vector< double > &z)
Definition Ioss_Decomposition.C:560
Decomposition & operator=(Decomposition &&)=default
int m_processorCount
Definition Ioss_Decomposition.h:789
void get_local_node_list()
Definition Ioss_Decomposition.C:1339
size_t m_globalNodeCount
Definition Ioss_Decomposition.h:801
std::vector< float > m_weights
Definition Ioss_Decomposition.h:813
std::vector< INT > importElementIndex
Definition Ioss_Decomposition.h:871
int m_spatialDimension
Definition Ioss_Decomposition.h:794
IOSS_NODISCARD size_t global_node_count() const
Definition Ioss_Decomposition.h:190
std::vector< INT > importNodeMap
Definition Ioss_Decomposition.h:887
void get_shared_node_list()
Definition Ioss_Decomposition.C:1547
size_t m_elementCount
Definition Ioss_Decomposition.h:797
Definition Ioss_Decomposition.h:140
IOSS_NODISCARD std::vector< size_t > get_import_offset(const std::vector< int64_t > &blockSubsetIndex, const std::vector< int > &blockComponentCount) const
Definition Ioss_Decomposition.C:221
IOSS_NODISCARD std::vector< size_t > get_ioss_offset(const std::vector< int64_t > &blockSubsetIndex, const std::vector< int > &blockComponentCount) const
Definition Ioss_Decomposition.C:199
IOSS_NODISCARD size_t get_ioss_element_size(const std::vector< int64_t > &blockSubsetIndex) const
Definition Ioss_Decomposition.C:170
IOSS_NODISCARD std::vector< int > get_connectivity_ioss_component_count(const std::vector< int64_t > &blockSubsetIndex) const
Definition Ioss_Decomposition.C:243
IOSS_NODISCARD std::vector< size_t > get_connectivity_import_offset(const std::vector< int64_t > &blockSubsetIndex) const
Definition Ioss_Decomposition.C:270
const std::vector< BlockDecompositionData > & m_data
Definition Ioss_Decomposition.h:167
IOSS_NODISCARD size_t get_ioss_offset_size(const std::vector< int64_t > &blockSubsetIndex, const std::vector< int > &blockComponentCount) const
Definition Ioss_Decomposition.C:183
IOSS_NODISCARD size_t get_connectivity_ioss_offset_size(const std::vector< int64_t > &blockSubsetIndex) const
Definition Ioss_Decomposition.C:256
IOSS_NODISCARD std::vector< size_t > get_connectivity_ioss_offset(const std::vector< int64_t > &blockSubsetIndex) const
Definition Ioss_Decomposition.C:263
ElementBlockBatchOffset(const ElementBlockBatchOffset &)=delete
ElementBlockBatchOffset(ElementBlockBatchOffset &&)=delete
ElementBlockBatchOffset(const std::vector< BlockDecompositionData > &data)
Definition Ioss_Decomposition.h:142
Definition Ioss_ParallelUtils.h:32
static IOSS_NODISCARD Ioss_MPI_Comm comm_null()
Definition Ioss_ParallelUtils.h:45
void progress(std::string_view output) const
Definition Ioss_ParallelUtils.C:570
IOSS_NODISCARD int parallel_size() const
Definition Ioss_ParallelUtils.C:203
void broadcast(T &my_value, int root=0) const
A collection of Ioss::Property objects.
Definition Ioss_PropertyManager.h:36
Definition Ioss_Decomposition.h:92
IOSS_NODISCARD size_t ioss_count() const
Definition Ioss_Decomposition.h:114
IOSS_NODISCARD const std::string & ss_name() const
Definition Ioss_Decomposition.h:106
int distributionFactorValsPerEntity
Definition Ioss_Decomposition.h:131
bool distributionFactorConstant
Definition Ioss_Decomposition.h:136
IOSS_NODISCARD size_t df_count() const
Definition Ioss_Decomposition.h:115
int root_
Definition Ioss_Decomposition.h:127
IOSS_NODISCARD int section() const
Definition Ioss_Decomposition.h:112
std::string ss_name_
Definition Ioss_Decomposition.h:122
IOSS_NODISCARD int zone() const
Definition Ioss_Decomposition.h:111
IOSS_NODISCARD const std::string & name() const
Definition Ioss_Decomposition.h:105
std::vector< size_t > entitylist_map
Definition Ioss_Decomposition.h:118
double distributionFactorValue
Definition Ioss_Decomposition.h:133
size_t fileCount
Definition Ioss_Decomposition.h:126
IOSS_NODISCARD int64_t id() const
Definition Ioss_Decomposition.h:110
~SetDecompositionData()
Definition Ioss_Decomposition.h:98
IOSS_NODISCARD size_t file_count() const
Definition Ioss_Decomposition.h:113
std::vector< bool > hasEntities
Definition Ioss_Decomposition.h:119
size_t distributionFactorCount
Definition Ioss_Decomposition.h:132
size_t parentBlockIndex
Definition Ioss_Decomposition.h:129
int section_
Definition Ioss_Decomposition.h:125
int zone_
Definition Ioss_Decomposition.h:124
SetDecompositionData(SetDecompositionData &&)=default
std::string topologyType
Definition Ioss_Decomposition.h:128
std::string name_
Definition Ioss_Decomposition.h:121
SetDecompositionData(const SetDecompositionData &)=delete
int64_t id_
Definition Ioss_Decomposition.h:123
Ioss_MPI_Comm setComm_
Definition Ioss_Decomposition.h:135
static void generate_index(std::vector< T > &index)
Definition Ioss_Utils.h:183
The main namespace for the Ioss library.
Definition Ioad_DatabaseIO.C:40
int MY_Alltoallv(const std::vector< T > &sendbuf, const std::vector< int64_t > &sendcnts, const std::vector< int64_t > &senddisp, std::vector< T > &recvbuf, const std::vector< int64_t > &recvcnts, const std::vector< int64_t > &recvdisp, Ioss_MPI_Comm comm)
Definition Ioss_ParallelUtils.h:231
Ioss::NameList NameList
Definition Ioss_ChangeSetFactory.h:25
IOSS_EXPORT const Ioss::NameList & valid_decomp_methods()
Definition Ioss_Decomposition.C:140
std::vector< int64_t > MapContainer
Definition Ioss_Map.h:29
hopscotch_map< Key, T, Hash, KeyEqual, Allocator, NeighborhoodSize, StoreHash, tsl::hh::prime_growth_policy > hopscotch_pg_map
Definition hopscotch_map.h:721
robin_map< Key, T, Hash, KeyEqual, Allocator, StoreHash, tsl::rh::prime_growth_policy > robin_pg_map
Definition robin_map.h:786