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 {
177 const std::vector<unsigned int> &start,
178 const std::vector<unsigned int> &
count,
const double *op)
const {
179 int stat, varid, ndims =
static_cast<int>(start.size());
181 std::vector<MPI_Offset> nc_start(ndims), nc_count(ndims);
183 stat = ncmpi_inq_varid(
m_file_id, variable_name.c_str(), &varid);
186 for (
int j = 0; j < ndims; ++j) {
187 nc_start[j] = start[j];
188 nc_count[j] =
count[j];
191 stat = ncmpi_put_vara_double_all(
m_file_id, varid, nc_start.data(), nc_count.data(), op);
198 stat = ncmpi_inq_nvars(
m_file_id, &result);
204 std::vector<std::string> &result)
const {
205 int stat, ndims, varid = -1;
206 std::vector<int> dimids;
208 stat = ncmpi_inq_varid(
m_file_id, variable_name.c_str(), &varid);
211 stat = ncmpi_inq_varndims(
m_file_id, varid, &ndims);
219 result.resize(ndims);
220 dimids.resize(ndims);
222 stat = ncmpi_inq_vardimid(
m_file_id, varid, dimids.data());
225 for (
int k = 0;
k < ndims; ++
k) {
226 char name[NC_MAX_NAME];
227 memset(name, 0, NC_MAX_NAME);
229 stat = ncmpi_inq_dimname(
m_file_id, dimids[
k], name);
237 if (variable_name ==
"PISM_GLOBAL") {
242 int stat = ncmpi_inq_varid(
m_file_id, variable_name.c_str(), &varid);
258 stat = ncmpi_inq_varid(
m_file_id, variable_name.c_str(), &flag);
260 exists = (stat == NC_NOERR);
266 char varname[NC_MAX_NAME];
267 memset(varname, 0, NC_MAX_NAME);
269 stat = ncmpi_inq_varname(
m_file_id, j, varname);
276 std::vector<double> &result)
const {
277 int len, varid =
get_varid(variable_name);
278 MPI_Offset attlen = 0;
281 int stat = ncmpi_inq_attlen(
m_file_id, varid, att_name.c_str(), &attlen);
283 if (stat == NC_NOERR) {
284 len =
static_cast<int>(attlen);
285 }
else if (stat == NC_ENOTATT) {
300 stat = ncmpi_get_att_double(
m_file_id, varid, att_name.c_str(), result.data());
304 if (stat != NC_NOERR) {
305 fprintf(stderr,
"Error reading the %s attribute; (varid %d, NetCDF error %s)", att_name.c_str(),
306 varid, ncmpi_strerror(stat));
312 std::string &result)
const {
316 MPI_Offset attlen = 0;
318 int stat = ncmpi_inq_attlen(
m_file_id, varid, att_name.c_str(), &attlen);
319 int len = (stat == NC_NOERR) ?
static_cast<int>(attlen) : 0;
327 std::vector<char> str(len + 1, 0);
330 stat = ncmpi_get_att_text(
m_file_id, varid, att_name.c_str(), str.data());
342 io::Type nctype,
const std::vector<double> &data)
const {
344 int stat = ncmpi_put_att_double(
m_file_id,
get_varid(variable_name), att_name.c_str(),
351 const std::string &value)
const {
352 int stat = ncmpi_put_att_text(
m_file_id,
get_varid(variable_name), att_name.c_str(), value.size(),
359 std::string &result)
const {
361 char name[NC_MAX_NAME];
362 memset(name, 0, NC_MAX_NAME);
366 stat = ncmpi_inq_attname(
m_file_id, varid,
n, name);
377 nc_type tmp = NC_NAT;
378 int stat = ncmpi_inq_atttype(
m_file_id, varid, att_name.c_str(), &tmp);
379 if (stat == NC_ENOTATT) {
390 int stat = ncmpi_set_fill(
m_file_id, fillmode, &old_modep);
396 const std::vector<unsigned int> &start,
397 const std::vector<unsigned int> &
count,
double *ip)
const {
398 int stat, varid, ndims =
static_cast<int>(start.size());
400 std::vector<MPI_Offset> nc_start(ndims), nc_count(ndims);
402 stat = ncmpi_inq_varid(
m_file_id, variable_name.c_str(), &varid);
405 for (
int j = 0; j < ndims; ++j) {
406 nc_start[j] = start[j];
407 nc_count[j] =
count[j];
410 stat = ncmpi_get_vara_double_all(
m_file_id, varid, nc_start.data(), nc_count.data(), ip);
417 auto words =
split(hint,
':');
419 if (words.size() == 2) {
424 const_cast<char*
>(words[0].c_str()),
425 const_cast<char*
>(words[1].c_str()));
428 MPI_Comm_rank(
m_com, &rank);
430 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 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 get_var_double(const std::string &variable_name, const std::vector< unsigned int > &start, const std::vector< unsigned int > &count, double *ip) 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 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.