Extension: Json and NetCDF utilities
#include "dg/file/file.h"
Loading...
Searching...
No Matches
nc_mpi_file.h
Go to the documentation of this file.
1#pragma once
2
3#include "nc_file.h"
4#include "dg/backend/mpi_datatype.h"
5
12namespace dg
13{
14namespace file
15{
16
46{
48 // ///////////////////////////// CONSTRUCTORS/DESTRUCTOR /////////
55 MPINcFile (MPI_Comm comm = MPI_COMM_WORLD)
56 : m_comm(comm)
57 {}
62 MPINcFile(const std::filesystem::path& filename, enum NcFileMode mode =
63 nc_nowrite, MPI_Comm comm = MPI_COMM_WORLD)
64 : m_comm(comm)
65 {
66 open( filename, mode);
67 }
69 MPINcFile(const MPINcFile& rhs) = delete;
71 MPINcFile& operator =(const MPINcFile & rhs) = delete;
72
74 MPINcFile(MPINcFile&& rhs) = default;
78 {
79 if( this!= &rhs)
80 {
81 // We need to check that the rhs has the same communicator
82 // else we need to think about different groups (do all ranks in both
83 // groups call this function?)
84 int result;
85 MPI_Comm_compare( this->m_comm, rhs.m_comm, &result);
86 // congruent, similar and ident all should be fine
87 assert( result != MPI_UNEQUAL);
88 this->m_comm = rhs.m_comm;
89 this->m_rank0 = rhs.m_rank0;
90 this->m_readonly = rhs.m_readonly;
91 this->m_file = std::move( rhs.m_file);
92 this->m_buffer = std::move( rhs.m_buffer);
93 this->m_receive = std::move( rhs.m_receive);
94 }
95 return *this;
96 }
97
99 ~MPINcFile() = default;
100 // /////////////////// open/close /////////
101
108 void open(const std::filesystem::path& filename,
109 enum NcFileMode mode = nc_nowrite)
110 {
111 // General problem: HDF5 may use file locks to prevent multiple processes
112 // from opening the same file for write at the same time
113 int rank;
114 MPI_Comm_rank( m_comm, &rank);
115 m_rank0 = (rank == 0);
116 m_readonly = ( mode == nc_nowrite);
117 // Classic file access, one process writes, everyone else reads
118 mpi_invoke_void( &SerialNcFile::open, m_file, filename, mode);
119 MPI_Barrier( m_comm); // all ranks agree that file exists
120 }
123 bool is_open() const
124 {
125 return mpi_invoke( &SerialNcFile::is_open, m_file);
126 }
127
132 void close()
133 {
134 mpi_invoke_void( &SerialNcFile::close, m_file);
135 MPI_Barrier( m_comm); // all ranks agree that file is closed
136 // removes lock from file
137 }
138
140 void sync()
141 {
142 mpi_invoke_void( &SerialNcFile::sync, m_file);
143 }
147 int get_ncid() const noexcept
148 {
149 return m_file.get_ncid();
150 }
151
153 MPI_Comm communicator() const { return m_comm;}
154
155 // ///////////// Groups /////////////////
157 void def_grp( std::string name)
158 {
159 mpi_invoke_void( &SerialNcFile::def_grp, m_file, name);
160 }
162 void def_grp_p( std::filesystem::path path)
163 {
164 mpi_invoke_void( &SerialNcFile::def_grp_p, m_file, path);
165 }
167 bool grp_is_defined( std::filesystem::path path) const
168 {
169 return mpi_invoke( &SerialNcFile::grp_is_defined, m_file, path);
170 }
172 void set_grp( std::filesystem::path path = "")
173 {
174 mpi_invoke_void( &SerialNcFile::set_grp, m_file, path);
175 }
177 void rename_grp( std::string old_name, std::string new_name)
178 {
179 mpi_invoke_void( &SerialNcFile::rename_grp, m_file, old_name, new_name);
180 }
181
185 int get_grpid() const noexcept
186 {
187 return m_file.get_grpid();
188 }
189
191 std::filesystem::path get_current_path( ) const
192 {
193 return mpi_invoke( &SerialNcFile::get_current_path, m_file);
194 }
195
197 std::list<std::filesystem::path> get_grps( ) const
198 {
199 return mpi_invoke( &SerialNcFile::get_grps, m_file);
200 }
202 std::list<std::filesystem::path> get_grps_r( ) const
203 {
204 return mpi_invoke( &SerialNcFile::get_grps_r, m_file);
205 }
206
207 // //////////// Dimensions ////////////////////////
209 void def_dim( std::string name, size_t size)
210 {
211 mpi_invoke_void( &SerialNcFile::def_dim, m_file, name, size);
212 }
214 void rename_dim( std::string old_name, std::string new_name)
215 {
216 mpi_invoke_void( &SerialNcFile::rename_dim, m_file, old_name, new_name);
217 }
219 size_t get_dim_size( std::string name) const
220 {
221 return mpi_invoke( &SerialNcFile::get_dim_size, m_file, name);
222 }
223
225 std::vector<size_t> get_dims_shape( const std::vector<std::string>& dims) const
226 {
227 return mpi_invoke( &SerialNcFile::get_dims_shape, m_file, dims);
228 }
230 std::vector<std::string> get_dims(bool include_parents = true) const
231 {
232 return mpi_invoke( &SerialNcFile::get_dims, m_file, include_parents);
233 }
235 std::vector<std::string> get_unlim_dims() const
236 {
237 return mpi_invoke( &SerialNcFile::get_unlim_dims, m_file);
238 }
240 bool dim_is_defined( std::string name) const
241 {
242 return mpi_invoke( &SerialNcFile::dim_is_defined, m_file, name);
243 }
244 // ///////////// Attributes setters
246 void put_att ( const std::pair<std::string, nc_att_t>& att, std::string id = "")
247 {
248 // Fix unresolved type following
249 // https://stackoverflow.com/questions/45505017/how-comes-stdinvoke-does-not-handle-function-overloads
250 mpi_invoke_void( [this]( auto&&...xs) { m_file.put_att(
251 std::forward<decltype(xs)>(xs)...);}, att, id);
252 }
254 template<class S, class T>
255 void put_att( const std::tuple<S,nc_type, T>& att, std::string id = "")
256 {
257 mpi_invoke_void( &SerialNcFile::put_att<S,T>, m_file, att, id);
258 }
260 template<class Attributes = std::map<std::string, nc_att_t> > // *it must be usable in put_att
261 void put_atts( const Attributes& atts, std::string id = "")
262 {
263 mpi_invoke_void( &SerialNcFile::put_atts<Attributes>, m_file, atts, id);
264 }
265
266 // ///////////////// Attribute getters
267
269 template<class T>
270 T get_att_as(std::string att_name, std::string id = "") const
271 {
272 return mpi_invoke( &SerialNcFile::get_att_as<T>, m_file, att_name, id);
273 }
275 template<class T>
276 std::vector<T> get_att_vec_as( std::string att_name, std::string id = "") const
277 {
278 return mpi_invoke( &SerialNcFile::get_att_vec_as<T>, m_file,
279 att_name, id);
280 }
281
283 template<class T>
284 std::map<std::string, T> get_atts_as( std::string id = "") const
285 {
286 return mpi_invoke( &SerialNcFile::get_atts_as<T>, m_file, id);
287 }
289 std::map<std::string, nc_att_t> get_atts( std::string id = "") const
290 {
291 return get_atts_as<nc_att_t>( id);
292 }
293
295 void del_att( std::string att_name, std::string id = "")
296 {
297 mpi_invoke_void( &SerialNcFile::del_att, m_file, att_name, id);
298 }
300 bool att_is_defined( std::string att_name, std::string id = "") const
301 {
302 return mpi_invoke( &SerialNcFile::att_is_defined, m_file, att_name, id);
303 }
305 void rename_att( std::string old_att_name, std::string
306 new_att_name, std::string id = "")
307 {
308 mpi_invoke_void( &SerialNcFile::rename_att, m_file, old_att_name,
309 new_att_name, id);
310 }
311
312 // //////////// Variables ////////////////////////
314 template<class T, class Attributes = std::map<std::string, nc_att_t>>
315 void def_var_as( std::string name,
316 const std::vector<std::string>& dim_names,
317 const Attributes& atts = {})
318 {
319 mpi_invoke_void( &SerialNcFile::def_var_as<T, Attributes>, m_file, name, dim_names, atts);
320 }
322 template<class Attributes = std::map<std::string, nc_att_t>>
323 void def_var( std::string name, nc_type xtype,
324 const std::vector<std::string>& dim_names,
325 const Attributes& atts = {})
326 {
327 mpi_invoke_void( &SerialNcFile::def_var<Attributes>, m_file, name,
328 xtype, dim_names, atts);
329 }
330
335 template<class ContainerType, typename = std::enable_if_t<
336 dg::is_vector_v<ContainerType, dg::SharedVectorTag> or
337 dg::is_vector_v<ContainerType, dg::MPIVectorTag>>>
338 void put_var( std::string name, const MPINcHyperslab& slab,
339 const ContainerType& data)
340 {
341 int grpid = m_file.get_grpid(), varid = 0;
342 int e;
344 if( m_readonly or m_rank0)
345 {
346 e = nc_inq_varid( grpid, name.c_str(), &varid);
347 }
348 if ( not m_readonly)
349 {
350 MPI_Bcast( &e, 1, dg::getMPIDataType<int>(), 0, m_comm);
351 }
352 err = e;
353 using value_type = dg::get_value_type<ContainerType>;
354 m_receive.template set<value_type>(0);
355 auto& receive = m_receive.template get<value_type>( );
356 const auto& data_ref = get_ref( data, dg::get_tensor_category<ContainerType>());
357 if constexpr ( dg::has_policy_v<ContainerType, dg::CudaTag>)
358 {
359 m_buffer.template set<value_type>( data.size());
360 auto& buffer = m_buffer.template get<value_type>( );
361 dg::assign ( data_ref, buffer);
362 detail::put_vara_detail( grpid, varid, slab, buffer, receive, m_comm);
363 }
364 else
365 detail::put_vara_detail( grpid, varid, slab, data_ref, receive, m_comm);
366 }
367
369 template<class ContainerType, class Attributes = std::map<std::string, nc_att_t>,
370 typename = std::enable_if_t<
371 dg::is_vector_v<ContainerType, dg::SharedVectorTag> or
372 dg::is_vector_v<ContainerType, dg::MPIVectorTag>>>
373 void defput_var( std::string name, const std::vector<std::string>& dim_names,
374 const Attributes& atts, const MPINcHyperslab& slab,
375 const ContainerType& data)
376 {
377 def_var_as<dg::get_value_type<ContainerType>>( name, dim_names, atts);
378 put_var( name, slab, data);
379 }
380
383 template<class T, typename = std::enable_if_t<dg::is_scalar_v<T>>>
384 void put_var( std::string name, const std::vector<size_t>& start, T data)
385 {
386 mpi_invoke_void( &SerialNcFile::put_var<T>, m_file, name, start, data);
387 }
388
390 template<class T, class Attributes = std::map<std::string, nc_att_t>>
391 void def_dimvar_as( std::string name, size_t size, const Attributes& atts)
392 {
393 mpi_invoke_void( &SerialNcFile::def_dimvar_as<T>, m_file, name, size, atts);
394 }
400 template<class ContainerType, class Attributes = std::map<std::string, nc_att_t>>
401 void defput_dim( std::string name,
402 const Attributes& atts,
403 const MPI_Vector<ContainerType>& abscissas) // implicitly assume ordered by rank
404 {
405 unsigned size = abscissas.size(), global_size = 0;
406 MPI_Reduce( &size, &global_size, 1, MPI_UNSIGNED, MPI_SUM, 0,
407 abscissas.communicator());
409 atts);
410 put_var( name, {abscissas}, abscissas);
411 }
412
417 template<class ContainerType, typename = std::enable_if_t<
418 dg::is_vector_v<ContainerType, dg::SharedVectorTag> or
419 dg::is_vector_v<ContainerType, dg::MPIVectorTag>>>
420 void get_var( std::string name, const MPINcHyperslab& slab,
421 ContainerType& data) const
422 {
423 int grpid = m_file.get_grpid(), varid = 0; // grpid does not throw
424 int e;
426 if( m_readonly or m_rank0)
427 {
428 e = nc_inq_varid( grpid, name.c_str(), &varid);
429 }
430 if ( not m_readonly)
431 {
432 MPI_Bcast( &e, 1, dg::getMPIDataType<int>(), 0, m_comm);
433 }
434 err = e;
435
436 using value_type = dg::get_value_type<ContainerType>;
437 auto& data_ref = get_ref( data, dg::get_tensor_category<ContainerType>());
438 set_comm( data, slab.communicator(), dg::get_tensor_category<ContainerType>());
439 unsigned size = 1;
440 for( unsigned u=0; u<slab.ndim(); u++)
441 size *= slab.count()[u];
442
443 if constexpr ( dg::has_policy_v<ContainerType, dg::CudaTag>)
444 {
445 m_buffer.template set<value_type>( size);
446 auto& buffer = m_buffer.template get<value_type>( );
447 if( m_readonly)
448 err = detail::get_vara_T( grpid, varid,
449 slab.startp(), slab.countp(), buffer.data());
450 else
451 {
452 m_receive.template set<value_type>( 0);
453 auto& receive = m_receive.template get<value_type>( );
454 detail::get_vara_detail( grpid, varid, slab, buffer, receive, m_comm);
455 }
456 dg::assign ( buffer, data_ref);
457 }
458 else
459 {
460 data_ref.resize( size);
461 if( m_readonly)
462 err = detail::get_vara_T( grpid, varid,
463 slab.startp(), slab.countp(),
464 thrust::raw_pointer_cast(data_ref.data()));
465 else
466 {
467 m_receive.template set<value_type>( 0);
468 auto& receive = m_receive.template get<value_type>( );
469 detail::get_vara_detail( grpid, varid, slab, data_ref, receive, m_comm);
470 }
471 }
472 }
473
475 template<class T, typename = std::enable_if_t<dg::is_scalar_v<T>> >
476 void get_var( std::string name, const std::vector<size_t>& start, T& data) const
477 {
478 mpi_invoke_void( &SerialNcFile::get_var<T>, m_file, name, start, data);
479 if( not m_readonly)
480 mpi_bcast( data);
481 }
482
484 bool var_is_defined( std::string name) const
485 {
486 return mpi_invoke( &SerialNcFile::var_is_defined, m_file, name);
487 }
488
490 nc_type get_var_type(std::string name) const
491 {
492 return mpi_invoke( &SerialNcFile::get_var_type, m_file, name);
493 }
494
496 std::vector<std::string> get_var_dims(std::string name) const
497 {
498 return mpi_invoke( &SerialNcFile::get_var_dims, m_file, name);
499 }
500
502 std::list<std::string> get_var_names() const
503 {
504 return mpi_invoke( &SerialNcFile::get_var_names, m_file);
505 }
506
507 private:
508 template<class ContainerType>
509 void set_comm( MPI_Vector<ContainerType>& x, MPI_Comm comm, dg::MPIVectorTag) const
510 {
511 x.set_communicator(comm);
512 }
513 template<class ContainerType>
514 void set_comm( ContainerType& x, MPI_Comm comm, dg::AnyVectorTag) const
515 {
516 return;
517 }
518 template<class ContainerType>
519 const ContainerType& get_ref( const MPI_Vector<ContainerType>& x, dg::MPIVectorTag) const
520 {
521 return x.data();
522 }
523 template<class ContainerType>
524 const ContainerType& get_ref( const ContainerType& x, dg::AnyVectorTag) const
525 {
526 return x;
527 }
528 template<class ContainerType>
529 ContainerType& get_ref( MPI_Vector<ContainerType>& x, dg::MPIVectorTag) const
530 {
531 return x.data();
532 }
533 template<class ContainerType>
534 ContainerType& get_ref( ContainerType& x, dg::AnyVectorTag) const
535 {
536 return x;
537 }
538
539 template<class T>
540 void mpi_bcast( T& data) const
541 {
542 MPI_Bcast( &data, 1, dg::getMPIDataType<T>(), 0, m_comm);
543 }
544 void mpi_bcast( std::string& data) const
545 {
546 size_t len = data.size();
547 MPI_Bcast( &len, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
548 data.resize( len, 'x');
549 MPI_Bcast( &data[0], len, MPI_CHAR, 0, m_comm);
550 }
551 void mpi_bcast( std::filesystem::path& data) const
552 {
553 std::string name = data.generic_string();
554 mpi_bcast( name);
555 data = name;
556 }
557
558 template<class T>
559 void mpi_bcast( std::vector<T>& data) const
560 {
561 size_t len = data.size();
562 MPI_Bcast( &len, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
563 data.resize( len);
564 for( unsigned u=0; u<len; u++)
565 {
566 if constexpr ( std::is_same_v<T, bool>)
567 {
568 bool b = data[u];
569 mpi_bcast( b);
570 data[u] = b;
571 }
572 else
573 mpi_bcast( data[u]);
574 }
575 }
576 template<class T>
577 void mpi_bcast( std::list<T>& data) const
578 {
579 size_t len = data.size();
580 MPI_Bcast( &len, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
581 data.resize( len);
582 for( auto it = data.begin(); it != data.end(); it++)
583 mpi_bcast( *it);
584 }
585 template<class K, class T>
586 void mpi_bcast( std::map<K,T>& data) const
587 {
588 size_t len = data.size();
589 MPI_Bcast( &len, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
590 std::vector<K> keys;
591 std::vector<T> values;
592 if( m_rank0)
593 {
594 for ( const auto& pair : data)
595 {
596 keys.push_back( pair.first);
597 values.push_back( pair.second);
598 }
599 }
600 mpi_bcast( keys);
601 mpi_bcast( values);
602 if( not m_rank0)
603 {
604 for( unsigned u=0; u<len; u++)
605 data[keys[u]] = values[u];
606 }
607 }
608 // Adapted from
609 // https://stackoverflow.com/questions/60564132/default-constructing-an-stdvariant-from-index
610 template <class Variant, std::size_t I = 0>
611 Variant variant_from_index(std::size_t index) const
612 {
613 // I increases so we need to stop
614 if constexpr( I >= std::variant_size_v<Variant>)
615 return {};
616 else
617 return index == 0
618 ? Variant{std::in_place_index<I>}
619 : variant_from_index<Variant, I + 1>(index - 1);
620 }
621 void mpi_bcast( nc_att_t& data) const
622 {
623 // We need to make sure that data holds the correct type on non-rank0
624 size_t idx = data.index();
625 MPI_Bcast( &idx, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
626 if( not m_rank0)
627 data = variant_from_index<nc_att_t>( idx);
628 // ... so that visit calls the correct bcast overload
629 std::visit( [this]( auto&& arg) { mpi_bcast(arg);}, data);
630 }
631
632 // Here we handle errors, such that if they occur on rank0 all ranks will
633 // throw
634 template<class F, class ... Args>
635 std::invoke_result_t<F, Args...> mpi_invoke( F&& f, Args&& ...args) const
636 {
637 using R = std::invoke_result_t<F, Args...>;
638 if ( m_readonly)
639 {
640 return std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
641 }
642 int err = NC_NOERR;
643 R r;
644 if( m_rank0)
645 {
646 try
647 {
648 r = std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
649 }
650 catch( const NC_Error& e) { err = e.error();}
651 }
652 mpi_bcast( err);
653 if( err)
654 throw NC_Error( err);
655 mpi_bcast( r);
656 return r;
657 }
658 template<class F, class ... Args>
659 void mpi_invoke_void( F&& f, Args&& ... args) const
660 {
661 if ( m_readonly)
662 {
663 std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
664 return;
665 }
666 int err = NC_NOERR;
667 if( m_rank0)
668 {
669 try
670 {
671 std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
672 }
673 catch(const NC_Error& e) { err = e.error(); }
674 }
675 mpi_bcast( err); // this makes all calls blocking if not readonly!
676 if( err)
677 throw NC_Error( err);
678 }
679
680
681
682 bool m_rank0;
683 bool m_readonly;
684 MPI_Comm m_comm;
685 SerialNcFile m_file;
686 // Buffer for device to host transfer, and dg::assign
687 mutable dg::detail::AnyVector<thrust::host_vector> m_buffer, m_receive;
688};
689
694
695}// namespace file
696}// namespace dg
NcFileMode
NetCDF file format.
Definition nc_file.h:95
std::variant< int, unsigned, float, double, bool, std::string, std::vector< int >, std::vector< unsigned >, std::vector< float >, std::vector< double >, std::vector< bool > > nc_att_t
Utility type to simplify dealing with heterogeneous attribute types.
Definition easy_atts.h:25
@ nc_nowrite
NC_NOWRITE Open an existing file for read-only access, fail if it does not exist.
Definition nc_file.h:96
Definition easy_atts.h:15
MPI NetCDF-4 file based on serial NetCDF.
Definition nc_mpi_file.h:46
MPINcFile(const std::filesystem::path &filename, enum NcFileMode mode=nc_nowrite, MPI_Comm comm=MPI_COMM_WORLD)
Open/Create a netCDF file.
Definition nc_mpi_file.h:62
void put_atts(const Attributes &atts, std::string id="")
Write a collection of attributes to a NetCDF variable or file.
Definition nc_mpi_file.h:261
std::list< std::filesystem::path > get_grps_r() const
Get all subgroups recursively in the current group as absolute paths.
Definition nc_mpi_file.h:202
void rename_att(std::string old_att_name, std::string new_att_name, std::string id="")
Definition nc_mpi_file.h:305
std::vector< std::string > get_var_dims(std::string name) const
Get the dimension names associated to variable name.
Definition nc_mpi_file.h:496
void set_grp(std::filesystem::path path="")
Change group to path.
Definition nc_mpi_file.h:172
std::map< std::string, nc_att_t > get_atts(std::string id="") const
Definition nc_mpi_file.h:289
std::list< std::filesystem::path > get_grps() const
Definition nc_mpi_file.h:197
void del_att(std::string att_name, std::string id="")
Remove an attribute named att_name from variable id.
Definition nc_mpi_file.h:295
std::vector< std::string > get_dims(bool include_parents=true) const
Definition nc_mpi_file.h:230
void def_var_as(std::string name, const std::vector< std::string > &dim_names, const Attributes &atts={})
Define a variable with given type, dimensions and (optionally) attributes.
Definition nc_mpi_file.h:315
void def_var(std::string name, nc_type xtype, const std::vector< std::string > &dim_names, const Attributes &atts={})
Define a variable with given type, dimensions and (optionally) attributes.
Definition nc_mpi_file.h:323
MPINcFile(MPI_Comm comm=MPI_COMM_WORLD)
Construct a File Handle not associated to any file.
Definition nc_mpi_file.h:55
bool att_is_defined(std::string att_name, std::string id="") const
Definition nc_mpi_file.h:300
void rename_grp(std::string old_name, std::string new_name)
Definition nc_mpi_file.h:177
void get_var(std::string name, const std::vector< size_t > &start, T &data) const
Read scalar from position start from variable named name.
Definition nc_mpi_file.h:476
std::vector< std::string > get_unlim_dims() const
Definition nc_mpi_file.h:235
std::filesystem::path get_current_path() const
Get the absolute path of the current group.
Definition nc_mpi_file.h:191
void def_grp_p(std::filesystem::path path)
Definition nc_mpi_file.h:162
void put_att(const std::pair< std::string, nc_att_t > &att, std::string id="")
Put an individual attribute.
Definition nc_mpi_file.h:246
void open(const std::filesystem::path &filename, enum NcFileMode mode=nc_nowrite)
Definition nc_mpi_file.h:108
void put_var(std::string name, const MPINcHyperslab &slab, const ContainerType &data)
Write data to a variable.
Definition nc_mpi_file.h:338
void rename_dim(std::string old_name, std::string new_name)
Rename a dimension from old_name to new_name.
Definition nc_mpi_file.h:214
void def_dim(std::string name, size_t size)
Define a dimension named name of size size.
Definition nc_mpi_file.h:209
std::vector< T > get_att_vec_as(std::string att_name, std::string id="") const
Short for get_att_as<std::vector<T>>( id, att_name);
Definition nc_mpi_file.h:276
void put_var(std::string name, const std::vector< size_t > &start, T data)
Write a single data point.
Definition nc_mpi_file.h:384
T get_att_as(std::string att_name, std::string id="") const
Get an attribute named att_name of the group or variable id.
Definition nc_mpi_file.h:270
void put_att(const std::tuple< S, nc_type, T > &att, std::string id="")
Put an individual attribute of preset type to variable id.
Definition nc_mpi_file.h:255
bool is_open() const
Definition nc_mpi_file.h:123
bool grp_is_defined(std::filesystem::path path) const
Check for existence of the group given by path.
Definition nc_mpi_file.h:167
std::vector< size_t > get_dims_shape(const std::vector< std::string > &dims) const
Get the size of each dimension in dims.
Definition nc_mpi_file.h:225
void defput_var(std::string name, const std::vector< std::string > &dim_names, const Attributes &atts, const MPINcHyperslab &slab, const ContainerType &data)
Define and put a variable in one go.
Definition nc_mpi_file.h:373
void defput_dim(std::string name, const Attributes &atts, const MPI_Vector< ContainerType > &abscissas)
Define a dimension and define and write to a dimension variable in one go.
Definition nc_mpi_file.h:401
nc_type get_var_type(std::string name) const
Definition nc_mpi_file.h:490
MPINcFile(const MPINcFile &rhs)=delete
There can only be exactly one file handle per physical file.
void def_grp(std::string name)
Definition nc_mpi_file.h:157
size_t get_dim_size(std::string name) const
Get the size of the dimension named name.
Definition nc_mpi_file.h:219
void sync()
Call nc_sync.
Definition nc_mpi_file.h:140
int get_ncid() const noexcept
Get the ncid of the underlying NetCDF C-API.
Definition nc_mpi_file.h:147
std::map< std::string, T > get_atts_as(std::string id="") const
Read all NetCDF attributes of a certain type.
Definition nc_mpi_file.h:284
MPINcFile & operator=(const MPINcFile &rhs)=delete
There can only be exactly one file handle per physical file.
MPINcFile(MPINcFile &&rhs)=default
Swap resources between two file handles.
int get_grpid() const noexcept
Get the NetCDF-C ID of the current group.
Definition nc_mpi_file.h:185
void close()
Explicitly close a file.
Definition nc_mpi_file.h:132
void def_dimvar_as(std::string name, size_t size, const Attributes &atts)
Define a dimension and dimension variable in one go.
Definition nc_mpi_file.h:391
void get_var(std::string name, const MPINcHyperslab &slab, ContainerType &data) const
Read hyperslab slab from variable named name into container data.
Definition nc_mpi_file.h:420
bool var_is_defined(std::string name) const
Definition nc_mpi_file.h:484
std::list< std::string > get_var_names() const
Get a list of variable names in the current group.
Definition nc_mpi_file.h:502
~MPINcFile()=default
Close open nc file and release all resources.
bool dim_is_defined(std::string name) const
Definition nc_mpi_file.h:240
MPI_Comm communicator() const
Return MPI communicator set in constructor.
Definition nc_mpi_file.h:153
A NetCDF Hyperslab for MPINcFile.
Definition nc_hyperslab.h:151
const size_t * countp() const
Definition nc_hyperslab.h:268
const size_t * startp() const
Definition nc_hyperslab.h:266
MPI_Comm communicator() const
Definition nc_hyperslab.h:264
const std::vector< size_t > & count() const
Definition nc_hyperslab.h:258
unsigned ndim() const
Definition nc_hyperslab.h:253
DEPRECATED Empty utitlity class that handles return values of netcdf functions and throws NC_Error(st...
Definition nc_error.h:70
T get_att_as(std::string att_name, std::string id="") const
Get an attribute named att_name of the group or variable id.
Definition nc_file.h:629
void sync()
Call nc_sync.
Definition nc_file.h:253
std::vector< std::string > get_var_dims(std::string name) const
Get the dimension names associated to variable name.
Definition nc_file.h:971
void def_grp(std::string name)
Definition nc_file.h:276
void put_att(const std::pair< std::string, nc_att_t > &att, std::string id="")
Put an individual attribute.
Definition nc_file.h:573
void del_att(std::string att_name, std::string id="")
Remove an attribute named att_name from variable id.
Definition nc_file.h:678
std::vector< size_t > get_dims_shape(const std::vector< std::string > &dims) const
Get the size of each dimension in dims.
Definition nc_file.h:484
void rename_dim(std::string old_name, std::string new_name)
Rename a dimension from old_name to new_name.
Definition nc_file.h:456
void rename_att(std::string old_att_name, std::string new_att_name, std::string id="")
Definition nc_file.h:696
std::list< std::filesystem::path > get_grps_r() const
Get all subgroups recursively in the current group as absolute paths.
Definition nc_file.h:425
bool var_is_defined(std::string name) const
Definition nc_file.h:946
std::list< std::string > get_var_names() const
Get a list of variable names in the current group.
Definition nc_file.h:1002
void put_atts(const Attributes &atts, std::string id="")
Write a collection of attributes to a NetCDF variable or file.
Definition nc_file.h:609
nc_type get_var_type(std::string name) const
Definition nc_file.h:956
bool is_open() const noexcept
Definition nc_file.h:224
void def_var(std::string name, nc_type xtype, const std::vector< std::string > &dim_names, const Attributes &atts={})
Define a variable with given type, dimensions and (optionally) attributes.
Definition nc_file.h:739
void def_grp_p(std::filesystem::path path)
Definition nc_file.h:295
void set_grp(std::filesystem::path path="")
Change group to path.
Definition nc_file.h:355
std::filesystem::path get_current_path() const
Get the absolute path of the current group.
Definition nc_file.h:397
bool dim_is_defined(std::string name) const
Definition nc_file.h:559
void def_dim(std::string name, size_t size)
Define a dimension named name of size size.
Definition nc_file.h:448
void get_var(std::string name, const NcHyperslab &slab, ContainerType &data) const
Read hyperslab slab from variable named name into container data.
Definition nc_file.h:891
std::vector< T > get_att_vec_as(std::string att_name, std::string id="") const
Short for get_att_as<std::vector<T>>( id, att_name);
Definition nc_file.h:637
int get_grpid() const noexcept
Get the NetCDF-C ID of the current group.
Definition nc_file.h:394
void close()
Explicitly close a file.
Definition nc_file.h:239
bool grp_is_defined(std::filesystem::path path) const
Check for existence of the group given by path.
Definition nc_file.h:333
bool att_is_defined(std::string att_name, std::string id="") const
Definition nc_file.h:687
std::vector< std::string > get_unlim_dims() const
Definition nc_file.h:533
void put_var(std::string name, const NcHyperslab &slab, const ContainerType &data)
Write data to a variable.
Definition nc_file.h:766
std::vector< std::string > get_dims(bool include_parents=true) const
Definition nc_file.h:501
void def_dimvar_as(std::string name, size_t size, const Attributes &atts)
Define a dimension and dimension variable in one go.
Definition nc_file.h:848
int get_ncid() const noexcept
Get the ncid of the underlying NetCDF C-API.
Definition nc_file.h:265
size_t get_dim_size(std::string name) const
Get the size of the dimension named name.
Definition nc_file.h:471
void def_var_as(std::string name, const std::vector< std::string > &dim_names, const Attributes &atts={})
Define a variable with given type, dimensions and (optionally) attributes.
Definition nc_file.h:720
std::map< std::string, T > get_atts_as(std::string id="") const
Read all NetCDF attributes of a certain type.
Definition nc_file.h:655
std::list< std::filesystem::path > get_grps() const
Definition nc_file.h:405
void rename_grp(std::string old_name, std::string new_name)
Definition nc_file.h:384
void open(const std::filesystem::path &filename, enum NcFileMode mode=nc_nowrite)
Definition nc_file.h:191