File emulator_io.cpp
File List > common > src > emulator_io.cpp
Go to the documentation of this file
#include "emulator_io.hpp"
namespace emulator {
// Static member definitions
MPI_Comm EmulatorIO::s_comm = MPI_COMM_NULL;
int EmulatorIO::s_iosysid = -1;
bool EmulatorIO::s_initialized = false;
int EmulatorIO::s_rank = -1;
void EmulatorIO::initialize(MPI_Comm comm, const std::string &comp_name) {
(void)comp_name; // Currently unused
if (s_initialized) {
return;
}
s_comm = comm;
// Check if MPI communicator is valid
int nprocs = 1;
if (comm != MPI_COMM_NULL && comm != 0) {
MPI_Comm_rank(comm, &s_rank);
MPI_Comm_size(comm, &nprocs);
} else {
// Fallback for non-MPI runs or invalid comm
s_rank = 0;
return; // Cannot initialize PIO without valid MPI
}
// PIO initialization parameters
int stride = 1;
int base = 0;
int rearranger = PIO_REARR_SUBSET;
int ret =
PIOc_Init_Intracomm(comm, nprocs, stride, base, rearranger, &s_iosysid);
if (ret != PIO_NOERR) {
// Initialization failed - caller should handle gracefully
return;
}
s_initialized = true;
}
void EmulatorIO::finalize() {
if (!s_initialized) {
return;
}
if (s_iosysid >= 0) {
PIOc_finalize(s_iosysid);
s_iosysid = -1;
}
s_initialized = false;
}
int EmulatorIO::open_file(const std::string &filename) {
if (!s_initialized) {
return -1;
}
int ncid;
int iotype = PIO_IOTYPE_NETCDF;
int ret =
PIOc_openfile(s_iosysid, &ncid, &iotype, filename.c_str(), PIO_NOWRITE);
if (ret != PIO_NOERR) {
return -1;
}
return ncid;
}
int EmulatorIO::create_file(const std::string &filename) {
if (!s_initialized) {
return -1;
}
int ncid;
int iotype = PIO_IOTYPE_NETCDF;
int ret =
PIOc_createfile(s_iosysid, &ncid, &iotype, filename.c_str(), PIO_CLOBBER);
if (ret != PIO_NOERR) {
return -1;
}
return ncid;
}
void EmulatorIO::close_file(int ncid) {
if (ncid >= 0) {
PIOc_closefile(ncid);
}
}
void EmulatorIO::sync_file(int ncid) {
if (ncid >= 0) {
PIOc_sync(ncid);
}
}
bool EmulatorIO::read_var_1d(int ncid, const std::string &varname, double *data,
int size) {
int varid;
int ret = PIOc_inq_varid(ncid, varname.c_str(), &varid);
if (ret != PIO_NOERR) {
return false;
}
PIO_Offset start[1] = {0};
PIO_Offset count[1] = {static_cast<PIO_Offset>(size)};
ret = PIOc_get_vara_double(ncid, varid, start, count, data);
return (ret == PIO_NOERR);
}
bool EmulatorIO::read_var_2d(int ncid, const std::string &varname, double *data,
int nx, int ny) {
int varid;
int ret = PIOc_inq_varid(ncid, varname.c_str(), &varid);
if (ret != PIO_NOERR) {
return false;
}
PIO_Offset start[2] = {0, 0};
PIO_Offset count[2] = {static_cast<PIO_Offset>(ny),
static_cast<PIO_Offset>(nx)};
ret = PIOc_get_vara_double(ncid, varid, start, count, data);
return (ret == PIO_NOERR);
}
bool EmulatorIO::read_var_3d_slice(int ncid, const std::string &varname,
double *data, int nx, int ny, int time_idx) {
int varid;
int ret = PIOc_inq_varid(ncid, varname.c_str(), &varid);
if (ret != PIO_NOERR) {
return false;
}
// Read slice at time_idx from (time, lat, lon) array
PIO_Offset start[3] = {static_cast<PIO_Offset>(time_idx), 0, 0};
PIO_Offset count[3] = {1, static_cast<PIO_Offset>(ny),
static_cast<PIO_Offset>(nx)};
ret = PIOc_get_vara_double(ncid, varid, start, count, data);
return (ret == PIO_NOERR);
}
bool EmulatorIO::read_var_1d_int(int ncid, const std::string &varname,
int *data, int size) {
int varid;
int ret = PIOc_inq_varid(ncid, varname.c_str(), &varid);
if (ret != PIO_NOERR) {
return false;
}
PIO_Offset start[1] = {0};
PIO_Offset count[1] = {static_cast<PIO_Offset>(size)};
ret = PIOc_get_vara_int(ncid, varid, start, count, data);
return (ret == PIO_NOERR);
}
bool EmulatorIO::write_var_1d(int ncid, const std::string &varname,
const double *data, int size) {
int varid;
int ret = PIOc_inq_varid(ncid, varname.c_str(), &varid);
if (ret != PIO_NOERR) {
return false;
}
PIO_Offset start[1] = {0};
PIO_Offset count[1] = {static_cast<PIO_Offset>(size)};
ret = PIOc_put_vara_double(ncid, varid, start, count, data);
return (ret == PIO_NOERR);
}
bool EmulatorIO::write_var_2d(int ncid, const std::string &varname,
const double *data, int nx, int ny) {
int varid;
int ret = PIOc_inq_varid(ncid, varname.c_str(), &varid);
if (ret != PIO_NOERR) {
return false;
}
PIO_Offset start[2] = {0, 0};
PIO_Offset count[2] = {static_cast<PIO_Offset>(ny),
static_cast<PIO_Offset>(nx)};
ret = PIOc_put_vara_double(ncid, varid, start, count, data);
return (ret == PIO_NOERR);
}
int EmulatorIO::define_dim(int ncid, const std::string &dimname, int length) {
int dimid;
int ret = PIOc_def_dim(ncid, dimname.c_str(), length, &dimid);
return (ret == PIO_NOERR) ? dimid : -1;
}
int EmulatorIO::get_dim_size(int ncid, const std::string &dimname) {
int dimid;
int ret = PIOc_inq_dimid(ncid, dimname.c_str(), &dimid);
if (ret != PIO_NOERR) {
return -1;
}
PIO_Offset dimlen;
ret = PIOc_inq_dimlen(ncid, dimid, &dimlen);
return (ret == PIO_NOERR) ? static_cast<int>(dimlen) : -1;
}
bool EmulatorIO::has_var(int ncid, const std::string &varname) {
int varid;
return (PIOc_inq_varid(ncid, varname.c_str(), &varid) == PIO_NOERR);
}
int EmulatorIO::define_var(int ncid, const std::string &varname, int nctype,
const std::vector<int> &dimids) {
int varid;
int ret =
PIOc_def_var(ncid, varname.c_str(), nctype,
static_cast<int>(dimids.size()), dimids.data(), &varid);
return (ret == PIO_NOERR) ? varid : -1;
}
bool EmulatorIO::end_def(int ncid) {
int ret = PIOc_enddef(ncid);
return (ret == PIO_NOERR);
}
} // namespace emulator