REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_NCInterface.cpp
Go to the documentation of this file.
1#include <algorithm>
2#include <cctype>
3#include <cstdio>
4#include <string>
5
7#include <AMReX.H>
8#include <AMReX_Print.H>
9
10#define abort_func amrex::Abort
11
12namespace ncutils {
13
14namespace {
15
16char recname[NC_MAX_NAME + 1];
17
18void check_ncmpi_error(int ierr) {
19 if (ierr != NC_NOERR) {
20 printf("\n%s\n\n", ncmpi_strerror(ierr));
21 abort_func("Encountered NetCDF error; aborting");
22 }
23}
24
25std::string lowercase (std::string value) {
26 std::transform(value.begin(), value.end(), value.begin(),
27 [](unsigned char c) { return static_cast<char>(std::tolower(c)); });
28 return value;
29}
30
31int inq_varid_case_insensitive (int ncid, const std::string& name, int* varid) {
32 int ierr = ncmpi_inq_varid(ncid, name.data(), varid);
33 if (ierr == NC_NOERR) {
34 return ierr;
35 }
36
37 int nvars = 0;
39
40 const std::string name_lower = lowercase(name);
41 int matched_varid = -1;
42 int nmatches = 0;
43 for (int i = 0; i < nvars; ++i) {
45 if (lowercase(std::string(recname)) == name_lower) {
47 ++nmatches;
48 }
49 }
50
51 if (nmatches == 1) {
52 *varid = matched_varid;
53 return NC_NOERR;
54 }
55
56 if (nmatches > 1) {
57 abort_func("Ambiguous case-insensitive NetCDF variable lookup for " + name);
58 }
59
60 return ierr;
61}
62} // namespace
63
64std::string NCDim::name() const {
66 return std::string(recname);
67}
68
69MPI_Offset NCDim::len() const {
70 MPI_Offset dlen;
72 return dlen;
73}
74
75std::string NCVar::name() const {
77 return std::string(recname);
78}
79
80int NCVar::ndim() const {
81 int ndims;
83 return ndims;
84}
85
86std::vector<MPI_Offset> NCVar::shape() const {
87 int ndims = ndim();
88 std::vector<int> dimids(ndims);
89 std::vector<MPI_Offset> vshape(ndims);
90
92
93 for (int i = 0; i < ndims; ++i) {
95 }
96
97 return vshape;
98}
99
100void NCVar::put(const double *ptr) const {
102}
103
104void NCVar::put(const float *ptr) const {
106}
107
108void NCVar::put(const int *ptr) const {
110}
111
112void NCVar::put(const double *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count) const {
114}
115
116//! Write out a slice of data, collective
117void NCVar::put_all(const double *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count) const {
119}
120
121void NCVar::put_varn_all(int num, MPI_Offset *const *starts, MPI_Offset *const *counts, const double *dptr) const {
123}
124
125void NCVar::put_varn_all(int num, MPI_Offset *const *starts, MPI_Offset *const *counts, const float *dptr) const {
127}
128
129//! Write out a slice of data, non-blocking
130void NCVar::iput(const double *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count,
131 int *request) const {
133}
134
135void NCVar::put(const double *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count,
136 const std::vector<MPI_Offset> &stride) const {
138}
139
140void NCVar::put_all(const double *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count,
141 const std::vector<MPI_Offset> &stride) const {
143}
144
145void NCVar::put(const float *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count) const {
147}
148
149void NCVar::put_all(const float *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count) const {
151}
152
153void NCVar::put(const float *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count,
154 const std::vector<MPI_Offset> &stride) const {
156}
157
158void NCVar::put_all(const float *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count,
159 const std::vector<MPI_Offset> &stride) const {
161}
162
163void NCVar::put(const int *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count) const {
165}
166
167void NCVar::put_all(const int *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count) const {
169}
170
171void NCVar::put(const int *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count,
172 const std::vector<MPI_Offset> &stride) const {
174}
175
176void NCVar::put_all(const int *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count,
177 const std::vector<MPI_Offset> &stride) const {
179}
180
181void NCVar::put(const char **dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count) const {
183}
184
185void NCVar::put(const char **dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count,
186 const std::vector<MPI_Offset> &stride) const {
188}
189
190void NCVar::get(double *ptr) const {
192}
193
194void NCVar::get(float *ptr) const {
196}
197
198void NCVar::get(int *ptr) const {
200}
201
202void NCVar::get(double *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count) const {
204}
205
206void NCVar::get_all(double *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count) const {
208}
209
210void NCVar::get(double *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count,
211 const std::vector<MPI_Offset> &stride) const {
213}
214
215void NCVar::get_all(double *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count,
216 const std::vector<MPI_Offset> &stride) const {
218}
219
220void NCVar::get(float *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count) const {
222}
223
224void NCVar::get_all(float *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count) const {
226}
227
228void NCVar::get(float *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count,
229 const std::vector<MPI_Offset> &stride) const {
231}
232
233void NCVar::get_all(float *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count,
234 const std::vector<MPI_Offset> &stride) const {
236}
237
238void NCVar::get(int *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count) const {
240}
241
242void NCVar::get_all(int *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count) const {
244}
245
246void NCVar::get(int *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count,
247 const std::vector<MPI_Offset> &stride) const {
249}
250
251void NCVar::get_all(int *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count,
252 const std::vector<MPI_Offset> &stride) const {
254}
255
256void NCVar::get(char *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count) const {
258}
259
260void NCVar::get(char *dptr, const std::vector<MPI_Offset> &start, const std::vector<MPI_Offset> &count,
261 const std::vector<MPI_Offset> &stride) const {
263}
264
265bool NCVar::has_attr(const std::string &name) const {
266 int ierr;
267 MPI_Offset lenp;
268 ierr = ncmpi_inq_att(ncid, varid, name.data(), NULL, &lenp);
269 return (ierr == NC_NOERR);
270}
271
272void NCVar::put_attr(const std::string &name, const std::string &value) const {
273 check_ncmpi_error(ncmpi_put_att_text(ncid, varid, name.data(), value.size(), value.data()));
274}
275
276void NCVar::put_attr(const std::string &name, const std::vector<double> &value) const {
278}
279
280void NCVar::put_attr(const std::string &name, const std::vector<float> &value) const {
282}
283
284void NCVar::put_attr(const std::string &name, const std::vector<int> &value) const {
286}
287
288std::string NCVar::get_attr(const std::string &name) const {
289 MPI_Offset lenp;
290 std::vector<char> aval;
292 aval.resize(lenp);
294 return std::string { aval.begin(), aval.end() };
295}
296
297void NCVar::get_attr(const std::string &name, std::vector<double> &values) const {
298 MPI_Offset lenp;
300 values.resize(lenp);
302}
303
304void NCVar::get_attr(const std::string &name, std::vector<float> &values) const {
305 MPI_Offset lenp;
307 values.resize(lenp);
309}
310
311void NCVar::get_attr(const std::string &name, std::vector<int> &values) const {
312 MPI_Offset lenp;
314 values.resize(lenp);
316}
317
318NCDim NCFile::dim(const std::string &name) const {
319 int newid;
321 return NCDim { ncid, newid };
322}
323
324NCDim NCFile::def_dim(const std::string &name, const size_t len) const {
325 int newid;
326 check_ncmpi_error(ncmpi_def_dim(ncid, name.data(), (MPI_Offset) len, &newid));
327 return NCDim { ncid, newid };
328}
329
330NCVar NCFile::def_scalar(const std::string &name, const nc_type dtype) const {
331 int newid;
332 check_ncmpi_error(ncmpi_def_var(ncid, name.data(), dtype, 0, NULL, &newid));
333 return NCVar { ncid, newid };
334}
335
336NCVar NCFile::def_array(const std::string &name, const nc_type dtype, const std::vector<std::string> &dnames) const {
337 int newid;
338 int ndims = dnames.size();
339 std::vector<int> dimids(ndims);
340 for (int i = 0; i < ndims; ++i) {
341 dimids[i] = dim(dnames[i]).dimid;
342 }
343
344 check_ncmpi_error(ncmpi_def_var(ncid, name.data(), dtype, ndims, dimids.data(), &newid));
345 return NCVar { ncid, newid };
346}
347
348NCVar NCFile::def_array_fill(const std::string &name, const nc_type dtype, const std::vector<std::string> &dnames,
349 const void *fill_val) const {
350 int newid;
351 int ndims = dnames.size();
352 std::vector<int> dimids(ndims);
353 for (int i = 0; i < ndims; ++i) {
354 dimids[i] = dim(dnames[i]).dimid;
355 }
356
357 check_ncmpi_error(ncmpi_def_var(ncid, name.data(), dtype, ndims, dimids.data(), &newid));
359 return NCVar { ncid, newid };
360}
361
362NCVar NCFile::var(const std::string &name) const {
363 int varid;
365 return NCVar { ncid, varid };
366}
367
369 int ndims;
371 return ndims;
372}
373
375 int nattrs;
377 return nattrs;
378}
379
381 int nvars;
383 return nvars;
384}
385
386bool NCFile::has_dim(const std::string &name) const {
387 int ierr = ncmpi_inq_dimid(ncid, name.data(), nullptr);
388 return (ierr == NC_NOERR);
389}
390
391bool NCFile::has_var(const std::string &name) const {
392 int rh_id = 0;
394 return (ierr == NC_NOERR);
395}
396
397bool NCFile::has_attr(const std::string &name) const {
398 int ierr;
399 MPI_Offset lenp;
400 ierr = ncmpi_inq_att(ncid, NC_GLOBAL, name.data(), nullptr, &lenp);
401 return (ierr == NC_NOERR);
402}
403
404void NCFile::put_attr(const std::string &name, const std::string &value) const {
405 check_ncmpi_error(ncmpi_put_att_text(ncid, NC_GLOBAL, name.data(), value.size(), value.data()));
406}
407
408void NCFile::put_attr(const std::string &name, const std::vector<double> &value) const {
410}
411
412void NCFile::put_attr(const std::string &name, const std::vector<float> &value) const {
413 check_ncmpi_error(ncmpi_put_att_float(ncid, NC_GLOBAL, name.data(), NC_FLOAT, value.size(), value.data()));
414}
415
416void NCFile::put_attr(const std::string &name, const std::vector<int> &value) const {
417 check_ncmpi_error(ncmpi_put_att_int(ncid, NC_GLOBAL, name.data(), NC_INT, value.size(), value.data()));
418}
419
420std::string NCFile::get_attr(const std::string &name) const {
421 MPI_Offset lenp;
422 std::vector<char> aval;
424 aval.resize(lenp);
426 return std::string { aval.begin(), aval.end() };
427}
428
429void NCFile::get_attr(const std::string &name, std::vector<double> &values) const {
430 MPI_Offset lenp;
432 values.resize(lenp);
434}
435
436void NCFile::get_attr(const std::string &name, std::vector<float> &values) const {
437 MPI_Offset lenp;
439 values.resize(lenp);
441}
442
443void NCFile::get_attr(const std::string &name, std::vector<int> &values) const {
444 MPI_Offset lenp;
446 values.resize(lenp);
448}
449
450std::vector<NCDim> NCFile::all_dims() const {
451 std::vector<NCDim> adims;
452 int ndims = num_dimensions();
453 adims.reserve(ndims);
454 for (int i = 0; i < ndims; ++i) {
455 adims.emplace_back(NCDim { ncid, i });
456 }
457 return adims;
458}
459
460std::vector<NCVar> NCFile::all_vars() const {
461 std::vector<NCVar> avars;
462 int nvars = num_variables();
463 avars.reserve(nvars);
464 for (int i = 0; i < nvars; ++i) {
465 avars.emplace_back(NCVar { ncid, i });
466 }
467 return avars;
468}
469
471 int ierr;
473
474 // Ignore already in define mode error
475 if (ierr == NC_EINDEFINE)
476 return;
477 // Handle all other errors
479}
480
484
485NCFile NCFile::create(const std::string &name, const int cmode, MPI_Comm comm, MPI_Info info) {
486 int ncid;
488 return NCFile(ncid);
489}
490
491NCFile NCFile::open(const std::string &name, const int cmode, MPI_Comm comm, MPI_Info info) {
492 int ncid;
493 check_ncmpi_error(ncmpi_open(comm, name.data(), cmode, info, &ncid));
494 return NCFile(ncid);
495}
496
498 std::vector<int> statuses(num_requests);
500 // ncmpi_wait_all returns the first error it saw, but a request can also fail
501 // on its own, so the per-request statuses have to be inspected too.
502 for (int i = 0; i < num_requests; ++i) {
504 }
505}
506
511
513 is_open = false;
515}
516} // namespace ncutils
mf_h setVal(geomdata.ProbHi(2))
#define abort_func
void put_attr(const std::string &name, const std::string &value) const
Set file attribute to value.
std::vector< NCDim > all_dims() const
Return a list of all dimensions defined in this group.
NCVar def_scalar(const std::string &name, const nc_type dtype) const
Define a scalar variable, i.e., 0-dimensional array.
NCVar def_array(const std::string &name, const nc_type dtype, const std::vector< std::string > &) const
Define an array.
std::vector< NCVar > all_vars() const
Return a list of all variables defined in this group.
NCDim dim(const std::string &) const
Get the dimension instance by name.
void enter_def_mode() const
Enter definition mode (not needed for NetCDF4 format)
bool has_var(const std::string &) const
Check if a variable exists by name.
bool has_attr(const std::string &) const
Check if an attribute exists.
NCDim def_dim(const std::string &, const size_t len) const
Define new dimension.
void exit_def_mode() const
Exit definition mode.
std::string get_attr(const std::string &name) const
Read file attribute from file.
int num_dimensions() const
Number of dimensions.
void wait_all(int num_requests, int *requests)
wait for non-blocking calls to finish
bool has_dim(const std::string &) const
Check if a dimension exists by name.
int num_attributes() const
Number of attributes.
static NCFile create(const std::string &name, const int cmode=NC_CLOBBER|NC_64BIT_DATA, MPI_Comm comm=MPI_COMM_WORLD, MPI_Info info=MPI_INFO_NULL)
Create a file. Defaults to CDF-5; classic CDF-1 has a 2GB limit.
int num_variables() const
Number of variables.
static NCFile open(const std::string &name, const int cmode=NC_NOWRITE, MPI_Comm comm=MPI_COMM_WORLD, MPI_Info info=MPI_INFO_NULL)
Open an existing file.
void close()
Close file object.
NCVar var(const std::string &) const
Get the variable instance by name.
NCVar def_array_fill(const std::string &name, const nc_type dtype, const std::vector< std::string > &dnames, const void *fill_val) const
Define an array with a fill value.
Representation of NetCDF dimension.
const int dimid
Dimension ID used with NetCDF API.
const int ncid
File/Group Identifier.
MPI_Offset len() const
Length of this dimension.
std::string name() const
Name of this dimension.
Representation of a NetCDF variable.
bool has_attr(const std::string &name) const
Whether a variable has an attribute with name.
const int ncid
File/Group identifier.
const int varid
Variable ID used with NetCDF API.
void iput(const double *dptr, const std::vector< MPI_Offset > &start, const std::vector< MPI_Offset > &count, int *request) const
Write out a slice of data with with strides (see hyperslab definition in NetCDF)
std::string name() const
Name of this variable.
void put_varn_all(int num, MPI_Offset *const *starts, MPI_Offset *const *counts, const double *dptr) const
void put(const double *ptr) const
Write out the entire double variable.
void get(double *ptr) const
Read the entire variable from file.
std::string get_attr(const std::string &name) const
Read attribute from file.
void put_all(const double *dptr, const std::vector< MPI_Offset > &start, const std::vector< MPI_Offset > &count) const
Write out a slice of data, collective.
void put_attr(const std::string &name, const std::string &value) const
Set attribute "name" to "value".
std::vector< MPI_Offset > shape() const
Shape of the array (size in each array dimension)
void get_all(double *dptr, const std::vector< MPI_Offset > &start, const std::vector< MPI_Offset > &count) const
Read a chunk of data from the file, collective.
int ndim() const
Number of array dimensions for this variable.