23 #include "pism/util/io/PNCFile.hh"
25 #include "pism/util/io/pism_type_conversion.hh"
27 #include "pism/util/error_handling.hh"
28 #include "pism/util/pism_utilities.hh"
44 if (return_code != NC_NOERR) {
102 stat = ncmpi_def_dim(
m_file_id, name.c_str(), length, &dimid);
110 stat = ncmpi_inq_dimid(
m_file_id, dimension_name.c_str(), &tmp);
112 if (stat == NC_NOERR) {
121 int stat, dimid = -1;
124 stat = ncmpi_inq_dimid(
m_file_id, dimension_name.c_str(), &dimid);
127 stat = ncmpi_inq_dimlen(
m_file_id, dimid, &len);
130 result =
static_cast<unsigned int>(len);
135 int stat = NC_NOERR, dimid = -1;
136 char dimname[NC_MAX_NAME];
138 stat = ncmpi_inq_unlimdim(
m_file_id, &dimid);
144 stat = ncmpi_inq_dimname(
m_file_id, dimid, dimname);
152 const std::vector<std::string> &dims)
const {
153 std::vector<int> dimids;
156 for (
auto d : dims) {
158 stat = ncmpi_inq_dimid(
m_file_id, d.c_str(), &dimid);
160 dimids.push_back(dimid);
164 static_cast<int>(dims.size()), dimids.data(), &varid);
170 const std::vector<unsigned int> &start,
171 const std::vector<unsigned int> &
count,
double *ip)
const {
172 std::vector<unsigned int> dummy;
178 const std::vector<unsigned int> &start,
179 const std::vector<unsigned int> &
count,
const double *op)
const {
180 int stat, varid, ndims =
static_cast<int>(start.size());
182 std::vector<MPI_Offset> nc_start(ndims), nc_count(ndims), nc_stride(ndims);
184 stat = ncmpi_inq_varid(
m_file_id, variable_name.c_str(), &varid);
187 for (
int j = 0; j < ndims; ++j) {
188 nc_start[j] = start[j];
189 nc_count[j] =
count[j];
193 stat = ncmpi_put_vara_double_all(
m_file_id, varid, nc_start.data(), nc_count.data(), op);
199 const std::vector<unsigned int> &start,
200 const std::vector<unsigned int> &
count,
201 const std::vector<unsigned int> &imap,
double *ip)
const {
209 stat = ncmpi_inq_nvars(
m_file_id, &result);
215 std::vector<std::string> &result)
const {
216 int stat, ndims, varid = -1;
217 std::vector<int> dimids;
219 stat = ncmpi_inq_varid(
m_file_id, variable_name.c_str(), &varid);
222 stat = ncmpi_inq_varndims(
m_file_id, varid, &ndims);
230 result.resize(ndims);
231 dimids.resize(ndims);
233 stat = ncmpi_inq_vardimid(
m_file_id, varid, dimids.data());
236 for (
int k = 0;
k < ndims; ++
k) {
237 char name[NC_MAX_NAME];
238 memset(name, 0, NC_MAX_NAME);
240 stat = ncmpi_inq_dimname(
m_file_id, dimids[
k], name);
248 if (variable_name ==
"PISM_GLOBAL") {
253 int stat = ncmpi_inq_varid(
m_file_id, variable_name.c_str(), &varid);
269 stat = ncmpi_inq_varid(
m_file_id, variable_name.c_str(), &flag);
271 exists = (stat == NC_NOERR);
277 char varname[NC_MAX_NAME];
278 memset(varname, 0, NC_MAX_NAME);
280 stat = ncmpi_inq_varname(
m_file_id, j, varname);
287 std::vector<double> &result)
const {
288 int len, varid =
get_varid(variable_name);
289 MPI_Offset attlen = 0;
292 int stat = ncmpi_inq_attlen(
m_file_id, varid, att_name.c_str(), &attlen);
294 if (stat == NC_NOERR) {
295 len =
static_cast<int>(attlen);
296 }
else if (stat == NC_ENOTATT) {
311 stat = ncmpi_get_att_double(
m_file_id, varid, att_name.c_str(), result.data());
315 if (stat != NC_NOERR) {
316 fprintf(stderr,
"Error reading the %s attribute; (varid %d, NetCDF error %s)", att_name.c_str(),
317 varid, ncmpi_strerror(stat));
323 std::string &result)
const {
327 MPI_Offset attlen = 0;
329 int stat = ncmpi_inq_attlen(
m_file_id, varid, att_name.c_str(), &attlen);
330 int len = (stat == NC_NOERR) ?
static_cast<int>(attlen) : 0;
338 std::vector<char> str(len + 1, 0);
341 stat = ncmpi_get_att_text(
m_file_id, varid, att_name.c_str(), str.data());
353 io::Type nctype,
const std::vector<double> &data)
const {
355 int stat = ncmpi_put_att_double(
m_file_id,
get_varid(variable_name), att_name.c_str(),
362 const std::string &value)
const {
363 int stat = ncmpi_put_att_text(
m_file_id,
get_varid(variable_name), att_name.c_str(), value.size(),
370 std::string &result)
const {
372 char name[NC_MAX_NAME];
373 memset(name, 0, NC_MAX_NAME);
377 stat = ncmpi_inq_attname(
m_file_id, varid,
n, name);
388 nc_type tmp = NC_NAT;
389 int stat = ncmpi_inq_atttype(
m_file_id, varid, att_name.c_str(), &tmp);
390 if (stat == NC_ENOTATT) {
401 int stat = ncmpi_set_fill(
m_file_id, fillmode, &old_modep);
407 const std::vector<unsigned int> &start,
408 const std::vector<unsigned int> &
count,
409 const std::vector<unsigned int> &imap_input,
double *ip,
410 bool transposed)
const {
411 std::vector<unsigned int> imap = imap_input;
412 int stat, varid, ndims =
static_cast<int>(start.size());
414 if (not transposed) {
418 std::vector<MPI_Offset> nc_start(ndims), nc_count(ndims), nc_imap(ndims), nc_stride(ndims);
420 stat = ncmpi_inq_varid(
m_file_id, variable_name.c_str(), &varid);
423 for (
int j = 0; j < ndims; ++j) {
424 nc_start[j] = start[j];
425 nc_count[j] =
count[j];
426 nc_imap[j] = imap[j];
431 stat = ncmpi_get_varm_double_all(
m_file_id, varid, nc_start.data(), nc_count.data(),
432 nc_stride.data(), nc_imap.data(), ip);
435 stat = ncmpi_get_vara_double_all(
m_file_id, varid,
436 nc_start.data(), nc_count.data(),
445 auto words =
split(hint,
':');
447 if (words.size() == 2) {
452 const_cast<char*
>(words[0].c_str()),
453 const_cast<char*
>(words[1].c_str()));
456 MPI_Comm_rank(
m_com, &rank);
458 printf(
"PISM WARNING: invalid MPI I/O hint: %s. Ignoring it...\n",
The PISM wrapper for a subset of the NetCDF C API.
void def_dim_impl(const std::string &name, size_t length) const
void inq_unlimdim_impl(std::string &result) const
void get_vara_double_impl(const std::string &variable_name, const std::vector< unsigned int > &start, const std::vector< unsigned int > &count, double *ip) const
void inq_varid_impl(const std::string &variable_name, bool &exists) const
void get_varm_double_impl(const std::string &variable_name, const std::vector< unsigned int > &start, const std::vector< unsigned int > &count, const std::vector< unsigned int > &imap, double *ip) const
void inq_varname_impl(unsigned int j, std::string &result) const
void inq_dimid_impl(const std::string &dimension_name, bool &exists) const
void inq_nvars_impl(int &result) const
void del_att_impl(const std::string &variable_name, const std::string &att_name) const
void put_vara_double_impl(const std::string &variable_name, const std::vector< unsigned int > &start, const std::vector< unsigned int > &count, const double *op) const
void inq_varnatts_impl(const std::string &variable_name, int &result) const
void inq_dimlen_impl(const std::string &dimension_name, unsigned int &result) const
std::vector< std::string > m_mpi_io_hints
void put_att_double_impl(const std::string &variable_name, const std::string &att_name, io::Type xtype, const std::vector< double > &data) const
void inq_attname_impl(const std::string &variable_name, unsigned int n, std::string &result) const
void inq_atttype_impl(const std::string &variable_name, const std::string &att_name, io::Type &result) const
void inq_vardimid_impl(const std::string &variable_name, std::vector< std::string > &result) const
void get_att_text_impl(const std::string &variable_name, const std::string &att_name, std::string &result) const
void get_var_double(const std::string &variable_name, const std::vector< unsigned int > &start, const std::vector< unsigned int > &count, const std::vector< unsigned int > &imap, double *ip, bool transposed) const
void set_fill_impl(int fillmode, int &old_modep) const
void set_compression_level_impl(int level) const
void create_impl(const std::string &filename)
void get_att_double_impl(const std::string &variable_name, const std::string &att_name, std::vector< double > &result) const
int get_varid(const std::string &variable_name) const
void open_impl(const std::string &filename, io::Mode mode)
void put_att_text_impl(const std::string &variable_name, const std::string &att_name, const std::string &value) const
void def_var_impl(const std::string &name, io::Type nctype, const std::vector< std::string > &dims) const
#define PISM_ERROR_LOCATION
@ PISM_READONLY
open an existing file for reading only
static void check(const ErrorLocation &where, int return_code)
Prints an error message; for debugging.
std::string printf(const char *format,...)
static pism::io::Type nc_type_to_pism_type(int input)
static nc_type pism_type_to_nc_type(pism::io::Type input)
std::vector< std::string > split(const std::string &input, char separator)
Transform a separator-separated list (a string) into a vector of strings.