MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
parallelio.h
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
7#ifndef PARALLELIO_H
8#define PARALLELIO_H
9
10#include <set>
11#include <sys/stat.h>
12#include <utility>
13#include <vector>
14#include "COMM/globalmpiinfo.h"
15#include "COMM/mpioverride.h"
17#include "INCLUDE/maiatypes.h"
18#include "MEMORY/scratch.h"
19#include "UTIL/debug.h"
20#include "UTIL/functions.h"
21#include "UTIL/timer.h"
22#include "config.h"
23#include "typetraits.h"
24
25namespace maia {
26namespace parallel_io {
27
28// Typedef for constants
29// Used for all constants that are used to interact with ParallelIoPNetcdf
31
32// File mode constants
34const MInt PIO_CREATE = 0;
35// File mode to create a new file. If file already exists, it is overwritten
36const MInt PIO_REPLACE = 1;
37// File mode to open an existing file for reading and writing
38const MInt PIO_APPEND = 2;
39// File mode to open an existing file for reading only
40const MInt PIO_READ = 3;
41
42// Data type constants
43// Specifies all unknown (= unsupported) data types.
45// Specifies data of type MFloat.
46const MInt PIO_FLOAT = 0;
47// Specifies data of type MInt.
48const MInt PIO_INT = 1;
49// Specifies data of type MLong.
50const MInt PIO_LONG = 2;
51// Specifies data of type MString.
52const MInt PIO_STRING = 3;
53// Specifies data of type MChar.
54const MInt PIO_UCHAR = 4;
55// Specifies data of type MUlong.
57
58} // namespace parallel_io
59} // namespace maia
60
100template <class Backend>
102 // CRTP
103 private:
104 Backend& derived() { return static_cast<Backend&>(*this); }
105 const Backend& derived() const { return static_cast<const Backend&>(*this); }
106
107 // Public types
108 public:
124
129
130 // Public member functions
131 public:
132 // Static file system-related methods
133 static MBool fileExists(const MString& name, const MPI_Comm& mpiComm);
134 static void deleteFile(const MString& name);
135 static MBool isParallelIoFile(const MString& name, const MPI_Comm& mpiComm);
136 static MString fileExt();
137
138 // Constructors & destructor; protected, so that the user can't create it
139 // directly. Only objects of the derived classes should exist
140 protected:
141 ParallelIoBase(MString fileName, MInt fileMode, const MPI_Comm& mpiComm);
143
144 // The following methods represent the interface used by the derived classes
145 public:
146 // Methods to get information about file contents
147 MBool hasDataset(const MString& name, MInt dimension);
148 MBool hasDataset(const MString& name, const MString& path);
150 MBool hasObject(const MString& path);
152 std::vector<MString> getDatasetNames(const size_type dimensions = -1);
153 std::vector<MString> getDatasetNames(const MString& path);
154 std::vector<MString> getGroupNames(const MString& path);
156 size_type getDatasetNoDims(const MString& name, const MString& path);
157 std::vector<size_type> getArrayDims(const MString& name);
158 size_type getArraySize(const MString& name, const size_type dimensionId = 0);
159 void getArraySize(const MString& name, const MString& path, size_type* datasetSize);
160 MBool hasAttribute(const MString& name, const MString& path = "");
161 maiabd_type getAttributeType(const MString& name, const MString& datasetName = "");
162
163 // Methods to define arrays and scalars
164 void defineArray(maiabd_type type, const MString& name, size_type totalCount);
165 void defineArray(maiabd_type type, const MString& name, size_type noDims, size_type* totalCount);
166 void defineArray(maiabd_type type, const std::vector<MString>& name, size_type totalCount);
167 void defineArray(maiabd_type type, const MString& datasetName, const MString& name, size_type noDims,
168 size_type* totalCount);
169 void defineScalar(maiabd_type type, const MString& name);
170
171 // Methods to write data or attributes
172 template <class T>
173 void writeArray(const T* array, const MString& name, size_type memoryStride = -1, size_type diskStride = -1);
174 template <class T>
175 void writeArray(const T* array, const std::vector<MString>& names, size_type memoryStride = -1,
176 size_type diskStride = -1);
177 template <class T>
178 void writeArray(const T* array, const MString& path, const MString& name, const size_type noDims, size_type* offset,
179 size_type* localCount);
180 template <class T>
181 void writeArray(const T* array, const MString& path, const MString& name, const size_type noDims, size_type* offset,
182 size_type* localCount, size_type* ghost);
183 template <class T>
184 void writeScalar(T scalar, const MString& name);
185 template <class T>
186 void setAttribute(const T& value, const MString& name, const MString& datasetName = "");
187 void setAttribute(const MChar* value, const MString& name, const MString& datasetName = "");
188 template <class T>
189 void setAttributes(const T* value, const MString& name, size_type totalCount, const MString& datasetName = "");
190
191 // Methods to read data or attributes
192 template <class T>
193 void readArray(T* array, const MString& name, size_type memoryStride = -1, size_type diskStride = -1);
194 template <class T>
195 void readArray(std::vector<T>& array, const MString& name, size_type memoryStride = -1, size_type diskStride = -1) {
196 readArray(array.data(), name, memoryStride, diskStride);
197 }
198 template <class T>
199 void readArray(T* array, const std::vector<MString>& names, size_type memoryStride = -1, size_type diskStride = -1);
200
201 template <class T>
202 void readArray(T* array, const MString& datasetName, const MString& name, const size_type noDims,
203 const size_type* offset, const size_type* localCount);
204 template <class T>
205 void readArray(T* array, const MString& datasetName, const MString& name, const size_type noDims,
206 const size_type* localCount);
207
208 template <class T>
209 void readScalar(T* scalar, const MString& name);
210 template <class T>
211 void getAttribute(T* value, const MString& name, const MString& datasetName = "");
212 template <class T>
213 void getAttribute(T* value, const MString& name, const size_type totalCount, const MString& datasetName = "");
214 void getAttributeCount(const MString& name, size_type* totalCount, const MString& datasetName = "");
215
216 // Methods to calculate and set offset
217 void setOffset(const size_type localCount, const size_type offset, const size_type noDims, const size_type noChunks);
218 void setOffset(const size_type localCount, const size_type offset, const size_type noDims);
219 void setOffset(size_type localCount, size_type offset);
220
221 static void calcOffset(size_type localCount, size_type* offset, size_type* totalCount, const MPI_Comm& mpiComm,
222 size_type* noChunks = nullptr);
223
224 // Member variables and methods which are not part of the interface
225 protected:
226 // Auxiliary methods
227 void validateType(const maiabd_type type) const;
228
229 // File related
231 const MInt m_fileMode = -1;
233
234 // Other core member variables used for information
235 // which will be added into the file header
238
239 // MPI-related
240 MPI_Comm m_mpiComm{};
241 MPI_Info m_mpiInfo = MPI_INFO_NULL;
242
243 // Offset array-related (usually: offset size = number of cells)
245 std::vector<size_type> m_localCount = {-1};
246 std::vector<size_type> m_offset = {-1};
248
249 // Creation time stamp to output total file lifetime
251
252#ifdef MAIA_EXTRA_DEBUG
253 // Debugging related
254 std::set<MString> m_unwrittenArrays;
255 std::set<MString> m_unwrittenScalars;
256 std::set<MString> m_writtenArrays;
257 std::set<MString> m_writtenScalars;
258 std::set<MString> m_readArrays;
259 std::set<MString> m_readScalars;
260#endif
261
262 // Maximum allowable size for writing to an array at once (limited by MPI I/O,
263 // as the 'count' parameter in the relevant MPI call is a 32-bit integer). The
264 // value used here is 2^31 - 3, the '-3' being an extra buffer
265 const static size_type s_maxChunkSize = 2147483645;
266
267 // Internal pseudo-datatypes used for MPI-related tasks
268 // Used to communicate values of type 'size_type'. Therefore the chosen type
269 // must always be big enough to hold a single value of 'size_type'.
270 const static MPI_Datatype s_mpiSizeType;
271};
272
273// For future Developers of ParallelIo:
274// Why here? These headers contain definitions of derived classes of
275// ParallelIoBase(-> They can't be on the top). After these includes the
276// definitions of member functions of
277// ParallelIoBase call functions of these derived classes(-> They have to be
278// included before member function definitions and after defining the Base
279// Class).
280#if !defined(MAIA_WINDOWS)
281#include "parallelio_pnetcdf.h"
282#elif !defined(WITH_HDF5)
283#error Cannot compile on Windows if "WITH_HDF5" is not set
284#endif
285#if defined(WITH_HDF5)
286#include "parallelio_hdf5.h"
287#endif
288
289// Add convenience type definition to allow simple usage of the default backend
290// "configure.py ? ?" -> PARALLELIO_DEFAULT_BACKEND = ParallelIoPNetcdf
291// "configure.py ? ? --io hdf5" -> PARALLELIO_DEFAULT_BACKEND = ParallelIoHdf5
292using ParallelIo = PARALLELIO_DEFAULT_BACKEND;
293
294// Set static members
295template <typename Backend>
296const MPI_Datatype
298
299//------------------------------------------------------------------------------
300// Static file system-related methods
301//------------------------------------------------------------------------------
302
303
317template <typename Backend>
318MBool ParallelIoBase<Backend>::fileExists(const MString& name, const MPI_Comm& mpiComm) {
319 TRACE();
320
321 // Try to stat file on rank 0 - will return something other than zero of file
322 // does not exist - and broadcast to others
323 int rank, status;
324 MPI_Comm_rank(mpiComm, &rank);
325 if(rank == 0) {
326 struct stat buffer {};
327 status = static_cast<int>(stat(name.c_str(), &buffer) == 0);
328 }
329 MPI_Bcast(&status, 1, MPI_INT, 0, mpiComm, AT_, "status");
330
331 return status != 0;
332}
333
334
345template <typename Backend>
347 TRACE();
348
349 MPI_File_delete(const_cast<MChar*>(name.c_str()), MPI_INFO_NULL);
350}
351
352
363template <class Backend>
364MBool ParallelIoBase<Backend>::isParallelIoFile(const MString& name, const MPI_Comm& mpiComm) {
365 TRACE();
366
367 return Backend::b_isValidFile(name, mpiComm);
368}
369
370
378template <class Backend>
380 TRACE();
381
382 return Backend::b_fileExt();
383}
384
385
386//------------------------------------------------------------------------------
387// Constructors & destructor
388//------------------------------------------------------------------------------
389
390
404template <class Backend>
405ParallelIoBase<Backend>::ParallelIoBase(MString fileName, MInt fileMode, const MPI_Comm& mpiComm)
406 : m_fileName(std::move(fileName)), m_fileMode(fileMode), m_mpiComm(mpiComm) {
407 TRACE();
408
409 using namespace maia::parallel_io;
410 // Make sure that the file mode is supported
411 if(fileMode != PIO_CREATE && fileMode != PIO_APPEND && fileMode != PIO_REPLACE && fileMode != PIO_READ) {
412 TERMM(1, "File mode must be one of PIO_CREATE/PIO_APPEND/PIO_REPLACE/PIO_READ!");
413 }
414
415 // Set domain id and number of domains
416 MPI_Comm_rank(m_mpiComm, &m_domainId);
417 MPI_Comm_size(m_mpiComm, &m_noDomains);
418
419 // Store creation time stamp
421}
422
423
430template <class Backend>
432 TRACE();
433
434 // Log the total file lifetime
435 const MFloat lifetime = wallTime() - m_creationTime;
436
437 const MInt maxLineLength = 256;
438 MChar b[maxLineLength];
439 snprintf(b, maxLineLength, "=== PARALLELIO FILE LIFETIME: %-35s | %.4e s |\n", m_fileName.c_str(), lifetime);
440 if(m_domainId == 0) {
441 std::cerr << b;
442 }
443 m_log << b;
444}
445
446
447//------------------------------------------------------------------------------
448// Methods to get information about file contents
449//------------------------------------------------------------------------------
450
451
466template <class Backend>
468 TRACE();
469
470 MBool returnValue = derived().b_hasDataset(name, dimension);
471
472 return returnValue;
473}
474
475
486template <class Backend>
488 TRACE();
489
490 MBool returnValue = derived().b_hasDataset(name, -1);
491
492 return returnValue;
493}
494
495template <class Backend>
497 TRACE();
498
499 MBool returnValue = derived().b_hasDataset(name, path);
500
501 return returnValue;
502}
503
504template <class Backend>
506 TRACE();
507
508 MBool returnValue = derived().b_hasObject(name);
509
510 return returnValue;
511}
512
513
529template <class Backend>
531 TRACE();
532
533 // Abort if dataset does not exist
534 if(!hasDataset(name)) {
535 TERMM(1, "The specified dataset '" + name + "' does not exist.");
536 }
537
538 return derived().b_getDatasetType(name);
539}
540
541
553template <class Backend>
554std::vector<MString> ParallelIoBase<Backend>::getDatasetNames(const size_type dimension) {
555 TRACE();
556
557 std::vector<MString> names;
558 derived().b_getDatasetNames(names, dimension);
559
560 return names;
561}
562
563
564template <class Backend>
565std::vector<MString> ParallelIoBase<Backend>::getDatasetNames(const MString& path) {
566 TRACE();
567
568 std::vector<MString> names;
569 derived().b_getDatasetNames(names, path);
570
571 return names;
572}
573
574template <class Backend>
575std::vector<MString> ParallelIoBase<Backend>::getGroupNames(const MString& path) {
576 TRACE();
577
578 std::vector<MString> names;
579 derived().b_getGroupNames(names, path);
580
581 return names;
582}
583
593template <class Backend>
595 TRACE();
596
597 // Abort if dataset does not exist
598 if(!hasDataset(name)) {
599 TERMM(1, "The specified dataset '" + name + "' does not exist.");
600 }
601
602 size_type noDims = derived().b_getDatasetNoDims(name);
603
604 return noDims;
605}
606
607template <class Backend>
609 const MString& path) {
610 TRACE();
611
612 // Abort if dataset does not exist
613 if(!hasDataset(name, path)) {
614 TERMM(1, "The specified dataset '" + name + "' does not exist.");
615 }
616
617 size_type noDims = derived().b_getDatasetNoDims(name, path);
618
619 return noDims;
620}
621
622
632template <class Backend>
633std::vector<typename ParallelIoBase<Backend>::size_type> ParallelIoBase<Backend>::getArrayDims(const MString& name) {
634 TRACE();
635
636 // Abort if array does not exist
637 if(!hasDataset(name) || hasDataset(name, 0)) {
638 TERMM(1, "The specified array '" + name + "' does not exist.");
639 }
640
641 // Get number of dimensions
642 size_type noDims = getDatasetNoDims(name);
643
644 std::vector<size_type> dims;
645
646 // Get lengths of all dimensions
647 for(size_type dimId = 0; dimId < noDims; dimId++) {
648 dims.push_back(getArraySize(name, dimId));
649 }
650
651 return dims;
652}
653
654
666template <class Backend>
668 const size_type dimensionId) {
669 TRACE();
670
671 // Abort if dataset does not exist or if its a scalar
672 if(!hasDataset(name) || hasDataset(name, 0)) {
673 TERMM(1, "The specified array '" + name + "' does not exist.");
674 }
675
676 // Abort if dimensionId exceeds number of dimensions
677 size_type noDims = getDatasetNoDims(name);
678 if(dimensionId >= noDims) {
679 TERMM(1, "The specified dimension for array '" + name + "'does not exist.");
680 }
681
682 size_type returnValue = derived().b_getDatasetSize(name, dimensionId);
683
684 return returnValue;
685}
686
687template <class Backend>
688void ParallelIoBase<Backend>::getArraySize(const MString& name, const MString& path, size_type* datasetSize) {
689 TRACE();
690
691 // Abort if dataset does not exist or if its a scalar
692 if(!hasDataset(name, path)) {
693 TERMM(1, "The specified array '" + name + "' does not exist.");
694 }
695
696 size_type noDims = derived().b_getDatasetNoDims(name, path);
697 derived().b_getDatasetSize(name, path, noDims, datasetSize);
698}
699
700
713template <class Backend>
715 TRACE();
716
717 // If the dataset name is empty, this means a file attribute should be
718 // checked.
719 // Otherwise a dataset attribute (scalar or array) is to be checked - abort if
720 // no dataset can be found.
721 if(!path.empty()) {
722 if(!hasObject(path)) {
723 return false;
724 }
725 }
726
727 MBool returnValue = derived().b_hasAttribute(name, path);
728
729 return returnValue;
730}
731
732
748template <class Backend>
750 TRACE();
751
752 // Abort if attribute does not exist
753 if(!hasAttribute(name, datasetName)) {
754 mTerm(1, AT_, "The specified attribute does not exist.");
755 }
756
757 return derived().b_getAttributeType(name, datasetName);
758}
759
760
761//------------------------------------------------------------------------------
762// Methods to define arrays and scalars
763//------------------------------------------------------------------------------
764
765
782template <class Backend>
784 TRACE();
785
786#ifdef DISABLE_OUTPUT
787 return;
788#endif
789
790 defineArray(type, name, 1, &totalCount);
791}
792
793
811template <class Backend>
813 size_type* totalCount) {
814 TRACE();
815
816#ifdef DISABLE_OUTPUT
817 return;
818#endif
819
820 using namespace maia::parallel_io;
821
822 // Prevent adding data in read-only mode
823 if(m_fileMode == PIO_READ) {
824 mTerm(1, AT_, "Cannot add data in read-only mode!");
825 }
826
827 // Abort if header was already written
828 if(m_isHeaderSaved) {
829 mTerm(1, AT_, "Cannot add new data after header was written!");
830 }
831
832#ifdef MAIA_EXTRA_DEBUG
833 m_unwrittenArrays.insert(name);
834#endif
835
836 // Ensure reasonable parameter values
837 validateType(type);
838 if(name.empty()) {
839 TERMM(1, "Invalid name! Name must not be empty.");
840 }
841 if(noDims <= 0) {
842 TERMM(1, "Invalid number of dimensions! Must at least be 1.");
843 }
844
845 derived().b_defineArray(type, name, noDims, totalCount);
846}
847
848
864template <class Backend>
865void ParallelIoBase<Backend>::defineArray(maiabd_type type, const std::vector<MString>& names, size_type totalCount) {
866 TRACE();
867
868#ifdef DISABLE_OUTPUT
869 return;
870#endif
871
872 for(const auto& name : names) {
873 defineArray(type, name, totalCount);
874 }
875}
876
890template <class Backend>
891void ParallelIoBase<Backend>::defineArray(maiabd_type type, const MString& datasetName, const MString& name,
892 size_type noDims, size_type* totalCount) {
893 TRACE();
894
895 using namespace maia::parallel_io;
896
897 // Prevent adding data in read-only mode
898 if(m_fileMode == PIO_READ) {
899 mTerm(1, AT_, "Cannot add data in read-only mode!");
900 }
901
902#ifdef MAIA_EXTRA_DEBUG
903 m_unwrittenArrays.insert(name);
904#endif
905
906 // Ensure reasonable parameter values
907 validateType(type);
908 if(name.empty()) {
909 TERMM(1, "Invalid name! Name must not be empty.");
910 }
911 if(noDims <= 0) {
912 TERMM(1, "Invalid number of dimensions! Must at least be 1.");
913 }
914
915 derived().b_defineArray(type, datasetName, name, noDims, totalCount);
916}
917
918
932template <class Backend>
934 TRACE();
935
936#ifdef DISABLE_OUTPUT
937 return;
938#endif
939
940 using namespace maia::parallel_io;
941
942 // Prevent adding data in read-only mode
943 if(m_fileMode == PIO_READ) {
944 TERMM(1, "Cannot add data in read-only mode!");
945 }
946
947 // Abort if header was already written
948 if(m_isHeaderSaved) {
949 TERMM(1, "Cannot add new data after header was written!");
950 }
951
952#ifdef MAIA_EXTRA_DEBUG
953 m_unwrittenScalars.insert(name);
954#endif
955
956 // Ensure reasonable parameter values
957 validateType(type);
958 if(name.empty()) {
959 TERMM(1, "Invalid name! Name must not be empty.");
960 }
961
962 derived().b_defineScalar(type, name);
963}
964
965
966//------------------------------------------------------------------------------
967// Methods to write data or attributes
968//------------------------------------------------------------------------------
969
970
1044template <class Backend>
1045template <class T>
1046void ParallelIoBase<Backend>::writeArray(const T* array, const MString& name, size_type memoryStride,
1047 size_type diskStride) {
1048 TRACE();
1049
1050#ifdef DISABLE_OUTPUT
1051 return;
1052#endif
1053
1054 using namespace maia::parallel_io;
1055
1056 // Prevent rewriting data in read-only mode
1057 if(m_fileMode == PIO_READ) {
1058 TERMM(1, "Cannot write data in read-only mode!");
1059 }
1060
1061 // Abort if offsets were not set
1062 if(!m_offsetsAreSet) {
1063 TERMM(1, "Offsets have to be set before calling writeArray!");
1064 }
1065
1066#ifdef MAIA_EXTRA_DEBUG
1067 // In debug mode, check if array was already written and give a warning
1068 if(m_writtenArrays.count(name) != 0) {
1069 std::cerr << "Warning: in " << AT_ << " (" << __FILE__ << ":" << __LINE__ << ") "
1070 << "the array '" << name << "' is written more than once. Make sure that this is the"
1071 << "intended behavior." << std::endl;
1072 }
1073 m_writtenArrays.insert(name);
1074 if(m_unwrittenArrays.count(name)) {
1075 m_unwrittenArrays.erase(name);
1076 }
1077#endif
1078
1079 // Ensure reasonable parameter values
1080 if(memoryStride != -1 && memoryStride <= 0) {
1081 TERMM(1, "memoryStride must be greater than zero (or -1 to set automatically)!");
1082 }
1083 if(diskStride != -1 && diskStride <= 0) {
1084 TERMM(1, "diskStride must be greater than zero (or -1 to set automatically)!");
1085 }
1086 if(array == 0 && m_localCount[0] > 0) {
1087 TERMM(1, "Data pointer must point to a valid location (is: null pointer)!");
1088 }
1089
1090 // Set actual stride if no explicit stride value was given
1091 size_type actualMemoryStride;
1092 if(memoryStride == -1) {
1093 actualMemoryStride = 1;
1094 } else {
1095 actualMemoryStride = memoryStride;
1096 }
1097 size_type actualDiskStride = (diskStride == -1) ? 1 : diskStride;
1098
1099 // Save header (if not yet
1100 if(!m_isHeaderSaved) {
1101 derived().b_saveHeader();
1102 m_isHeaderSaved = true;
1103 }
1104
1105 // Set number of chunks
1106 const size_type noChunks = (m_noChunks == -1) ? 1 : m_noChunks;
1107
1108 size_type noDims = getDatasetNoDims(name);
1109
1110 ScratchSpace<MPI_Offset> localCount(noDims, FUN_, "localCount");
1111 ScratchSpace<MPI_Offset> offset(noDims, FUN_, "offset");
1112
1113 // Set counts for all dimensions except first to total dimension length
1114 // localCount[0] is set via setOffset(...)
1115 localCount[0] = m_localCount[0];
1116 for(MInt dimId = 1; dimId < noDims; dimId++) {
1117 localCount[dimId] = getArraySize(name, dimId);
1118 }
1119 for(MInt dimId = 0; dimId < noDims; dimId++) {
1120 offset[dimId] = m_offset[dimId];
1121 }
1122
1123 // Write array
1124 derived().b_writeArray(array, name, noDims, &offset[0], &localCount[0], actualMemoryStride, noChunks,
1125 actualDiskStride);
1126}
1127
1128
1202template <class Backend>
1203template <class T>
1204void ParallelIoBase<Backend>::writeArray(const T* array, const std::vector<MString>& names, size_type memoryStride,
1205 size_type diskStride) {
1206 TRACE();
1207
1208#ifdef DISABLE_OUTPUT
1209 return;
1210#endif
1211
1212 // Ensure reasonable parameter values
1213 if(memoryStride != -1 && memoryStride < static_cast<size_type>(names.size())) {
1214 TERMM(1, "memoryStride must be greater than or equal to number of "
1215 "variables (or -1 to set automatically)!");
1216 }
1217 if(diskStride != -1 && diskStride < static_cast<size_type>(names.size())) {
1218 TERMM(1, "diskStride must be greater than or equal to number of "
1219 "variables (or -1 to set automatically)!");
1220 }
1221
1222 // Set actual stride if no explicit stride value was given
1223 size_type actualMemoryStride;
1224 if(memoryStride == -1) {
1225 actualMemoryStride = static_cast<size_type>(names.size());
1226 } else {
1227 actualMemoryStride = memoryStride;
1228 }
1229 size_type actualDiskStride = (diskStride == -1) ? 1 : diskStride;
1230
1231 // Write arrays from vector using normal writeArray call
1232 for(std::vector<MString>::size_type i = 0; i < names.size(); i++) {
1233 writeArray(array + i, names[i], actualMemoryStride, actualDiskStride);
1234 }
1235}
1236
1253template <class Backend>
1254template <class T>
1255void ParallelIoBase<Backend>::writeArray(const T* array, const MString& path, const MString& name,
1256 const size_type noDims, size_type* offset, size_type* localCount) {
1257 TRACE();
1258
1259 ScratchSpace<size_type> ghost(noDims, FUN_, "ghost");
1260 ghost.fill(0);
1261
1262 derived().b_writeArray(array, path, name, noDims, offset, localCount, &ghost[0]);
1263}
1264
1265
1290template <class Backend>
1291template <class T>
1293 const MString& path,
1294 const MString& name,
1295 const size_type noDims,
1296 size_type* offset,
1297 size_type* localCount,
1298 size_type* ghost) {
1299 TRACE();
1300
1301#ifdef DISABLE_OUTPUT
1302 return;
1303#endif
1304
1305 using namespace maia::parallel_io;
1306
1307 // Prevent rewriting data in read-only mode
1308 if(m_fileMode == PIO_READ) {
1309 TERMM(1, "Cannot write data in read-only mode!");
1310 }
1311
1312#ifdef MAIA_EXTRA_DEBUG
1313 // In debug mode, check if array was already written and give a warning
1314 if(m_writtenArrays.count(name) != 0) {
1315 std::cerr << "Warning: in " << AT_ << " (" << __FILE__ << ":" << __LINE__ << ") "
1316 << "the array '" << name << "' is written more than once. Make sure that this is the"
1317 << "intended behavior." << std::endl;
1318 }
1319 m_writtenArrays.insert(name);
1320 if(m_unwrittenArrays.count(name)) {
1321 m_unwrittenArrays.erase(name);
1322 }
1323#endif
1324
1325 // Save header (if not yet
1326 if(!m_isHeaderSaved) {
1327 derived().b_saveHeader();
1328 m_isHeaderSaved = true;
1329 }
1330
1331 // Ensure reasonable parameter values
1332 if(array == 0 && localCount[0] > 0) {
1333 TERMM(1, "Data pointer must point to a valid location (is: null pointer)!");
1334 }
1335
1336 // Write array
1337 derived().b_writeArray(array, path, name, noDims, offset, localCount, ghost);
1338}
1339
1340
1352template <class Backend>
1353template <class T>
1355 TRACE();
1356
1357#ifdef DISABLE_OUTPUT
1358 return;
1359#endif
1360
1361 using namespace maia::parallel_io;
1362
1363 // Prevent rewriting data in read-only mode
1364 if(m_fileMode == PIO_READ) {
1365 mTerm(1, AT_, "Cannot write data in read-only mode!");
1366 }
1367
1368#ifndef NDEBUG
1369 // In debug mode check if scalar value is the same on all ranks
1370 const T localValue = scalar;
1371 ScratchSpace<T> globalValues(m_noDomains, AT_, "globalValues");
1372 // Gather scalar values on rank 0
1373 MPI_Gather(&localValue, 1, maia::type_traits<T>::mpiType(), &globalValues[0], 1, maia::type_traits<T>::mpiType(), 0,
1374 m_mpiComm, AT_, "localValue", "globalValues[0]");
1375
1376 // Compare values
1377 if(m_domainId == 0) {
1378 for(MInt i = 0; i < m_noDomains; i++) {
1379 MBool equal = true;
1380 // Note: cannot use == for floating point values
1381 if(globalValues[i] < localValue) {
1382 equal = false;
1383 }
1384 if(globalValues[i] > localValue) {
1385 equal = false;
1386 }
1387 if(!equal) {
1388 TERMM(1, "Error: scalar variable has not the same value on all domains, rank 0: " + std::to_string(localValue)
1389 + " != " + std::to_string(globalValues[i]) + " (domain " + std::to_string(i) + ")");
1390 }
1391 }
1392 }
1393#endif
1394
1395#ifdef MAIA_EXTRA_DEBUG
1396 // In extra debug mode, check if scalar was already written and give a warning
1397 if(m_writtenScalars.count(name) != 0) {
1398 std::cerr << "Warning: in " << AT_ << " (" << __FILE__ << ":" << __LINE__ << ") "
1399 << "the scalar '" << name << "' is written more than once. Make sure that this is the"
1400 << "intended behavior." << std::endl;
1401 }
1402 m_writtenScalars.insert(name);
1403 if(m_unwrittenScalars.count(name)) {
1404 m_unwrittenScalars.erase(name);
1405 }
1406#endif
1407
1408 // Save header (if not yet done)
1409 if(!m_isHeaderSaved) {
1410 derived().b_saveHeader();
1411 m_isHeaderSaved = true;
1412 }
1413
1414 derived().b_writeScalar(scalar, name);
1415}
1416
1417
1436template <class Backend>
1437template <class T>
1438void ParallelIoBase<Backend>::setAttribute(const T& value, const MString& name, const MString& datasetName) {
1439 TRACE();
1440 setAttributes(&value, name, 1, datasetName);
1441}
1442
1443// Provide simple overload in order to accept string literals
1444template <class Backend>
1445void ParallelIoBase<Backend>::setAttribute(const MChar* value, const MString& name, const MString& datasetName) {
1446 const MString tmpValue = MString(value);
1447 setAttributes(&tmpValue, name, 1, datasetName);
1448}
1449
1450template <class Backend>
1451template <class T>
1453 const MString& name,
1454 size_type totalCount,
1455 const MString& datasetName) {
1456 TRACE();
1457
1458#ifdef DISABLE_OUTPUT
1459 return;
1460#endif
1461
1462 using namespace maia::parallel_io;
1463
1464 // Prevent rewriting data in read-only mode
1465 if(m_fileMode == PIO_READ) {
1466 mTerm(1, AT_, "Cannot write data in read-only mode!");
1467 }
1468
1469 // Ensure reasonable parameter values
1470 if(name.empty()) {
1471 mTerm(1, AT_, "Invalid name! Name must not be empty.");
1472 }
1473 ASSERT(totalCount > 0, "");
1474
1475 derived().b_setAttribute(value, name, datasetName, totalCount);
1476}
1477
1478
1479//------------------------------------------------------------------------------
1480// Methods to read data or attributes
1481//------------------------------------------------------------------------------
1482
1483
1521template <class Backend>
1522template <class T>
1523void ParallelIoBase<Backend>::readArray(T* array, const MString& name, size_type memoryStride, size_type diskStride) {
1524 TRACE();
1525
1526 // Abort if offsets were not set
1527 if(!m_offsetsAreSet) {
1528 mTerm(1, AT_, "Offsets have to be set before calling readArray!");
1529 }
1530
1531#ifdef MAIA_EXTRA_DEBUG
1532 // In debug mode, check if array was already read and give a warning
1533 if(m_readArrays.count(name) != 0) {
1534 std::cerr << "Warning: in " << AT_ << " (" << __FILE__ << ":" << __LINE__ << ") "
1535 << "the array '" << name << "' is read more than once. Make sure that this is the"
1536 << "intended behavior." << std::endl;
1537 }
1538 m_readArrays.insert(name);
1539#endif
1540
1541 // Ensure reasonable parameter values
1542 if(memoryStride != -1 && memoryStride <= 0) {
1543 mTerm(1, AT_, "memoryStride must be greater than zero (or -1 to set automatically)!");
1544 }
1545 if(diskStride != -1 && diskStride <= 0) {
1546 mTerm(1, AT_, "diskStride must be greater than zero (or -1 to set automatically)!");
1547 }
1548 if(array == 0 && m_localCount[0] > 0) {
1549 mTerm(1, AT_, "Data pointer must point to a valid location (is: null pointer)!");
1550 }
1551
1552 // Set actual stride if no explicit stride value was given
1553 size_type actualMemoryStride;
1554 if(memoryStride == -1) {
1555 actualMemoryStride = 1;
1556 } else {
1557 actualMemoryStride = memoryStride;
1558 }
1559 size_type actualDiskStride = (diskStride == -1) ? 1 : diskStride;
1560
1561 // Set number of chunks
1562 const size_type noChunks = (m_noChunks == -1) ? 1 : m_noChunks;
1563
1564 size_type noDims = getDatasetNoDims(name);
1565
1566 ScratchSpace<MPI_Offset> localCount(noDims, FUN_, "localCount");
1567 ScratchSpace<MPI_Offset> offset(noDims, FUN_, "offset");
1568
1569 localCount[0] = m_localCount[0];
1570 // Set counts for all dimensions except first to total dimension length
1571 // m_localCount[0] is set via setOffset(...)
1572 for(MInt dimId = 1; dimId < noDims; dimId++) {
1573 localCount[dimId] = getArraySize(name, dimId);
1574 }
1575 for(MInt dimId = 0; dimId < noDims; dimId++) {
1576 offset[dimId] = m_offset[dimId];
1577 }
1578
1579 // Read array
1580 derived().b_readArray(array, name, noDims, &offset[0], &localCount[0], actualMemoryStride, noChunks,
1581 actualDiskStride);
1582}
1583
1600template <class Backend>
1601template <class T>
1603 const MString& datasetName,
1604 const MString& name,
1605 const size_type noDims,
1606 const size_type* offset,
1607 const size_type* localCount) {
1608 TRACE();
1609
1610#ifdef MAIA_EXTRA_DEBUG
1611 // In debug mode, check if array was already read and give a warning
1612 if(m_readArrays.count(name) != 0) {
1613 std::cerr << "Warning: in " << AT_ << " (" << __FILE__ << ":" << __LINE__ << ") "
1614 << "the array '" << name << "' is read more than once. Make sure that this is the"
1615 << "intended behavior." << std::endl;
1616 }
1617 m_readArrays.insert(name);
1618#endif
1619
1620 if(array == 0 && localCount[0] > 0) {
1621 mTerm(1, AT_, "Data pointer must point to a valid location (is: null pointer)!");
1622 }
1623
1624 // Read array
1625 derived().b_readArray(array, datasetName, name, noDims, offset, localCount);
1626}
1627
1643template <class Backend>
1644template <class T>
1645void ParallelIoBase<Backend>::readArray(T* array, const MString& datasetName, const MString& name,
1646 const size_type noDims, const size_type* localCount) {
1647 TRACE();
1648
1649#ifdef MAIA_EXTRA_DEBUG
1650 // In debug mode, check if array was already read and give a warning
1651 if(m_readArrays.count(name) != 0) {
1652 std::cerr << "Warning: in " << AT_ << " (" << __FILE__ << ":" << __LINE__ << ") "
1653 << "the array '" << name << "' is read more than once. Make sure that this is the"
1654 << "intended behavior." << std::endl;
1655 }
1656 m_readArrays.insert(name);
1657#endif
1658
1659 if(array == 0 && localCount[0] > 0) {
1660 mTerm(1, AT_, "Data pointer must point to a valid location (is: null pointer)!");
1661 }
1662
1663 ScratchSpace<size_type> offset(noDims, FUN_, "offset");
1664 offset.fill(0);
1665
1666 // Read array
1667 derived().b_readArray(array, datasetName, name, noDims, &offset[0], localCount);
1668}
1669
1709template <class Backend>
1710template <class T>
1711void ParallelIoBase<Backend>::readArray(T* array, const std::vector<MString>& names, size_type memoryStride,
1712 size_type diskStride) {
1713 TRACE();
1714
1715 // Ensure reasonable parameter values
1716 if(memoryStride != -1 && memoryStride < static_cast<size_type>(names.size())) {
1717 mTerm(1, AT_,
1718 "memoryStride must be greater than or equal to number of "
1719 "variables (or -1 to set automatically)!");
1720 }
1721 if(diskStride != -1 && diskStride < static_cast<size_type>(names.size())) {
1722 mTerm(1, AT_,
1723 "diskStride must be greater than or equal to number of "
1724 "variables (or -1 to set automatically)!");
1725 }
1726
1727 // Set actual stride if no explicit stride value was given
1728 size_type actualMemoryStride;
1729 if(memoryStride == -1) {
1730 actualMemoryStride = static_cast<size_type>(names.size());
1731 } else {
1732 actualMemoryStride = memoryStride;
1733 }
1734 size_type actualDiskStride = (diskStride == -1) ? 1 : diskStride;
1735
1736 // Read arrays from vector using normal readArray call
1737 for(std::vector<MString>::size_type i = 0; i < names.size(); i++) {
1738 readArray(array + i, names[i], actualMemoryStride, actualDiskStride);
1739 }
1740}
1741
1742
1756template <class Backend>
1757template <class T>
1758void ParallelIoBase<Backend>::readScalar(T* scalar, const MString& name) {
1759#ifdef MAIA_EXTRA_DEBUG
1760 // In debug mode, check if scalar was already read and give a warning
1761 if(m_readScalars.count(name) != 0) {
1762 std::cerr << "Warning: in " << AT_ << " (" << __FILE__ << ":" << __LINE__ << ") "
1763 << "the scalar '" << name << "' is read more than once. Make sure that this is the"
1764 << "intended behavior." << std::endl;
1765 }
1766 m_readScalars.insert(name);
1767#endif
1768
1769 derived().b_readScalar(scalar, name);
1770}
1771
1772
1786template <class Backend>
1787template <class T>
1788void ParallelIoBase<Backend>::getAttribute(T* value, const MString& name, const MString& datasetName) {
1789 TRACE();
1790 getAttribute(value, name, 1, datasetName);
1791}
1792
1793template <class Backend>
1794template <class T>
1795void ParallelIoBase<Backend>::getAttribute(T* value, const MString& name, const size_type totalCount,
1796 const MString& datasetName) {
1797 TRACE();
1798 derived().b_getAttribute(value, name, datasetName, totalCount);
1799}
1800
1801template <class Backend>
1803 const MString& datasetName) {
1804 TRACE();
1805 derived().b_getAttributeCount(name, totalCount, datasetName);
1806}
1807
1808//------------------------------------------------------------------------------
1809// Methods to calculate and set offset
1810//------------------------------------------------------------------------------
1811
1812
1839template <class Backend>
1841 const size_type offset,
1842 const size_type noDims,
1843 const size_type noChunks) {
1844 TRACE();
1845
1846 // Ensure reasonable parameter values
1847 if(localCount < 0) {
1848 TERMM(1, "The local size may not be less than zero (was:" + std::to_string(localCount) + ")!");
1849 }
1850 if(offset < 0) {
1851 TERMM(1, "The offset may not be less than zero (was:" + std::to_string(offset) + ")!");
1852 }
1853 if(noDims <= 0) {
1854 TERMM(1, "The number of dimensions must at least be one!");
1855 }
1856 if(noChunks == 0) {
1857 TERMM(1, "The number of chunks may not be zero!");
1858 }
1859
1860 // TODO labels:IO add support for setting a multi-dimensional count/offset for reading/writing data
1861
1862 // Set member variables
1863 m_localCount.reserve(noDims);
1864 m_localCount.assign(noDims, -1); // -1 as a precaution
1865 m_localCount[0] = localCount;
1866
1867 // Note:
1868 // if noDims>1: {m_localCount[i], i>0} will be set to the total count for that
1869 // dimension before reading/writing the multi-d array
1870 // setting the local count for multiple dimensions is not yet supported
1871 m_offset.reserve(noDims);
1872 m_offset.assign(noDims, 0);
1873 m_offset[0] = offset;
1874
1875 if(noChunks > 0) {
1876 m_noChunks = noChunks;
1877 }
1878
1879 // Set state variable
1880 m_offsetsAreSet = true;
1881}
1882
1883
1888template <class Backend>
1889void ParallelIoBase<Backend>::setOffset(const size_type localCount, const size_type offset, const size_type noDims) {
1890 TRACE();
1891
1892 setOffset(localCount, offset, noDims, -1);
1893}
1894
1895
1900template <class Backend>
1901void ParallelIoBase<Backend>::setOffset(const size_type localCount, const size_type offset) {
1902 TRACE();
1903
1904 setOffset(localCount, offset, 1, -1);
1905}
1906
1907
1926template <class Backend>
1928 const MPI_Comm& mpiComm, size_type* noChunks) {
1929 TRACE();
1930
1931 // Ensure reasonable parameter values
1932 if(localCount < 0) {
1933 TERMM(1, "The local size may not be less than zero (was:" + std::to_string(localCount) + ")!");
1934 }
1935
1936 // Get rank and size
1937 MInt domainId, noDomains;
1938 MPI_Comm_rank(mpiComm, &domainId);
1939 MPI_Comm_size(mpiComm, &noDomains);
1940
1941 // Calculate offset and total size values
1942 MPI_Exscan(&localCount, offset, 1, s_mpiSizeType, MPI_SUM, mpiComm, AT_, "localCount", "offset");
1943 if(domainId == 0) {
1944 offset[0] = 0;
1945 }
1946
1947 totalCount[0] = offset[0] + localCount;
1948 MPI_Bcast(totalCount, 1, s_mpiSizeType, (noDomains - 1), mpiComm, AT_, "totalCount");
1949
1950 // If a domain has zero size set the offset to zero such that reading/writing
1951 // can not result in an error caused by exceeding the array size
1952 if(localCount == 0) {
1953 offset[0] = 0;
1954 }
1955
1956 // If noChunks is not a null pointer, calculate & set number of chunks
1957 if(noChunks != nullptr) {
1958 // Divide total count by maximum chunk size
1959 noChunks[0] = totalCount[0] / s_maxChunkSize;
1960
1961 // If there is a remainder for the division, increment number by one
1962 if(totalCount[0] % s_maxChunkSize > 0) {
1963 noChunks[0] += 1;
1964 }
1965 }
1966}
1967
1968
1975template <class Backend>
1977 TRACE();
1978
1979 using namespace maia::parallel_io;
1980
1981 if(type != PIO_FLOAT && type != PIO_INT && type != PIO_LONG && type != PIO_STRING && type != PIO_UCHAR
1982 && type != PIO_ULONGLONG) {
1983 TERMM(1, "Invalid data type! Must be PIO_FLOAT or PIO_INT or PIO_LONG or PIO_STRING or PIO_UCHAR.");
1984 }
1985}
1986
1987
1988#endif /* PARALLELIO_H */
This class is intended to do all the heavy lifting when it comes to reading and writing "big data" fi...
Definition: parallelio.h:101
void readArray(T *array, const MString &datasetName, const MString &name, const size_type noDims, const size_type *offset, const size_type *localCount)
Read array data from file. [MPI]
Definition: parallelio.h:1602
void setOffset(const size_type localCount, const size_type offset, const size_type noDims)
Set the local and global counts, as well the local offset for array operations (overload).
Definition: parallelio.h:1889
void readArray(T *array, const std::vector< MString > &names, size_type memoryStride=-1, size_type diskStride=-1)
Read array data from file (multi-array version). [MPI]
Definition: parallelio.h:1711
MBool hasDataset(const MString &name)
Check if the file contains an dataset with the given name.
Definition: parallelio.h:487
ParallelIoBase(MString fileName, MInt fileMode, const MPI_Comm &mpiComm)
Creates a new object to read and write big data files. [MPI]
Definition: parallelio.h:405
void setAttributes(const T *value, const MString &name, size_type totalCount, const MString &datasetName="")
Definition: parallelio.h:1452
MInt getDatasetType(const MString &name)
Returns the data type of an array.
Definition: parallelio.h:530
void getAttribute(T *value, const MString &name, const size_type totalCount, const MString &datasetName="")
Definition: parallelio.h:1795
static const size_type s_maxChunkSize
Definition: parallelio.h:265
void readScalar(T *scalar, const MString &name)
Read scalar data from file. [MPI]
Definition: parallelio.h:1758
Backend & derived()
Definition: parallelio.h:104
MBool hasObject(const MString &path)
Definition: parallelio.h:505
static const MPI_Datatype s_mpiSizeType
Definition: parallelio.h:270
void setOffset(const size_type localCount, const size_type offset, const size_type noDims, const size_type noChunks)
Set the local and global counts, as well the local offset for array operations.
Definition: parallelio.h:1840
static MBool fileExists(const MString &name, const MPI_Comm &mpiComm)
Check whether a file exists. [MPI]
Definition: parallelio.h:318
void writeScalar(T scalar, const MString &name)
Write scalar data to file. [MPI]
Definition: parallelio.h:1354
MBool m_isHeaderSaved
Definition: parallelio.h:232
std::set< MString > m_writtenScalars
Definition: parallelio.h:257
std::set< MString > m_unwrittenScalars
Definition: parallelio.h:255
void defineArray(maiabd_type type, const MString &name, size_type totalCount)
Create a new array in the file.
Definition: parallelio.h:783
void validateType(const maiabd_type type) const
Auxiliary method that aborts MAIA if type is not a valid type constant for ParallelIo.
Definition: parallelio.h:1976
size_type m_noChunks
Definition: parallelio.h:247
void writeArray(const T *array, const MString &name, size_type memoryStride=-1, size_type diskStride=-1)
Write array data to file. [MPI]
Definition: parallelio.h:1046
std::vector< MString > getGroupNames(const MString &path)
Definition: parallelio.h:575
void writeArray(const T *array, const MString &path, const MString &name, const size_type noDims, size_type *offset, size_type *localCount)
Write multidimensional array data to file. [MPI]
Definition: parallelio.h:1255
size_type getDatasetNoDims(const MString &name, const MString &path)
Definition: parallelio.h:608
MBool hasDataset(const MString &name, MInt dimension)
Check if the file contains an dataset with the given name and dimension.
Definition: parallelio.h:467
void getAttribute(T *value, const MString &name, const MString &datasetName="")
Retrieve a file or dataset attribute.
Definition: parallelio.h:1788
const MString m_fileName
Definition: parallelio.h:230
std::vector< MString > getDatasetNames(const size_type dimensions=-1)
Returns a vector with the names of all existing datasets with given dimensionality in the file.
Definition: parallelio.h:554
static void calcOffset(size_type localCount, size_type *offset, size_type *totalCount, const MPI_Comm &mpiComm, size_type *noChunks=nullptr)
Calculates the totalCount and offset information needed in setOffset(). [MPI]
Definition: parallelio.h:1927
void readArray(T *array, const MString &datasetName, const MString &name, const size_type noDims, const size_type *localCount)
Read array data from file [no offset version]. [MPI]
Definition: parallelio.h:1645
MBool m_offsetsAreSet
Definition: parallelio.h:244
std::vector< size_type > m_offset
Definition: parallelio.h:246
MPI_Comm m_mpiComm
Definition: parallelio.h:240
void defineArray(maiabd_type type, const MString &datasetName, const MString &name, size_type noDims, size_type *totalCount)
Creates new array in the file.
Definition: parallelio.h:891
static MBool isParallelIoFile(const MString &name, const MPI_Comm &mpiComm)
Check if specified file is a valid ParallelIoHdf5 file. [MPI]
Definition: parallelio.h:364
MPI_Info m_mpiInfo
Definition: parallelio.h:241
std::vector< MString > getDatasetNames(const MString &path)
Definition: parallelio.h:565
std::set< MString > m_writtenArrays
Definition: parallelio.h:256
void writeArray(const T *array, const MString &path, const MString &name, const size_type noDims, size_type *offset, size_type *localCount, size_type *ghost)
Write multidimensional array data to file [ghost cell version]. [MPI]
Definition: parallelio.h:1292
void defineScalar(maiabd_type type, const MString &name)
Create a new scalar in the file.
Definition: parallelio.h:933
void defineArray(maiabd_type type, const std::vector< MString > &name, size_type totalCount)
Create multiple new arrays in the file.
Definition: parallelio.h:865
MBool hasAttribute(const MString &name, const MString &path="")
Check if a given attribute exists in the file.
Definition: parallelio.h:714
MLong size_type
Type used for all size- and offset-related values.
Definition: parallelio.h:123
void readArray(std::vector< T > &array, const MString &name, size_type memoryStride=-1, size_type diskStride=-1)
Definition: parallelio.h:195
std::vector< size_type > m_localCount
Definition: parallelio.h:245
void setAttribute(const MChar *value, const MString &name, const MString &datasetName="")
Definition: parallelio.h:1445
void defineArray(maiabd_type type, const MString &name, size_type noDims, size_type *totalCount)
Create a new array in the file.
Definition: parallelio.h:812
void getArraySize(const MString &name, const MString &path, size_type *datasetSize)
Definition: parallelio.h:688
size_type getArraySize(const MString &name, const size_type dimensionId=0)
Get the length of an array in the file.
Definition: parallelio.h:667
static MString fileExt()
Returns backend-specific ending of filename (either ".Netcdf" or ".Hdf5")
Definition: parallelio.h:379
static void deleteFile(const MString &name)
Deletes the specified file. [MPI]
Definition: parallelio.h:346
std::set< MString > m_readScalars
Definition: parallelio.h:259
std::vector< size_type > getArrayDims(const MString &name)
Get the lengths of all dimensions of a dataset with given name.
Definition: parallelio.h:633
std::set< MString > m_readArrays
Definition: parallelio.h:258
void getAttributeCount(const MString &name, size_type *totalCount, const MString &datasetName="")
Definition: parallelio.h:1802
const Backend & derived() const
Definition: parallelio.h:105
size_type getDatasetNoDims(const MString &name)
Get the number of dimensions of a dataset with given name.
Definition: parallelio.h:594
MFloat m_creationTime
Definition: parallelio.h:250
void setOffset(size_type localCount, size_type offset)
Set the local and global counts, as well the local offset for array operations (overload).
Definition: parallelio.h:1901
MBool hasDataset(const MString &name, const MString &path)
Definition: parallelio.h:496
maiabd_type getAttributeType(const MString &name, const MString &datasetName="")
Returns the data type of an attribute in the file.
Definition: parallelio.h:749
std::set< MString > m_unwrittenArrays
Definition: parallelio.h:254
void writeArray(const T *array, const std::vector< MString > &names, size_type memoryStride=-1, size_type diskStride=-1)
Write array data to file (multi-array version). [MPI]
Definition: parallelio.h:1204
void setAttribute(const T &value, const MString &name, const MString &datasetName="")
Set a file or dataset attribute. [MPI]
Definition: parallelio.h:1438
void readArray(T *array, const MString &name, size_type memoryStride=-1, size_type diskStride=-1)
Read array data from file. [MPI]
Definition: parallelio.h:1523
maia::parallel_io::maiabd_type maiabd_type
Type used for all constants that are defined in maia::parallel_io.
Definition: parallelio.h:128
const MInt m_fileMode
Definition: parallelio.h:231
virtual ~ParallelIoBase()
empty destructor. [MPI]
Definition: parallelio.h:431
This class is a ScratchSpace.
Definition: scratch.h:758
void fill(T val)
fill the scratch with a given value
Definition: scratch.h:311
void mTerm(const MInt errorCode, const MString &location, const MString &message)
Definition: functions.cpp:29
MFloat wallTime()
Definition: functions.h:80
InfoOutFile m_log
int32_t MInt
Definition: maiatypes.h:62
std::basic_string< char > MString
Definition: maiatypes.h:55
double MFloat
Definition: maiatypes.h:52
int64_t MLong
Definition: maiatypes.h:64
bool MBool
Definition: maiatypes.h:58
char MChar
Definition: maiatypes.h:56
int MPI_Exscan(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Exscan
int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm, const MString &name, const MString &varname)
same as MPI_Bcast
int MPI_Gather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Gather
const MInt PIO_UNKNOWN_TYPE
Definition: parallelio.h:44
const MInt PIO_REPLACE
Definition: parallelio.h:36
const MInt PIO_STRING
Definition: parallelio.h:52
const MInt PIO_ULONGLONG
Definition: parallelio.h:56
const MInt PIO_UCHAR
Definition: parallelio.h:54
const MInt PIO_INT
Definition: parallelio.h:48
const MInt PIO_LONG
Definition: parallelio.h:50
const MInt PIO_APPEND
Definition: parallelio.h:38
const MInt PIO_CREATE
< File mode to create a new file. Aborts if file already exists
Definition: parallelio.h:34
const MInt PIO_FLOAT
Definition: parallelio.h:46
const MInt PIO_READ
Definition: parallelio.h:40
Namespace for auxiliary functions/classes.
PARALLELIO_DEFAULT_BACKEND ParallelIo
Definition: parallelio.h:292