REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_NCInterface.H
Go to the documentation of this file.
1/** \file nc_interface.H
2 *
3 * Interface to NetCDF library
4 *
5 * Defines convenience wrappers to interact with a NetCDF file in a more
6 * OOP-like manner.
7 */
8
9#ifndef REMORA_NC_INTERFACE_H
10#define REMORA_NC_INTERFACE_H
11
12#ifdef REMORA_USE_NETCDF
13#include <string>
14#include <unordered_map>
15#include <vector>
16
17#include <pnetcdf.h>
18
19namespace ncutils {
20
21//! Wrapper around NetCDF data types
22struct NCDType
23{
24 static constexpr nc_type Int = NC_INT;
25#ifdef AMREX_USE_FLOAT
26 static constexpr nc_type Real = NC_FLOAT;
27 using RType = float;
28#else
29 static constexpr nc_type Real = NC_DOUBLE;
30 using RType = double;
31#endif
32};
33
34//! Representation of NetCDF dimension
35struct NCDim
36{
37 //! File/Group Identifier
38 const int ncid;
39
40 //! Dimension ID used with NetCDF API
41 const int dimid;
42
43 //! Name of this dimension
44 std::string name() const;
45
46 //! Length of this dimension
47 MPI_Offset len() const;
48};
49
50//! Representation of a NetCDF variable
51struct NCVar
52{
53 //! File/Group identifier
54 const int ncid;
55
56 //! Variable ID used with NetCDF API
57 const int varid;
58
59 //! Name of this variable
60 std::string name() const;
61
62 //! Number of array dimensions for this variable
63 int ndim() const;
64
65 //! Shape of the array (size in each array dimension)
66 std::vector<MPI_Offset> shape() const;
67
68 //! Write out the entire double variable
69 void put(const double* ptr) const;
70 //! Write out the entire float variable
71 void put(const float* ptr) const;
72 //! Write out the entire int variable
73 void put(const int* ptr) const;
74
75 //! Write out a slice of data
76 void
77 put(const double* dptr,
78 const std::vector<MPI_Offset>& start,
79 const std::vector<MPI_Offset>& count) const;
80
81 //! Write out a slice of data, collective
82 void
83 put_all(const double* dptr,
84 const std::vector<MPI_Offset>& start,
85 const std::vector<MPI_Offset>& count) const;
86 //! Write out a slice of data with with strides (see hyperslab definition in NetCDF)
87 void iput(
88 const double* dptr,
89 const std::vector<MPI_Offset>& start,
90 const std::vector<MPI_Offset>& count,
91 int * request) const ;
92
93 //! Write out a slice of data with with strides
94 void
95 put(const double* dptr,
96 const std::vector<MPI_Offset>& start,
97 const std::vector<MPI_Offset>& count,
98 const std::vector<MPI_Offset>& stride) const;
99 //! Write out a slice of data with with strides , collective
100 void
101 put_all(const double* dptr,
102 const std::vector<MPI_Offset>& start,
103 const std::vector<MPI_Offset>& count,
104 const std::vector<MPI_Offset>& stride) const;
105 //! Write out a slice of data
106 void
107 put(const float* dptr,
108 const std::vector<MPI_Offset>& start,
109 const std::vector<MPI_Offset>& count) const;
110 //! Write out a slice of data, collective
111 void
112 put_all(const float* dptr,
113 const std::vector<MPI_Offset>& start,
114 const std::vector<MPI_Offset>& count) const;
115 //! Write out a slice of data with with strides (see hyperslab definition in NetCDF)
116 void
117 put(const float* dptr,
118 const std::vector<MPI_Offset>& start,
119 const std::vector<MPI_Offset>& count,
120 const std::vector<MPI_Offset>& stride) const;
121 //! Write out a slice of data with with strides, collective
122 void
123 put_all(const float* dptr,
124 const std::vector<MPI_Offset>& start,
125 const std::vector<MPI_Offset>& count,
126 const std::vector<MPI_Offset>& stride) const;
127
128
129 //! Write out a slice of data
130 void put(const int* dptr, const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count) const;
131 //! Write out a slice of data, collective
132 void put_all(const int* dptr, const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count) const;
133
134 //! Write out a slice of data with with strides (see hyperslab definition in NetCDF)
135 void
136 put(const int* dptr,
137 const std::vector<MPI_Offset>& start,
138 const std::vector<MPI_Offset>& count,
139 const std::vector<MPI_Offset>& stride) const;
140 //! Write out a slice of data with with strides, collective
141 void
142 put_all(const int* dptr,
143 const std::vector<MPI_Offset>& start,
144 const std::vector<MPI_Offset>& count,
145 const std::vector<MPI_Offset>& stride) const;
146
147
148 //! Write out a slice of string data
149 void put(const char** dptr, const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count) const;
150 //! Write out a slice of string data with stride
151 void
152 put(
153 const char** dptr,
154 const std::vector<MPI_Offset>& start,
155 const std::vector<MPI_Offset>& count,
156 const std::vector<MPI_Offset>& stride) const;
157
158 //! Read the entire variable from file
159 void get(double* ptr) const;
160 //! Read the entire variable from file
161 void get(float* ptr) const;
162 //! Read the entire variable from file
163 void get(int* ptr) const;
164
165 //! Read a chunk of data from the file
166 void
167 get(double* dptr, const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count) const;
168
169 //! Read a chunk of data from the file, collective
170 void
171 get_all(double* dptr, const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count) const;
172
173 //! Read a chunk of data with strides
174 void
175 get(double* dptr,
176 const std::vector<MPI_Offset>& start,
177 const std::vector<MPI_Offset>& count,
178 const std::vector<MPI_Offset>& stride) const;
179
180 //! Read a chunk of data with strides, collective
181 void
182 get_all(double* dptr,
183 const std::vector<MPI_Offset>& start,
184 const std::vector<MPI_Offset>& count,
185 const std::vector<MPI_Offset>& stride) const;
186
187 //! Read a chunk of data from the file
188 void
189 get(float* dptr, const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count) const;
190 //! Read a chunk of data from file, collective
191 void get_all(float* dptr, const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count) const;
192
193 //! Read a chunk of data with strides
194 void
195 get(float* dptr,
196 const std::vector<MPI_Offset>& start,
197 const std::vector<MPI_Offset>& count,
198 const std::vector<MPI_Offset>& stride) const;
199
200 //! Read a chunk of data with strides, collective
201 void
202 get_all(float* dptr,
203 const std::vector<MPI_Offset>& start,
204 const std::vector<MPI_Offset>& count,
205 const std::vector<MPI_Offset>& stride) const;
206
207 //! Read a chunk of data from the file
208 void
209 get(int* dptr, const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count) const;
210 //! Read a chunk of data from the file, collective
211 void
212 get_all(int* dptr, const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count) const;
213
214 //! Read a chunk of data with strides
215 void
216 get(int* dptr,
217 const std::vector<MPI_Offset>& start,
218 const std::vector<MPI_Offset>& count,
219 const std::vector<MPI_Offset>& stride) const;
220 //! Read a chunk of data with strides, collective
221 void
222 get_all(int* dptr,
223 const std::vector<MPI_Offset>& start,
224 const std::vector<MPI_Offset>& count,
225 const std::vector<MPI_Offset>& stride) const;
226
227
228 //! Read a chunk of data from the file
229 void
230 get(char* dptr, const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count) const;
231
232 //! Read a chunk of data with strides
233 void
234 get(char* dptr,
235 const std::vector<MPI_Offset>& start,
236 const std::vector<MPI_Offset>& count,
237 const std::vector<MPI_Offset>& stride) const;
238
239 //! Whether a variable has an attribute with name
240 bool has_attr(const std::string& name) const;
241 //! Set attribute "name" to "value"
242 void put_attr(const std::string& name, const std::string& value) const;
243 //! Set attribute "name" to "value"
244 void
245 put_attr(const std::string& name, const std::vector<double>& value) const;
246 //! Set attribute "name" to "value"
247 void
248 put_attr(const std::string& name, const std::vector<float>& value) const;
249 //! Set attribute "name" to "value"
250 void put_attr(const std::string& name, const std::vector<int>& value) const;
251
252 //! Read attribute from file
253 std::string get_attr(const std::string& name) const;
254 //! Read attribute from file
255 void get_attr(const std::string& name, std::vector<double>& value) const;
256 //! Read attribute from file
257 void get_attr(const std::string& name, std::vector<float>& value) const;
258 //! Read attribute from file
259 void get_attr(const std::string& name, std::vector<int>& value) const;
260};
261
262
263/** Representation of a NetCDF file
264 *
265 * Provide wrappers to create and open file
266 */
268{
269public:
270
271 //! Create a file
272 static NCFile create(
273 const std::string& name,
274 const int cmode = NC_CLOBBER | NC_MPIIO,
275 MPI_Comm comm = MPI_COMM_WORLD,
276 MPI_Info info = MPI_INFO_NULL);
277
278 //! Open an existing file
279 static NCFile open(
280 const std::string& name,
281 const int cmode = NC_NOWRITE,
282 MPI_Comm comm = MPI_COMM_WORLD,
283 MPI_Info info = MPI_INFO_NULL);
284
285 ~NCFile();
286
287 //! Close file object
288 void close();
289
290 //! Number of dimensions
291 int num_dimensions() const;
292
293 //! Number of variables
294 int num_variables() const;
295
296 //! Number of attributes
297 int num_attributes() const;
298
299 //! Check if a dimension exists by name
300 bool has_dim(const std::string&) const;
301
302 //! Check if a variable exists by name
303 bool has_var(const std::string&) const;
304
305 //! Check if an attribute exists
306 bool has_attr(const std::string&) const;
307
308 //! Get the dimension instance by name
309 NCDim dim(const std::string&) const;
310
311 //! Get the variable instance by name
312 NCVar var(const std::string&) const;
313
314 //! Define new dimension
315 NCDim def_dim(const std::string&, const size_t len) const;
316
317 //! Define a scalar variable, i.e., 0-dimensional array
318 NCVar def_scalar(const std::string& name, const nc_type dtype) const;
319
320 //! Define an array
322 const std::string& name,
323 const nc_type dtype,
324 const std::vector<std::string>&) const;
325
326 //! Define an array with a fill value
328 const std::string& name,
329 const nc_type dtype,
330 const std::vector<std::string>& dnames,
331 const void* fill_val) const;
332
333 //! Define a variable (wrapper for def_array)
335 const std::string& name,
336 const nc_type dtype,
337 const std::vector<std::string>& dnames) const
338 {
339 return def_array(name, dtype, dnames);
340 }
341
342 //! Define a variable (wrapper for def_array)
344 const std::string& name,
345 const nc_type dtype,
346 const std::vector<std::string>& dnames,
347 const void* fill_val) const
348 {
349 return def_array_fill(name, dtype, dnames, fill_val);
350 }
351
352 //! Set file attribute to value
353 void put_attr(const std::string& name, const std::string& value) const;
354 //! Set file attribute to value
355 void put_attr(const std::string& name, const std::vector<double>& value) const;
356 //! Set file attribute to value
357 void put_attr(const std::string& name, const std::vector<float>& value) const;
358 //! Set file attribute to value
359 void put_attr(const std::string& name, const std::vector<int>& value) const;
360
361 //! Read file attribute from file
362 std::string get_attr(const std::string& name) const;
363 //! Read file attribute from file
364 void get_attr(const std::string& name, std::vector<double>& value) const;
365 //! Read file attribute from file
366 void get_attr(const std::string& name, std::vector<float>& value) const;
367 //! Read file attribute from file
368 void get_attr(const std::string& name, std::vector<int>& value) const;
369
370 //! wait for non-blocking calls to finish
371 void wait_all( int num_requests, int * requests);
372
373 //! Return a list of all dimensions defined in this group
374 std::vector<NCDim> all_dims() const;
375
376 //! Return a list of all variables defined in this group
377 std::vector<NCVar> all_vars() const;
378
379 //! Enter definition mode (not needed for NetCDF4 format)
380 void enter_def_mode() const;
381
382 //! Exit definition mode
383 void exit_def_mode() const;
384
385 NCFile(const int id) : ncid(id), is_open{true} {}
386
387 const int ncid{-1};
388 bool is_open{false};
389};
390
391} // namespace ncutils
392
393#else
394// why do we need this if netcdf is not defined ?
395
396namespace ncutils {
397
398struct NCDim {
399 const int ncid { -1 };
400 const int dimid { -1 };
401};
402
403struct NCVar {
404 const int ncid { -1 };
405 const int varid { -1 };
406};
407
408class NCFile {
409public:
410 const int ncid { -1 };
411};
412
413} // namespace ncutils
414
415#endif
416
417#endif /* NC_INTERFACE_H */
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.
NCVar def_var(const std::string &name, const nc_type dtype, const std::vector< std::string > &dnames) const
Define a variable (wrapper for def_array)
NCDim def_dim(const std::string &, const size_t len) const
Define new dimension.
static NCFile create(const std::string &name, const int cmode=NC_CLOBBER|NC_MPIIO, MPI_Comm comm=MPI_COMM_WORLD, MPI_Info info=MPI_INFO_NULL)
Create a file.
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.
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_var_fill(const std::string &name, const nc_type dtype, const std::vector< std::string > &dnames, const void *fill_val) const
Define a variable (wrapper for def_array)
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.
Wrapper around NetCDF data types.
static constexpr nc_type Real
static constexpr nc_type Int
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(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.