26namespace parallel_io {
100template <
class Backend>
104 Backend&
derived() {
return static_cast<Backend&
>(*this); }
105 const Backend&
derived()
const {
return static_cast<const Backend&
>(*this); }
196 readArray(array.data(), name, memoryStride, diskStride);
252#ifdef MAIA_EXTRA_DEBUG
280#if !defined(MAIA_WINDOWS)
282#elif !defined(WITH_HDF5)
283#error Cannot compile on Windows if "WITH_HDF5" is not set
285#if defined(WITH_HDF5)
295template <
typename Backend>
317template <
typename Backend>
324 MPI_Comm_rank(mpiComm, &rank);
326 struct stat buffer {};
327 status =
static_cast<int>(stat(name.c_str(), &buffer) == 0);
329 MPI_Bcast(&status, 1, MPI_INT, 0, mpiComm, AT_,
"status");
345template <
typename Backend>
349 MPI_File_delete(
const_cast<MChar*
>(name.c_str()), MPI_INFO_NULL);
363template <
class Backend>
367 return Backend::b_isValidFile(name, mpiComm);
378template <
class Backend>
382 return Backend::b_fileExt();
404template <
class Backend>
406 : m_fileName(std::move(fileName)), m_fileMode(fileMode), m_mpiComm(mpiComm) {
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!");
430template <
class Backend>
437 const MInt maxLineLength = 256;
439 snprintf(
b, maxLineLength,
"=== PARALLELIO FILE LIFETIME: %-35s | %.4e s |\n", m_fileName.c_str(), lifetime);
440 if(m_domainId == 0) {
466template <
class Backend>
470 MBool returnValue = derived().b_hasDataset(name, dimension);
486template <
class Backend>
490 MBool returnValue = derived().b_hasDataset(name, -1);
495template <
class Backend>
499 MBool returnValue = derived().b_hasDataset(name, path);
504template <
class Backend>
508 MBool returnValue = derived().b_hasObject(name);
529template <
class Backend>
534 if(!hasDataset(name)) {
535 TERMM(1,
"The specified dataset '" + name +
"' does not exist.");
538 return derived().b_getDatasetType(name);
553template <
class Backend>
557 std::vector<MString> names;
558 derived().b_getDatasetNames(names, dimension);
564template <
class Backend>
568 std::vector<MString> names;
569 derived().b_getDatasetNames(names, path);
574template <
class Backend>
578 std::vector<MString> names;
579 derived().b_getGroupNames(names, path);
593template <
class Backend>
598 if(!hasDataset(name)) {
599 TERMM(1,
"The specified dataset '" + name +
"' does not exist.");
602 size_type noDims = derived().b_getDatasetNoDims(name);
607template <
class Backend>
613 if(!hasDataset(name, path)) {
614 TERMM(1,
"The specified dataset '" + name +
"' does not exist.");
617 size_type noDims = derived().b_getDatasetNoDims(name, path);
632template <
class Backend>
637 if(!hasDataset(name) || hasDataset(name, 0)) {
638 TERMM(1,
"The specified array '" + name +
"' does not exist.");
642 size_type noDims = getDatasetNoDims(name);
644 std::vector<size_type> dims;
647 for(
size_type dimId = 0; dimId < noDims; dimId++) {
648 dims.push_back(getArraySize(name, dimId));
666template <
class Backend>
672 if(!hasDataset(name) || hasDataset(name, 0)) {
673 TERMM(1,
"The specified array '" + name +
"' does not exist.");
677 size_type noDims = getDatasetNoDims(name);
678 if(dimensionId >= noDims) {
679 TERMM(1,
"The specified dimension for array '" + name +
"'does not exist.");
682 size_type returnValue = derived().b_getDatasetSize(name, dimensionId);
687template <
class Backend>
692 if(!hasDataset(name, path)) {
693 TERMM(1,
"The specified array '" + name +
"' does not exist.");
696 size_type noDims = derived().b_getDatasetNoDims(name, path);
697 derived().b_getDatasetSize(name, path, noDims, datasetSize);
713template <
class Backend>
722 if(!hasObject(path)) {
727 MBool returnValue = derived().b_hasAttribute(name, path);
748template <
class Backend>
753 if(!hasAttribute(name, datasetName)) {
754 mTerm(1, AT_,
"The specified attribute does not exist.");
757 return derived().b_getAttributeType(name, datasetName);
782template <
class Backend>
790 defineArray(type, name, 1, &totalCount);
811template <
class Backend>
823 if(m_fileMode == PIO_READ) {
824 mTerm(1, AT_,
"Cannot add data in read-only mode!");
828 if(m_isHeaderSaved) {
829 mTerm(1, AT_,
"Cannot add new data after header was written!");
832#ifdef MAIA_EXTRA_DEBUG
833 m_unwrittenArrays.insert(name);
839 TERMM(1,
"Invalid name! Name must not be empty.");
842 TERMM(1,
"Invalid number of dimensions! Must at least be 1.");
845 derived().b_defineArray(type, name, noDims, totalCount);
864template <
class Backend>
872 for(
const auto& name : names) {
873 defineArray(type, name, totalCount);
890template <
class Backend>
898 if(m_fileMode == PIO_READ) {
899 mTerm(1, AT_,
"Cannot add data in read-only mode!");
902#ifdef MAIA_EXTRA_DEBUG
903 m_unwrittenArrays.insert(name);
909 TERMM(1,
"Invalid name! Name must not be empty.");
912 TERMM(1,
"Invalid number of dimensions! Must at least be 1.");
915 derived().b_defineArray(type, datasetName, name, noDims, totalCount);
932template <
class Backend>
943 if(m_fileMode == PIO_READ) {
944 TERMM(1,
"Cannot add data in read-only mode!");
948 if(m_isHeaderSaved) {
949 TERMM(1,
"Cannot add new data after header was written!");
952#ifdef MAIA_EXTRA_DEBUG
953 m_unwrittenScalars.insert(name);
959 TERMM(1,
"Invalid name! Name must not be empty.");
962 derived().b_defineScalar(type, name);
1044template <
class Backend>
1050#ifdef DISABLE_OUTPUT
1057 if(m_fileMode == PIO_READ) {
1058 TERMM(1,
"Cannot write data in read-only mode!");
1062 if(!m_offsetsAreSet) {
1063 TERMM(1,
"Offsets have to be set before calling writeArray!");
1066#ifdef MAIA_EXTRA_DEBUG
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;
1073 m_writtenArrays.insert(name);
1074 if(m_unwrittenArrays.count(name)) {
1075 m_unwrittenArrays.erase(name);
1080 if(memoryStride != -1 && memoryStride <= 0) {
1081 TERMM(1,
"memoryStride must be greater than zero (or -1 to set automatically)!");
1083 if(diskStride != -1 && diskStride <= 0) {
1084 TERMM(1,
"diskStride must be greater than zero (or -1 to set automatically)!");
1086 if(array == 0 && m_localCount[0] > 0) {
1087 TERMM(1,
"Data pointer must point to a valid location (is: null pointer)!");
1092 if(memoryStride == -1) {
1093 actualMemoryStride = 1;
1095 actualMemoryStride = memoryStride;
1097 size_type actualDiskStride = (diskStride == -1) ? 1 : diskStride;
1100 if(!m_isHeaderSaved) {
1101 derived().b_saveHeader();
1102 m_isHeaderSaved =
true;
1106 const size_type noChunks = (m_noChunks == -1) ? 1 : m_noChunks;
1108 size_type noDims = getDatasetNoDims(name);
1115 localCount[0] = m_localCount[0];
1116 for(
MInt dimId = 1; dimId < noDims; dimId++) {
1117 localCount[dimId] = getArraySize(name, dimId);
1119 for(
MInt dimId = 0; dimId < noDims; dimId++) {
1120 offset[dimId] = m_offset[dimId];
1124 derived().b_writeArray(array, name, noDims, &offset[0], &localCount[0], actualMemoryStride, noChunks,
1202template <
class Backend>
1208#ifdef DISABLE_OUTPUT
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)!");
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)!");
1224 if(memoryStride == -1) {
1225 actualMemoryStride =
static_cast<size_type>(names.size());
1227 actualMemoryStride = memoryStride;
1229 size_type actualDiskStride = (diskStride == -1) ? 1 : diskStride;
1232 for(std::vector<MString>::size_type i = 0; i < names.size(); i++) {
1233 writeArray(array + i, names[i], actualMemoryStride, actualDiskStride);
1253template <
class Backend>
1262 derived().b_writeArray(array, path, name, noDims, offset, localCount, &ghost[0]);
1290template <
class Backend>
1301#ifdef DISABLE_OUTPUT
1308 if(m_fileMode == PIO_READ) {
1309 TERMM(1,
"Cannot write data in read-only mode!");
1312#ifdef MAIA_EXTRA_DEBUG
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;
1319 m_writtenArrays.insert(name);
1320 if(m_unwrittenArrays.count(name)) {
1321 m_unwrittenArrays.erase(name);
1326 if(!m_isHeaderSaved) {
1327 derived().b_saveHeader();
1328 m_isHeaderSaved =
true;
1332 if(array == 0 && localCount[0] > 0) {
1333 TERMM(1,
"Data pointer must point to a valid location (is: null pointer)!");
1337 derived().b_writeArray(array, path, name, noDims, offset, localCount, ghost);
1352template <
class Backend>
1357#ifdef DISABLE_OUTPUT
1364 if(m_fileMode == PIO_READ) {
1365 mTerm(1, AT_,
"Cannot write data in read-only mode!");
1370 const T localValue = scalar;
1374 m_mpiComm, AT_,
"localValue",
"globalValues[0]");
1377 if(m_domainId == 0) {
1378 for(
MInt i = 0; i < m_noDomains; i++) {
1381 if(globalValues[i] < localValue) {
1384 if(globalValues[i] > localValue) {
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) +
")");
1395#ifdef MAIA_EXTRA_DEBUG
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;
1402 m_writtenScalars.insert(name);
1403 if(m_unwrittenScalars.count(name)) {
1404 m_unwrittenScalars.erase(name);
1409 if(!m_isHeaderSaved) {
1410 derived().b_saveHeader();
1411 m_isHeaderSaved =
true;
1414 derived().b_writeScalar(scalar, name);
1436template <
class Backend>
1440 setAttributes(&value, name, 1, datasetName);
1444template <
class Backend>
1447 setAttributes(&tmpValue, name, 1, datasetName);
1450template <
class Backend>
1458#ifdef DISABLE_OUTPUT
1465 if(m_fileMode == PIO_READ) {
1466 mTerm(1, AT_,
"Cannot write data in read-only mode!");
1471 mTerm(1, AT_,
"Invalid name! Name must not be empty.");
1473 ASSERT(totalCount > 0,
"");
1475 derived().b_setAttribute(value, name, datasetName, totalCount);
1521template <
class Backend>
1527 if(!m_offsetsAreSet) {
1528 mTerm(1, AT_,
"Offsets have to be set before calling readArray!");
1531#ifdef MAIA_EXTRA_DEBUG
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;
1538 m_readArrays.insert(name);
1542 if(memoryStride != -1 && memoryStride <= 0) {
1543 mTerm(1, AT_,
"memoryStride must be greater than zero (or -1 to set automatically)!");
1545 if(diskStride != -1 && diskStride <= 0) {
1546 mTerm(1, AT_,
"diskStride must be greater than zero (or -1 to set automatically)!");
1548 if(array == 0 && m_localCount[0] > 0) {
1549 mTerm(1, AT_,
"Data pointer must point to a valid location (is: null pointer)!");
1554 if(memoryStride == -1) {
1555 actualMemoryStride = 1;
1557 actualMemoryStride = memoryStride;
1559 size_type actualDiskStride = (diskStride == -1) ? 1 : diskStride;
1562 const size_type noChunks = (m_noChunks == -1) ? 1 : m_noChunks;
1564 size_type noDims = getDatasetNoDims(name);
1569 localCount[0] = m_localCount[0];
1572 for(
MInt dimId = 1; dimId < noDims; dimId++) {
1573 localCount[dimId] = getArraySize(name, dimId);
1575 for(
MInt dimId = 0; dimId < noDims; dimId++) {
1576 offset[dimId] = m_offset[dimId];
1580 derived().b_readArray(array, name, noDims, &offset[0], &localCount[0], actualMemoryStride, noChunks,
1600template <
class Backend>
1610#ifdef MAIA_EXTRA_DEBUG
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;
1617 m_readArrays.insert(name);
1620 if(array == 0 && localCount[0] > 0) {
1621 mTerm(1, AT_,
"Data pointer must point to a valid location (is: null pointer)!");
1625 derived().b_readArray(array, datasetName, name, noDims, offset, localCount);
1643template <
class Backend>
1649#ifdef MAIA_EXTRA_DEBUG
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;
1656 m_readArrays.insert(name);
1659 if(array == 0 && localCount[0] > 0) {
1660 mTerm(1, AT_,
"Data pointer must point to a valid location (is: null pointer)!");
1667 derived().b_readArray(array, datasetName, name, noDims, &offset[0], localCount);
1709template <
class Backend>
1716 if(memoryStride != -1 && memoryStride <
static_cast<size_type>(names.size())) {
1718 "memoryStride must be greater than or equal to number of "
1719 "variables (or -1 to set automatically)!");
1721 if(diskStride != -1 && diskStride <
static_cast<size_type>(names.size())) {
1723 "diskStride must be greater than or equal to number of "
1724 "variables (or -1 to set automatically)!");
1729 if(memoryStride == -1) {
1730 actualMemoryStride =
static_cast<size_type>(names.size());
1732 actualMemoryStride = memoryStride;
1734 size_type actualDiskStride = (diskStride == -1) ? 1 : diskStride;
1737 for(std::vector<MString>::size_type i = 0; i < names.size(); i++) {
1738 readArray(array + i, names[i], actualMemoryStride, actualDiskStride);
1756template <
class Backend>
1759#ifdef MAIA_EXTRA_DEBUG
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;
1766 m_readScalars.insert(name);
1769 derived().b_readScalar(scalar, name);
1786template <
class Backend>
1790 getAttribute(value, name, 1, datasetName);
1793template <
class Backend>
1798 derived().b_getAttribute(value, name, datasetName, totalCount);
1801template <
class Backend>
1805 derived().b_getAttributeCount(name, totalCount, datasetName);
1839template <
class Backend>
1847 if(localCount < 0) {
1848 TERMM(1,
"The local size may not be less than zero (was:" + std::to_string(localCount) +
")!");
1851 TERMM(1,
"The offset may not be less than zero (was:" + std::to_string(offset) +
")!");
1854 TERMM(1,
"The number of dimensions must at least be one!");
1857 TERMM(1,
"The number of chunks may not be zero!");
1863 m_localCount.reserve(noDims);
1864 m_localCount.assign(noDims, -1);
1865 m_localCount[0] = localCount;
1871 m_offset.reserve(noDims);
1872 m_offset.assign(noDims, 0);
1873 m_offset[0] = offset;
1876 m_noChunks = noChunks;
1880 m_offsetsAreSet =
true;
1888template <
class Backend>
1892 setOffset(localCount, offset, noDims, -1);
1900template <
class Backend>
1904 setOffset(localCount, offset, 1, -1);
1926template <
class Backend>
1928 const MPI_Comm& mpiComm,
size_type* noChunks) {
1932 if(localCount < 0) {
1933 TERMM(1,
"The local size may not be less than zero (was:" + std::to_string(localCount) +
")!");
1937 MInt domainId, noDomains;
1938 MPI_Comm_rank(mpiComm, &domainId);
1939 MPI_Comm_size(mpiComm, &noDomains);
1942 MPI_Exscan(&localCount, offset, 1, s_mpiSizeType, MPI_SUM, mpiComm, AT_,
"localCount",
"offset");
1947 totalCount[0] = offset[0] + localCount;
1948 MPI_Bcast(totalCount, 1, s_mpiSizeType, (noDomains - 1), mpiComm, AT_,
"totalCount");
1952 if(localCount == 0) {
1957 if(noChunks !=
nullptr) {
1959 noChunks[0] = totalCount[0] / s_maxChunkSize;
1962 if(totalCount[0] % s_maxChunkSize > 0) {
1975template <
class Backend>
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.");
This class is intended to do all the heavy lifting when it comes to reading and writing "big data" fi...
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]
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).
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]
MBool hasDataset(const MString &name)
Check if the file contains an dataset with the given name.
ParallelIoBase(MString fileName, MInt fileMode, const MPI_Comm &mpiComm)
Creates a new object to read and write big data files. [MPI]
void setAttributes(const T *value, const MString &name, size_type totalCount, const MString &datasetName="")
MInt getDatasetType(const MString &name)
Returns the data type of an array.
void getAttribute(T *value, const MString &name, const size_type totalCount, const MString &datasetName="")
static const size_type s_maxChunkSize
void readScalar(T *scalar, const MString &name)
Read scalar data from file. [MPI]
MBool hasObject(const MString &path)
static const MPI_Datatype s_mpiSizeType
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.
static MBool fileExists(const MString &name, const MPI_Comm &mpiComm)
Check whether a file exists. [MPI]
void writeScalar(T scalar, const MString &name)
Write scalar data to file. [MPI]
std::set< MString > m_writtenScalars
std::set< MString > m_unwrittenScalars
void defineArray(maiabd_type type, const MString &name, size_type totalCount)
Create a new array in the file.
void validateType(const maiabd_type type) const
Auxiliary method that aborts MAIA if type is not a valid type constant for ParallelIo.
void writeArray(const T *array, const MString &name, size_type memoryStride=-1, size_type diskStride=-1)
Write array data to file. [MPI]
std::vector< MString > getGroupNames(const MString &path)
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]
size_type getDatasetNoDims(const MString &name, const MString &path)
MBool hasDataset(const MString &name, MInt dimension)
Check if the file contains an dataset with the given name and dimension.
void getAttribute(T *value, const MString &name, const MString &datasetName="")
Retrieve a file or dataset attribute.
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.
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]
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]
std::vector< size_type > m_offset
void defineArray(maiabd_type type, const MString &datasetName, const MString &name, size_type noDims, size_type *totalCount)
Creates new array in the file.
static MBool isParallelIoFile(const MString &name, const MPI_Comm &mpiComm)
Check if specified file is a valid ParallelIoHdf5 file. [MPI]
std::vector< MString > getDatasetNames(const MString &path)
std::set< MString > m_writtenArrays
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]
void defineScalar(maiabd_type type, const MString &name)
Create a new scalar in the file.
void defineArray(maiabd_type type, const std::vector< MString > &name, size_type totalCount)
Create multiple new arrays in the file.
MBool hasAttribute(const MString &name, const MString &path="")
Check if a given attribute exists in the file.
MLong size_type
Type used for all size- and offset-related values.
void readArray(std::vector< T > &array, const MString &name, size_type memoryStride=-1, size_type diskStride=-1)
std::vector< size_type > m_localCount
void setAttribute(const MChar *value, const MString &name, const MString &datasetName="")
void defineArray(maiabd_type type, const MString &name, size_type noDims, size_type *totalCount)
Create a new array in the file.
void getArraySize(const MString &name, const MString &path, size_type *datasetSize)
size_type getArraySize(const MString &name, const size_type dimensionId=0)
Get the length of an array in the file.
static MString fileExt()
Returns backend-specific ending of filename (either ".Netcdf" or ".Hdf5")
static void deleteFile(const MString &name)
Deletes the specified file. [MPI]
std::set< MString > m_readScalars
std::vector< size_type > getArrayDims(const MString &name)
Get the lengths of all dimensions of a dataset with given name.
std::set< MString > m_readArrays
void getAttributeCount(const MString &name, size_type *totalCount, const MString &datasetName="")
const Backend & derived() const
size_type getDatasetNoDims(const MString &name)
Get the number of dimensions of a dataset with given name.
void setOffset(size_type localCount, size_type offset)
Set the local and global counts, as well the local offset for array operations (overload).
MBool hasDataset(const MString &name, const MString &path)
maiabd_type getAttributeType(const MString &name, const MString &datasetName="")
Returns the data type of an attribute in the file.
std::set< MString > m_unwrittenArrays
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]
void setAttribute(const T &value, const MString &name, const MString &datasetName="")
Set a file or dataset attribute. [MPI]
void readArray(T *array, const MString &name, size_type memoryStride=-1, size_type diskStride=-1)
Read array data from file. [MPI]
maia::parallel_io::maiabd_type maiabd_type
Type used for all constants that are defined in maia::parallel_io.
virtual ~ParallelIoBase()
empty destructor. [MPI]
This class is a ScratchSpace.
void fill(T val)
fill the scratch with a given value
void mTerm(const MInt errorCode, const MString &location, const MString &message)
std::basic_string< char > MString
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
const MInt PIO_CREATE
< File mode to create a new file. Aborts if file already exists
Namespace for auxiliary functions/classes.
PARALLELIO_DEFAULT_BACKEND ParallelIo