Newer
Older
#include "GenericIO.h"
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <cstdint>
#include <optional>
#include <stdexcept>
#ifndef GENERICIO_NO_MPI
#include <mpi.h>
#endif
namespace py = pybind11;
class PyGenericIO : public gio::GenericIO {
public:
PyGenericIO(
const std::string& filename,
gio::GenericIO::FileIO method=gio::GenericIO::FileIOPOSIX,
gio::GenericIO::MismatchBehavior redistribute=gio::GenericIO::MismatchRedistribute,
int eff_rank = -1)
#ifdef GENERICIO_NO_MPI
: gio::GenericIO(filename, method), num_ranks(0) {
#else
: gio::GenericIO(MPI_COMM_WORLD, filename, method), num_ranks(0) {
#endif
// open headers and rank info
openAndReadHeader(redistribute, eff_rank);
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
num_ranks = readNRanks();
// read variable info
getVariableInfo(variables);
}
void inspect() {
int rank;
#ifdef GENERICIO_NO_MPI
rank = 0;
#else
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
#endif
if(rank == 0) {
std::stringstream s;
s << "Number of Elements: " << readNumElems() << "\n";
s << "Total number of Elements: " << readTotalNumElems() << "\n";
s << "[data type] Variable name\n";
s << "---------------------------------------------\n";
for (int i = 0; i < variables.size(); ++i) {
gio::GenericIO::VariableInfo vinfo = variables[i];
if (vinfo.IsFloat)
s << "[f";
else
s << "[i";
int NumElements = vinfo.Size / vinfo.ElementSize;
s << " " << vinfo.ElementSize * 8;
if (NumElements > 1)
s << "x" << NumElements;
s << "] ";
s << vinfo.Name << "\n";
}
s << "\n(i=integer,f=floating point, number bits size)\n";
py::print(s.str());
}
}
std::vector<std::string> read_variable_names() {
std::vector<std::string> variable_names;
for(const auto& v: variables) {
variable_names.push_back(v.Name);
}
return variable_names;
}
std::map<std::string, py::dtype> read_variable_dtypes() {
std::map<std::string, py::dtype> variable_dtypes;
for(const auto& var: variables) {
auto var_name = var.Name;
if(var.IsFloat && var.ElementSize == 4)
variable_dtypes[var_name] = py::dtype("f4");
else if(var.IsFloat && var.ElementSize == 8)
variable_dtypes[var_name] = py::dtype("f8");
else if(!var.IsFloat && var.ElementSize == 4)
variable_dtypes[var_name] = py::dtype("i4");
else if(!var.IsFloat && var.ElementSize == 8)
variable_dtypes[var_name] = py::dtype("i8");
else if(!var.IsFloat && var.ElementSize == 2)
variable_dtypes[var_name] = py::dtype("u2");
else
throw std::runtime_error(std::string("Unknown data type in GenericIO for variable ") + var_name);
}
return variable_dtypes;
}
std::optional<std::vector<std::string>> var_names,
bool print_stats=true,
bool collective_stats=true,
int eff_rank=-1
int rank;
#ifdef GENERICIO_NO_MPI
rank = 0;
#else
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
#endif
int64_t num_elem = readNumElems(eff_rank);
// if no argument, read all
if(!var_names.has_value()) {
var_names.emplace(read_variable_names());
}
clearVariables();
std::map<std::string, py::array> result;
for(const std::string& var_name: *var_names) {
// check if it's not already defined (caused some segfaults at some point)
if(result.count(var_name)) {
throw std::invalid_argument(std::string("variable name was passed multiple times: ") + var_name);
}
variables.begin(),
variables.end(),
[&var_name](const auto& v){ return v.Name == var_name; }
);
if (varp != variables.end()) {
// extra space
py::ssize_t readsize = num_elem + requestedExtraSpace()/(*varp).ElementSize;
// py::array_t constructor: (shape, stride) -> some compilers or numpy
// versions require stride to be explicitly specified
if((*varp).IsFloat && (*varp).ElementSize == 4) {
result[var_name] = py::array_t<float>({readsize}, {4});
addVariable(*varp, result[var_name].mutable_data(), gio::GenericIO::VarHasExtraSpace);
} else if((*varp).IsFloat && (*varp).ElementSize == 8) {
result[var_name] = py::array_t<double>({readsize}, {8});
addVariable(*varp, result[var_name].mutable_data(), gio::GenericIO::VarHasExtraSpace);
} else if(!(*varp).IsFloat && (*varp).ElementSize == 4) {
result[var_name] = py::array_t<int32_t>({readsize}, {4});
addVariable(*varp, result[var_name].mutable_data(), gio::GenericIO::VarHasExtraSpace);
} else if(!(*varp).IsFloat && (*varp).ElementSize == 8) {
result[var_name] = py::array_t<int64_t>({readsize}, {8});
addVariable(*varp, result[var_name].mutable_data(), gio::GenericIO::VarHasExtraSpace);
} else if(!(*varp).IsFloat && (*varp).ElementSize == 2) {
result[var_name] = py::array_t<uint16_t>({readsize}, {2});
addVariable(*varp, result[var_name].mutable_data(), gio::GenericIO::VarHasExtraSpace);
throw std::runtime_error(std::string("unknown data type in GenericIO for variable: ") + var_name);
} else { // variable not found
throw std::invalid_argument(std::string("requested variable is not defined in GenericIO file: ") + var_name);
readData(eff_rank, print_stats, collective_stats);
clearVariables();
#ifndef GENERICIO_NO_MPI
MPI_Barrier(MPI_COMM_WORLD);
#endif
// get rid of extraspace
std::for_each(result.begin(), result.end(), [&](auto& item){ item.second.resize({num_elem}); });
return result;
}
const std::vector<VariableInfo> &get_variables() {
return variables;
}
std::array<double, 3> read_phys_origin() {
std::array<double, 3> origin;
readPhysOrigin(origin.data());
return origin;
}
std::array<double, 3> read_phys_scale() {
std::array<double, 3> scale;
readPhysScale(scale.data());
return scale;
}
std::vector<int> get_source_ranks() {
std::vector<int> sr;
getSourceRanks(sr);
return sr;
}
std::array<int, 3> read_dims() {
std::array<int, 3> sd;
readDims(sd.data());
return sd;
}
std::array<int, 3> read_coords(int eff_rank=-1) {
std::array<int, 3> sc;
readCoords(sc.data(), eff_rank);
return sc;
}
std::vector<VariableInfo> variables;

Michael Buehlmann
committed
std::map<std::string, py::array> read_genericio(
std::string filename,
std::optional<std::vector<std::string>> var_names,
PyGenericIO::FileIO method=PyGenericIO::FileIO::FileIOPOSIX,
PyGenericIO::MismatchBehavior redistribute=PyGenericIO::MismatchBehavior::MismatchRedistribute,
bool print_stats=true,
bool collective_stats=true,

Michael Buehlmann
committed
) {
PyGenericIO reader(filename, method, redistribute, eff_rank);
return reader.read(var_names, print_stats, collective_stats, eff_rank);

Michael Buehlmann
committed
void inspect_genericio(
std::string filename,
PyGenericIO::FileIO method=PyGenericIO::FileIO::FileIOPOSIX,

Michael Buehlmann
committed
PyGenericIO::MismatchBehavior redistribute=PyGenericIO::MismatchBehavior::MismatchRedistribute
) {
PyGenericIO reader(filename, method, redistribute);
reader.inspect();
}
std::array<double, 3> read_phys_scale(
std::string filename,
PyGenericIO::FileIO method=PyGenericIO::FileIO::FileIOPOSIX,
PyGenericIO::MismatchBehavior redistribute=PyGenericIO::MismatchBehavior::MismatchRedistribute
) {
PyGenericIO reader(filename, method, redistribute);
return reader.read_phys_scale();
}
std::array<double, 3> read_phys_origin(
std::string filename,
PyGenericIO::FileIO method=PyGenericIO::FileIO::FileIOPOSIX,
PyGenericIO::MismatchBehavior redistribute=PyGenericIO::MismatchBehavior::MismatchRedistribute
) {
PyGenericIO reader(filename, method, redistribute);
return reader.read_phys_origin();
}
std::array<int, 3> read_dims(
std::string filename,
PyGenericIO::FileIO method=PyGenericIO::FileIO::FileIOPOSIX,
PyGenericIO::MismatchBehavior redistribute=PyGenericIO::MismatchBehavior::MismatchRedistribute
) {
PyGenericIO reader(filename, method, redistribute);
return reader.read_dims();
}
std::array<int, 3> read_coords(
std::string filename,
PyGenericIO::FileIO method=PyGenericIO::FileIO::FileIOPOSIX,
PyGenericIO::MismatchBehavior redistribute=PyGenericIO::MismatchBehavior::MismatchRedistribute,
int eff_rank=-1
) {
PyGenericIO reader(filename, method, redistribute);
return reader.read_coords(eff_rank);
}
std::vector<std::string> read_variable_names(
std::string filename,
PyGenericIO::FileIO method=PyGenericIO::FileIO::FileIOPOSIX,
PyGenericIO::MismatchBehavior redistribute=PyGenericIO::MismatchBehavior::MismatchRedistribute
) {
PyGenericIO reader(filename, method, redistribute);
return reader.read_variable_names();
}
std::map<std::string, py::dtype> read_variable_dtypes(
std::string filename,
PyGenericIO::FileIO method=PyGenericIO::FileIO::FileIOPOSIX,
PyGenericIO::MismatchBehavior redistribute=PyGenericIO::MismatchBehavior::MismatchRedistribute
) {
PyGenericIO reader(filename, method, redistribute);
return reader.read_variable_dtypes();
}
int64_t read_num_elems(
std::string filename,
PyGenericIO::FileIO method=PyGenericIO::FileIO::FileIOPOSIX,
PyGenericIO::MismatchBehavior redistribute=PyGenericIO::MismatchBehavior::MismatchRedistribute,
int eff_rank=-1
) {
PyGenericIO reader(filename, method, redistribute);
return reader.readNumElems(eff_rank);
}
int64_t read_total_num_elems(
std::string filename,
PyGenericIO::FileIO method=PyGenericIO::FileIO::FileIOPOSIX,
PyGenericIO::MismatchBehavior redistribute=PyGenericIO::MismatchBehavior::MismatchRedistribute
) {
PyGenericIO reader(filename, method, redistribute);
return reader.readTotalNumElems();
}

Michael Buehlmann
committed
void write_genericio(
std::string filename,
std::map<std::string, py::array> variables,
std::array<double, 3> phys_scale, std::array<double, 3> phys_origin,

Michael Buehlmann
committed
PyGenericIO::FileIO method=PyGenericIO::FileIO::FileIOPOSIX
) {
// check data integrity, find particle count
int64_t particle_count = -1;
for(auto const& [name, data]: variables) {
if(data.ndim() != 1) {
throw std::runtime_error("dimension of array must be 1 (" + name + ")");
}
if(particle_count == -1) {
particle_count = data.size();
} else if(particle_count != data.size()) {
throw std::runtime_error("arrays do not have same length (" + name + ")");
}
}
gio::GenericIO writer(MPI_COMM_WORLD, filename, method);
writer.setNumElems(particle_count);
// set size
for (int d = 0; d < 3; ++d) {
writer.setPhysOrigin(phys_origin[d], d);
writer.setPhysScale(phys_scale[d], d);
}
for(auto& [name, data]: variables) {
if(py::isinstance<py::array_t<float>>(data))
writer.addVariable(name.c_str(), reinterpret_cast<float*>(data.mutable_data()));
else if(py::isinstance<py::array_t<double>>(data))
writer.addVariable(name.c_str(), reinterpret_cast<double*>(data.mutable_data()));
else if(py::isinstance<py::array_t<int32_t>>(data))
writer.addVariable(name.c_str(), reinterpret_cast<int32_t*>(data.mutable_data()));
else if(py::isinstance<py::array_t<int64_t>>(data))
writer.addVariable(name.c_str(), reinterpret_cast<int64_t*>(data.mutable_data()));
else if(py::isinstance<py::array_t<uint16_t>>(data))
writer.addVariable(name.c_str(), reinterpret_cast<uint16_t*>(data.mutable_data()));
else
throw std::runtime_error("array dtype not supported for " + name);
}
writer.write();
MPI_Barrier(MPI_COMM_WORLD);
}
#endif

Michael Buehlmann
committed
#ifdef GENERICIO_NO_MPI
PYBIND11_MODULE(pygio_nompi_impl, m) {

Michael Buehlmann
committed
m.doc() = "genericio python module (no MPI support)";
#else // GENERICIO_NO_MPI
PYBIND11_MODULE(pygio_impl, m) {

Michael Buehlmann
committed
m.doc() = "genericio python module (with MPI support)";
m.def("_init_mpi", [](){
int initialized;
MPI_Initialized(&initialized);
MPI_Init_thread(nullptr, nullptr, MPI_THREAD_SINGLE, &level_provided);
#endif
py::class_<PyGenericIO> pyGenericIO(m, "PyGenericIO");
py::enum_<PyGenericIO::FileIO>(pyGenericIO, "FileIO")
.value("FileIOMPI", PyGenericIO::FileIO::FileIOMPI)
.value("FileIOPOSIX", PyGenericIO::FileIO::FileIOPOSIX)
.value("FileIOMPICollective", PyGenericIO::FileIO::FileIOMPICollective);
py::enum_<PyGenericIO::MismatchBehavior>(pyGenericIO, "MismatchBehavior")
.value("MismatchAllowed", PyGenericIO::MismatchBehavior::MismatchAllowed)
.value("MismatchDisallowed", PyGenericIO::MismatchBehavior::MismatchDisallowed)
.value("MismatchRedistribute", PyGenericIO::MismatchBehavior::MismatchRedistribute);

Michael Buehlmann
committed
pyGenericIO.def(
py::init<std::string, PyGenericIO::FileIO, PyGenericIO::MismatchBehavior>(),
py::arg("filename"),
py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX,

Michael Buehlmann
committed
py::arg("redistribute")=PyGenericIO::MismatchBehavior::MismatchRedistribute)
.def("inspect", &PyGenericIO::inspect, "Print variable infos and size of GenericIO file")
.def("get_variables", &PyGenericIO::get_variables, "Get a list of VariableInformations defined in the GenericIO file")
.def("read_num_elems", (size_t (PyGenericIO::*)(int))(&PyGenericIO::readNumElems), py::arg("eff_rank")=-1)
.def("read_total_num_elems", (uint64_t (PyGenericIO::*)(void))(&PyGenericIO::readTotalNumElems))
.def("read_phys_origin", &PyGenericIO::read_phys_origin)
.def("read_phys_scale", &PyGenericIO::read_phys_scale)
.def("read_dims", &PyGenericIO::read_dims)
.def("read_coords", &PyGenericIO::read_coords)
.def("read", &PyGenericIO::read,
py::arg("variables")=nullptr,
py::kw_only(),
py::arg("print_stats")=true,
py::arg("collective_stats")=true,
py::arg("eff_rank")=-1)
.def("read_nranks", (int (PyGenericIO::*)(void))(&PyGenericIO::readNRanks))
.def("read_variable_names", &PyGenericIO::read_variable_names)
.def("has_variable", &PyGenericIO::hasVariable)
.def("read_variable_dtypes", &PyGenericIO::read_variable_dtypes)
.def("get_source_ranks", &PyGenericIO::getSourceRanks)
.def_static("setDefaultShouldCompress", &PyGenericIO::setDefaultShouldCompress)
.def_static("setNaturalDefaultPartition", &PyGenericIO::setNaturalDefaultPartition)
.def_static("setDefaultFileIOType", &PyGenericIO::setDefaultFileIOType)

Michael Buehlmann
committed
#ifndef GENERICIO_NO_MPI
.def_static("setCollectiveMPIIOThreshold", &PyGenericIO::setCollectiveMPIIOThreshold)

Michael Buehlmann
committed
#endif
;
py::class_<PyGenericIO::VariableInfo>(pyGenericIO, "VariableInfo")
.def_readonly("name", &gio::GenericIO::VariableInfo::Name)
.def_readonly("size", &gio::GenericIO::VariableInfo::Size)
.def_readonly("element_size", &gio::GenericIO::VariableInfo::ElementSize)
.def_readonly("is_float", &gio::GenericIO::VariableInfo::IsFloat)
.def("__repr__", [](const gio::GenericIO::VariableInfo &vi) {
return std::string("<PyGenericIO.VariableInfo type=") +
(vi.IsFloat ? "float" : "int") + " name='" + vi.Name + "'>";
});

Michael Buehlmann
committed
m.def("read_genericio", &read_genericio, R"Delim(
Read data from a GenericIO file
Parameters
----------
filename: str
path to the GenericIO file
variables: List[str]
A list of variable names that should be read. If ``None``, all
variables contained in the file will be read
method: PyGenericIO.FileIO
file handling method (POSIX/MPI)
redistribute: PyGenericIO.MismatchBehavior
whether to allow mismatching ranks
print_stats: bool
if ``True``, print throughput statistics after reading
collective_stats: bool
if ``True``, aggregate statistics among reading ranks (if using MPI)
eff_rank: int
if -1, use the MPI rank of the calling process (or redistribute if
redistribute is set to MismatchRedistribute). Otherwise, use the
specified rank (if using MPI).
Returns
-------
data: Mapping[str, np.ndarray]
)Delim",
py::arg("filename"),
py::arg("variables")=nullptr,

Michael Buehlmann
committed
py::kw_only(),
py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX,
py::arg("redistribute")=PyGenericIO::MismatchBehavior::MismatchRedistribute,
py::arg("print_stats")=true,
py::arg("collective_stats")=true,
py::arg("eff_rank")=-1,

Michael Buehlmann
committed
py::return_value_policy::move);
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
m.def("inspect_genericio", &inspect_genericio, R"Delim(
Print a summary of variables and types defined in the GenericIO file
Parameters
----------
filename: str
path to the GenericIO file
method: PyGenericIO.FileIO
file handling method (POSIX/MPI)
redistribute: PyGenericIO.MismatchBehavior
whether to allow mismatching ranks
)Delim",
py::arg("filename"),
py::kw_only(),
py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX,
py::arg("redistribute")=PyGenericIO::MismatchBehavior::MismatchRedistribute);
m.def("read_num_elems", &read_num_elems, R"Delim(
Read the (local) number of objects (the number of objects that would be
read by this rank when calling :func:`read_genericio`)
Parameters
----------
filename: str
path to the GenericIO file
method: PyGenericIO.FileIO
file handling method (POSIX/MPI)
redistribute: PyGenericIO.MismatchBehavior
whether to allow mismatching ranks
eff_rank: int
if -1, use the MPI rank of the calling process (or redistribute if
redistribute is set to MismatchRedistribute). Otherwise, use the
specified rank (if using MPI).
Returns
-------
nlocal: int
the number of objects assigned to this rank
)Delim",
py::arg("filename"),
py::kw_only(),
py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX,
py::arg("redistribute")=PyGenericIO::MismatchBehavior::MismatchRedistribute,
py::arg("eff_rank")=-1);
m.def("read_total_num_elems", &read_total_num_elems, R"Delim(
Read the total number of objects (the number of objects that would be
read by all ranks combined when calling :func:`read_genericio`)
Parameters
----------
filename: str
path to the GenericIO file
method: PyGenericIO.FileIO
file handling method (POSIX/MPI)
redistribute: PyGenericIO.MismatchBehavior
whether to allow mismatching ranks
Returns
-------
ntotal: int
the total number of objects stored in the GenericIO file
)Delim",
py::arg("filename"),

Michael Buehlmann
committed
py::kw_only(),
py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX,

Michael Buehlmann
committed
py::arg("redistribute")=PyGenericIO::MismatchBehavior::MismatchRedistribute);
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
m.def("read_variable_names", &read_variable_names, R"Delim(
Get a list of variable names stored in the GenericIO file
Parameters
----------
filename: str
path to the GenericIO file
method: PyGenericIO.FileIO
file handling method (POSIX/MPI)
redistribute: PyGenericIO.MismatchBehavior
whether to allow mismatching ranks
Returns
-------
variable_names: List[str]
the list of variable names defined in the GenericIO file
)Delim",
py::arg("filename"),
py::kw_only(),
py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX,
py::arg("redistribute")=PyGenericIO::MismatchBehavior::MismatchRedistribute);
m.def("read_variable_dtypes", &read_variable_dtypes, R"Delim(
Get a dictionary of dtypes mapped to the variable names
Parameters
----------
filename: str
path to the GenericIO file
method: PyGenericIO.FileIO
file handling method (POSIX/MPI)
redistribute: PyGenericIO.MismatchBehavior
whether to allow mismatching ranks
Returns
-------
variable_dtypes: Mapping[str, np.dtype]
a map ``variable_name -> dtype`` for each variable in the GenericIO file
)Delim",
py::arg("filename"),
py::kw_only(),
py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX,
py::arg("redistribute")=PyGenericIO::MismatchBehavior::MismatchRedistribute);
m.def("read_phys_scale", &read_phys_scale, R"Delim(
Read the box size that is stored in the GenericIO file
Parameters
----------
filename: str
path to the GenericIO file
method: PyGenericIO.FileIO
file handling method (POSIX/MPI)
redistribute: PyGenericIO.MismatchBehavior
whether to allow mismatching ranks
Returns
-------
phys_scale: List[float]
the box length for each dimension (3 elements long)
)Delim",
py::arg("filename"),
py::kw_only(),
py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX,
py::arg("redistribute")=PyGenericIO::MismatchBehavior::MismatchRedistribute);
m.def("read_phys_origin", &read_phys_scale, R"Delim(
Read the origin / reference point of the box that is stored in the GenericIO file
Parameters
----------
filename: str
path to the GenericIO file
method: PyGenericIO.FileIO
file handling method (POSIX/MPI)
redistribute: PyGenericIO.MismatchBehavior
whether to allow mismatching ranks
Returns
-------
phys_origin: List[float]
the box origin coordinates (3 elements long)
)Delim",
py::arg("filename"),
py::kw_only(),
py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX,
py::arg("redistribute")=PyGenericIO::MismatchBehavior::MismatchRedistribute);
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
m.def("read_dims", &read_dims, R"Delim(
Read the topological decomposition of the box that is stored in the GenericIO file
Parameters
----------
filename: str
path to the GenericIO file
method: PyGenericIO.FileIO
file handling method (POSIX)
redistribute: PyGenericIO.MismatchBehavior
whether to allow mismatching ranks
Returns
-------
dims: List[int]
the box decomposition (3 elements long)
)Delim",
py::arg("filename"),
py::kw_only(),
py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX,
py::arg("redistribute")=PyGenericIO::MismatchBehavior::MismatchRedistribute);
m.def("read_coords", &read_coords, R"Delim(
Read the rank coordinates of the source_rank this rank is reading
Parameters
----------
filename: str
path to the GenericIO file
method: PyGenericIO.FileIO
file handling method (POSIX)
redistribute: PyGenericIO.MismatchBehavior
whether to allow mismatching ranks
eff_rank: int
if -1, use the MPI rank of the calling process (or redistribute if
redistribute is set to MismatchRedistribute). Otherwise, use the
specified rank (if using MPI).
Returns
-------
coords: List[int]
the rank coordinates (3 elements long)
Note
----
If eff_rank == -1 and redistribute is enabled, the rank coordinates
will be [0, 0, 0]
)Delim",
py::arg("filename"),
py::kw_only(),
py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX,
py::arg("redistribute")=PyGenericIO::MismatchBehavior::MismatchRedistribute,
py::arg("eff_rank")=-1);
m.def("write_genericio", &write_genericio, R"Delim(
Write data as a GenericIO file
Parameters
----------
filename: str
path to the GenericIO file
data: Mapping[str, np.ndarray]
a dictionary, with all items being 1-dimensional numpy arrays of
the same length. Currently, only float32, float64, int32, int64 and
uint16 data types are supported
phys_scale: List[float]
the physical size of the box that the data belongs to (3 elements)
phys_origin: List[float]
the origin coordinates of the box that the data belongs to (3 elements)
method: PyGenericIO.FileIO
file handling method (POSIX/MPI)
)Delim",
py::arg("filename"),
py::arg("phys_scale"),
py::arg("phys_origin") = std::array<double, 3>({0., 0., 0.}),

Michael Buehlmann
committed
py::kw_only(),
py::arg("method")=PyGenericIO::FileIO::FileIOPOSIX);