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);
196 const std::vector<unsigned int> &start,
197 const std::vector<unsigned int> &
count,
const char *data)
const {
198 int stat, varid, ndims =
static_cast<int>(start.size());
200 std::vector<MPI_Offset> nc_start(ndims), nc_count(ndims);
202 stat = ncmpi_inq_varid(
m_file_id, variable_name.c_str(), &varid);
205 for (
int j = 0; j < ndims; ++j) {
206 nc_start[j] = start[j];
207 nc_count[j] =
count[j];
210 stat = ncmpi_put_vara_text_all(
m_file_id, varid, nc_start.data(), nc_count.data(), data);
218 stat = ncmpi_inq_nvars(
m_file_id, &result);
224 std::vector<std::string> &result)
const {
225 int stat, ndims, varid = -1;
226 std::vector<int> dimids;
228 stat = ncmpi_inq_varid(
m_file_id, variable_name.c_str(), &varid);
231 stat = ncmpi_inq_varndims(
m_file_id, varid, &ndims);
239 result.resize(ndims);
240 dimids.resize(ndims);
242 stat = ncmpi_inq_vardimid(
m_file_id, varid, dimids.data());
245 for (
int k = 0;
k < ndims; ++
k) {
246 char name[NC_MAX_NAME];
247 memset(name, 0, NC_MAX_NAME);
249 stat = ncmpi_inq_dimname(
m_file_id, dimids[
k], name);
257 if (variable_name ==
"PISM_GLOBAL") {
262 int stat = ncmpi_inq_varid(
m_file_id, variable_name.c_str(), &varid);
278 stat = ncmpi_inq_varid(
m_file_id, variable_name.c_str(), &flag);
280 exists = (stat == NC_NOERR);
286 char varname[NC_MAX_NAME];
287 memset(varname, 0, NC_MAX_NAME);
289 stat = ncmpi_inq_varname(
m_file_id, j, varname);
296 std::vector<double> &result)
const {
297 int len, varid =
get_varid(variable_name);
298 MPI_Offset attlen = 0;
301 int stat = ncmpi_inq_attlen(
m_file_id, varid, att_name.c_str(), &attlen);
303 if (stat == NC_NOERR) {
304 len =
static_cast<int>(attlen);
305 }
else if (stat == NC_ENOTATT) {
320 stat = ncmpi_get_att_double(
m_file_id, varid, att_name.c_str(), result.data());
324 if (stat != NC_NOERR) {
325 fprintf(stderr,
"Error reading the %s attribute; (varid %d, NetCDF error %s)", att_name.c_str(),
326 varid, ncmpi_strerror(stat));
332 std::string &result)
const {
336 MPI_Offset attlen = 0;
338 int stat = ncmpi_inq_attlen(
m_file_id, varid, att_name.c_str(), &attlen);
339 int len = (stat == NC_NOERR) ?
static_cast<int>(attlen) : 0;
347 std::vector<char> str(len + 1, 0);
350 stat = ncmpi_get_att_text(
m_file_id, varid, att_name.c_str(), str.data());
362 io::Type nctype,
const std::vector<double> &data)
const {
364 int stat = ncmpi_put_att_double(
m_file_id,
get_varid(variable_name), att_name.c_str(),
371 const std::string &value)
const {
372 int stat = ncmpi_put_att_text(
m_file_id,
get_varid(variable_name), att_name.c_str(), value.size(),
379 std::string &result)
const {
381 char name[NC_MAX_NAME];
382 memset(name, 0, NC_MAX_NAME);
386 stat = ncmpi_inq_attname(
m_file_id, varid,
n, name);
397 nc_type tmp = NC_NAT;
398 int stat = ncmpi_inq_atttype(
m_file_id, varid, att_name.c_str(), &tmp);
399 if (stat == NC_ENOTATT) {
410 int stat = ncmpi_set_fill(
m_file_id, fillmode, &old_modep);
416 const std::vector<unsigned int> &start,
417 const std::vector<unsigned int> &
count,
double *ip)
const {
418 int stat, varid, ndims =
static_cast<int>(start.size());
420 std::vector<MPI_Offset> nc_start(ndims), nc_count(ndims);
422 stat = ncmpi_inq_varid(
m_file_id, variable_name.c_str(), &varid);
425 for (
int j = 0; j < ndims; ++j) {
426 nc_start[j] = start[j];
427 nc_count[j] =
count[j];
430 stat = ncmpi_get_vara_double_all(
m_file_id, varid, nc_start.data(), nc_count.data(), ip);
437 auto words =
split(hint,
':');
439 if (words.size() == 2) {
444 const_cast<char*
>(words[0].c_str()),
445 const_cast<char*
>(words[1].c_str()));
448 MPI_Comm_rank(
m_com, &rank);
450 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
void put_vara_text_impl(const std::string &variable_name, const std::vector< unsigned int > &start, const std::vector< unsigned int > &count, const char *data) 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.