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
117 m_readonly = ( mode == nc_nowrite);
118
119 // Classic file access, one process writes, everyone else reads
120 mpi_invoke_void( &SerialNcFile::open, m_file, filename, mode);
121 MPI_Barrier( m_comm); // all ranks agree that file exists
122 }
125 bool is_open() const
126 {
127 return mpi_invoke( &SerialNcFile::is_open, m_file);
128 }
129
134 void close()
135 {
136 mpi_invoke_void( &SerialNcFile::close, m_file);
137 MPI_Barrier( m_comm); // all ranks agree that file is closed
138 // removes lock from file
139 }
140
142 void sync()
143 {
144 mpi_invoke_void( &SerialNcFile::sync, m_file);
145 }
149 int get_ncid() const noexcept
150 {
151 return m_file.get_ncid();
152 }
153
155 int get_format()const
156 {
157 return mpi_invoke( &SerialNcFile::get_format, m_file);
158 }
159
161 MPI_Comm communicator() const { return m_comm;}
162
163 // ///////////// Groups /////////////////
165 void def_grp( std::string name)
166 {
167 mpi_invoke_void( &SerialNcFile::def_grp, m_file, name);
168 }
170 void def_grp_p( std::filesystem::path path)
171 {
172 mpi_invoke_void( &SerialNcFile::def_grp_p, m_file, path);
173 }
175 bool grp_is_defined( std::filesystem::path path) const
176 {
177 return mpi_invoke( &SerialNcFile::grp_is_defined, m_file, path);
178 }
180 void set_grp( std::filesystem::path path = "")
181 {
182 mpi_invoke_void( &SerialNcFile::set_grp, m_file, path);
183 }
185 void rename_grp( std::string old_name, std::string new_name)
186 {
187 mpi_invoke_void( &SerialNcFile::rename_grp, m_file, old_name, new_name);
188 }
189
193 int get_grpid() const noexcept
194 {
195 return m_file.get_grpid();
196 }
197
199 std::filesystem::path get_current_path( ) const
200 {
201 return mpi_invoke( &SerialNcFile::get_current_path, m_file);
202 }
203
205 std::list<std::filesystem::path> get_grps( ) const
206 {
207 return mpi_invoke( &SerialNcFile::get_grps, m_file);
208 }
210 std::list<std::filesystem::path> get_grps_r( ) const
211 {
212 return mpi_invoke( &SerialNcFile::get_grps_r, m_file);
213 }
214
215 // //////////// Dimensions ////////////////////////
217 void def_dim( std::string name, size_t size)
218 {
219 mpi_invoke_void( &SerialNcFile::def_dim, m_file, name, size);
220 }
222 void rename_dim( std::string old_name, std::string new_name)
223 {
224 mpi_invoke_void( &SerialNcFile::rename_dim, m_file, old_name, new_name);
225 }
227 size_t get_dim_size( std::string name) const
228 {
229 return mpi_invoke( &SerialNcFile::get_dim_size, m_file, name);
230 }
231
233 std::vector<size_t> get_dims_shape( const std::vector<std::string>& dims) const
234 {
235 return mpi_invoke( &SerialNcFile::get_dims_shape, m_file, dims);
236 }
238 std::vector<std::string> get_dims(bool include_parents = true) const
239 {
240 return mpi_invoke( &SerialNcFile::get_dims, m_file, include_parents);
241 }
243 std::vector<std::string> get_unlim_dims() const
244 {
245 return mpi_invoke( &SerialNcFile::get_unlim_dims, m_file);
246 }
248 bool dim_is_defined( std::string name) const
249 {
250 return mpi_invoke( &SerialNcFile::dim_is_defined, m_file, name);
251 }
252 // ///////////// Attributes setters
254 void put_att ( const std::pair<std::string, nc_att_t>& att, std::string id = "")
255 {
256 // Fix unresolved type following
257 // https://stackoverflow.com/questions/45505017/how-comes-stdinvoke-does-not-handle-function-overloads
258 mpi_invoke_void( [this]( auto&&...xs) { m_file.put_att(
259 std::forward<decltype(xs)>(xs)...);}, att, id);
260 }
262 template<class S, class T>
263 void put_att( const std::tuple<S,nc_type, T>& att, std::string id = "")
264 {
265 mpi_invoke_void( &SerialNcFile::put_att<S,T>, m_file, att, id);
266 }
268 template<class Attributes = std::map<std::string, nc_att_t> > // *it must be usable in put_att
269 void put_atts( const Attributes& atts, std::string id = "")
270 {
271 mpi_invoke_void( &SerialNcFile::put_atts<Attributes>, m_file, atts, id);
272 }
273
274 // ///////////////// Attribute getters
275
277 template<class T>
278 T get_att_as(std::string att_name, std::string id = "") const
279 {
280 return mpi_invoke( &SerialNcFile::get_att_as<T>, m_file, att_name, id);
281 }
283 template<class T>
284 std::vector<T> get_att_vec_as( std::string att_name, std::string id = "") const
285 {
286 return mpi_invoke( &SerialNcFile::get_att_vec_as<T>, m_file,
287 att_name, id);
288 }
289
291 template<class T>
292 std::map<std::string, T> get_atts_as( std::string id = "") const
293 {
294 return mpi_invoke( &SerialNcFile::get_atts_as<T>, m_file, id);
295 }
297 std::map<std::string, nc_att_t> get_atts( std::string id = "") const
298 {
299 return get_atts_as<nc_att_t>( id);
300 }
301
303 void del_att( std::string att_name, std::string id = "")
304 {
305 mpi_invoke_void( &SerialNcFile::del_att, m_file, att_name, id);
306 }
308 bool att_is_defined( std::string att_name, std::string id = "") const
309 {
310 return mpi_invoke( &SerialNcFile::att_is_defined, m_file, att_name, id);
311 }
313 void rename_att( std::string old_att_name, std::string
314 new_att_name, std::string id = "")
315 {
316 mpi_invoke_void( &SerialNcFile::rename_att, m_file, old_att_name,
317 new_att_name, id);
318 }
319
320 // //////////// Variables ////////////////////////
322 template<class T, class Attributes = std::map<std::string, nc_att_t>>
323 void def_var_as( std::string name,
324 const std::vector<std::string>& dim_names,
325 const Attributes& atts = {})
326 {
327 mpi_invoke_void( &SerialNcFile::def_var_as<T, Attributes>, m_file, name, dim_names, atts);
328 }
330 template<class Attributes = std::map<std::string, nc_att_t>>
331 void def_var( std::string name, nc_type xtype,
332 const std::vector<std::string>& dim_names,
333 const Attributes& atts = {})
334 {
335 mpi_invoke_void( &SerialNcFile::def_var<Attributes>, m_file, name,
336 xtype, dim_names, atts);
337 }
338
343 template<class ContainerType, typename = std::enable_if_t<
344 dg::is_vector_v<ContainerType, dg::SharedVectorTag> or
345 dg::is_vector_v<ContainerType, dg::MPIVectorTag>>>
346 void put_var( std::string name, const MPINcHyperslab& slab,
347 const ContainerType& data)
348 {
349 int grpid = m_file.get_grpid(), varid = 0;
350 int e;
352 if( m_readonly or m_rank0)
353 {
354 e = nc_inq_varid( grpid, name.c_str(), &varid);
355 }
356 if ( not m_readonly)
357 {
358 MPI_Bcast( &e, 1, dg::getMPIDataType<int>(), 0, m_comm);
359 }
360 err = e;
361 using value_type = dg::get_value_type<ContainerType>;
362 m_receive.template set<value_type>(0);
363 auto& receive = m_receive.template get<value_type>( );
364 const auto& data_ref = get_ref( data, dg::get_tensor_category<ContainerType>());
365 if constexpr ( dg::has_policy_v<ContainerType, dg::CudaTag>)
366 {
367 m_buffer.template set<value_type>( data.size());
368 auto& buffer = m_buffer.template get<value_type>( );
369 dg::assign ( data_ref, buffer);
370 detail::put_vara_detail( grpid, varid, slab, buffer, receive, m_comm);
371 }
372 else
373 detail::put_vara_detail( grpid, varid, slab, data_ref, receive, m_comm);
374 }
375
377 template<class ContainerType, class Attributes = std::map<std::string, nc_att_t>,
378 typename = std::enable_if_t<
379 dg::is_vector_v<ContainerType, dg::SharedVectorTag> or
380 dg::is_vector_v<ContainerType, dg::MPIVectorTag>>>
381 void defput_var( std::string name, const std::vector<std::string>& dim_names,
382 const Attributes& atts, const MPINcHyperslab& slab,
383 const ContainerType& data)
384 {
385 def_var_as<dg::get_value_type<ContainerType>>( name, dim_names, atts);
386 put_var( name, slab, data);
387 }
388
391 template<class T, typename = std::enable_if_t<dg::is_scalar_v<T>>>
392 void put_var( std::string name, const std::vector<size_t>& start, T data)
393 {
394 mpi_invoke_void( &SerialNcFile::put_var<T>, m_file, name, start, data);
395 }
396
398 template<class T, class Attributes = std::map<std::string, nc_att_t>>
399 void def_dimvar_as( std::string name, size_t size, const Attributes& atts)
400 {
401 mpi_invoke_void( &SerialNcFile::def_dimvar_as<T>, m_file, name, size, atts);
402 }
408 template<class ContainerType, class Attributes = std::map<std::string, nc_att_t>>
409 void defput_dim( std::string name,
410 const Attributes& atts,
411 const MPI_Vector<ContainerType>& abscissas) // implicitly assume ordered by rank
412 {
413 unsigned size = abscissas.size(), global_size = 0;
414 MPI_Reduce( &size, &global_size, 1, MPI_UNSIGNED, MPI_SUM, 0,
415 abscissas.communicator());
417 atts);
418 put_var( name, {abscissas}, abscissas);
419 }
420
425 template<class ContainerType, typename = std::enable_if_t<
426 dg::is_vector_v<ContainerType, dg::SharedVectorTag> or
427 dg::is_vector_v<ContainerType, dg::MPIVectorTag>>>
428 void get_var( std::string name, const MPINcHyperslab& slab,
429 ContainerType& data) const
430 {
431 int grpid = m_file.get_grpid(), varid = 0; // grpid does not throw
432 int e;
434 if( m_readonly or m_rank0)
435 {
436 e = nc_inq_varid( grpid, name.c_str(), &varid);
437 }
438 if ( not m_readonly)
439 {
440 MPI_Bcast( &e, 1, dg::getMPIDataType<int>(), 0, m_comm);
441 }
442 err = e;
443
444 using value_type = dg::get_value_type<ContainerType>;
445 auto& data_ref = get_ref( data, dg::get_tensor_category<ContainerType>());
446 set_comm( data, slab.communicator(), dg::get_tensor_category<ContainerType>());
447 unsigned size = 1;
448 for( unsigned u=0; u<slab.ndim(); u++)
449 size *= slab.count()[u];
450
451 if constexpr ( dg::has_policy_v<ContainerType, dg::CudaTag>)
452 {
453 m_buffer.template set<value_type>( size);
454 auto& buffer = m_buffer.template get<value_type>( );
455 if( m_readonly)
456 err = detail::get_vara_T( grpid, varid,
457 slab.startp(), slab.countp(), buffer.data());
458 else
459 {
460 m_receive.template set<value_type>( 0);
461 auto& receive = m_receive.template get<value_type>( );
462 detail::get_vara_detail( grpid, varid, slab, buffer, receive, m_comm);
463 }
464 dg::assign ( buffer, data_ref);
465 }
466 else
467 {
468 data_ref.resize( size);
469 if( m_readonly)
470 err = detail::get_vara_T( grpid, varid,
471 slab.startp(), slab.countp(),
472 thrust::raw_pointer_cast(data_ref.data()));
473 else
474 {
475 m_receive.template set<value_type>( 0);
476 auto& receive = m_receive.template get<value_type>( );
477 detail::get_vara_detail( grpid, varid, slab, data_ref, receive, m_comm);
478 }
479 }
480 }
481
483 template<class T, typename = std::enable_if_t<dg::is_scalar_v<T>> >
484 void get_var( std::string name, const std::vector<size_t>& start, T& data) const
485 {
486 mpi_invoke_void( &SerialNcFile::get_var<T>, m_file, name, start, data);
487 if( not m_readonly)
488 mpi_bcast( data);
489 }
490
492 template<class ContainerType, typename = std::enable_if_t<
493 dg::is_vector_v<ContainerType, dg::SharedVectorTag> or
494 dg::is_vector_v<ContainerType, dg::MPIVectorTag>>>
495 ContainerType get_var_as( std::string name, const MPINcHyperslab& slab
496 ) const
497 {
498 ContainerType data;
499 get_var( name, slab, data);
500 return data;
501 }
502
504 template<class T, std::enable_if_t< dg::is_scalar_v<T>, bool> = true>
505 T get_var_as( std::string name, const std::vector<size_t>& start = {}) const
506 {
507 T var;
508 get_var( name, start, var);
509 return var;
510 }
511
513 bool var_is_defined( std::string name) const
514 {
515 return mpi_invoke( &SerialNcFile::var_is_defined, m_file, name);
516 }
517
519 nc_type get_var_type(std::string name) const
520 {
521 return mpi_invoke( &SerialNcFile::get_var_type, m_file, name);
522 }
523
525 std::vector<std::string> get_var_dims(std::string name) const
526 {
527 return mpi_invoke( &SerialNcFile::get_var_dims, m_file, name);
528 }
529
531 std::list<std::string> get_var_names() const
532 {
533 return mpi_invoke( &SerialNcFile::get_var_names, m_file);
534 }
535
536 private:
537 template<class ContainerType>
538 void set_comm( MPI_Vector<ContainerType>& x, MPI_Comm comm, dg::MPIVectorTag) const
539 {
540 x.set_communicator(comm);
541 }
542 template<class ContainerType>
543 void set_comm( ContainerType&, MPI_Comm, dg::AnyVectorTag) const
544 {
545 return;
546 }
547 template<class ContainerType>
548 const ContainerType& get_ref( const MPI_Vector<ContainerType>& x, dg::MPIVectorTag) const
549 {
550 return x.data();
551 }
552 template<class ContainerType>
553 const ContainerType& get_ref( const ContainerType& x, dg::AnyVectorTag) const
554 {
555 return x;
556 }
557 template<class ContainerType>
558 ContainerType& get_ref( MPI_Vector<ContainerType>& x, dg::MPIVectorTag) const
559 {
560 return x.data();
561 }
562 template<class ContainerType>
563 ContainerType& get_ref( ContainerType& x, dg::AnyVectorTag) const
564 {
565 return x;
566 }
567
568 template<class T>
569 void mpi_bcast( T& data) const
570 {
571 MPI_Bcast( &data, 1, dg::getMPIDataType<T>(), 0, m_comm);
572 }
573 void mpi_bcast( std::string& data) const
574 {
575 size_t len = data.size();
576 MPI_Bcast( &len, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
577 data.resize( len, 'x');
578 MPI_Bcast( &data[0], len, MPI_CHAR, 0, m_comm);
579 }
580 void mpi_bcast( std::filesystem::path& data) const
581 {
582 std::string name = data.generic_string();
583 mpi_bcast( name);
584 data = name;
585 }
586
587 template<class T>
588 void mpi_bcast( std::vector<T>& data) const
589 {
590 size_t len = data.size();
591 MPI_Bcast( &len, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
592 data.resize( len);
593 for( unsigned u=0; u<len; u++)
594 {
595 if constexpr ( std::is_same_v<T, bool>)
596 {
597 bool b = data[u];
598 mpi_bcast( b);
599 data[u] = b;
600 }
601 else
602 mpi_bcast( data[u]);
603 }
604 }
605 template<class T>
606 void mpi_bcast( std::list<T>& data) const
607 {
608 size_t len = data.size();
609 MPI_Bcast( &len, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
610 data.resize( len);
611 for( auto it = data.begin(); it != data.end(); it++)
612 mpi_bcast( *it);
613 }
614 template<class K, class T>
615 void mpi_bcast( std::map<K,T>& data) const
616 {
617 size_t len = data.size();
618 MPI_Bcast( &len, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
619 std::vector<K> keys;
620 std::vector<T> values;
621 if( m_rank0)
622 {
623 for ( const auto& pair : data)
624 {
625 keys.push_back( pair.first);
626 values.push_back( pair.second);
627 }
628 }
629 mpi_bcast( keys);
630 mpi_bcast( values);
631 if( not m_rank0)
632 {
633 for( unsigned u=0; u<len; u++)
634 data[keys[u]] = values[u];
635 }
636 }
637 // Adapted from
638 // https://stackoverflow.com/questions/60564132/default-constructing-an-stdvariant-from-index
639 template <class Variant, std::size_t I = 0>
640 Variant variant_from_index(std::size_t index) const
641 {
642 // I increases so we need to stop
643 if constexpr( I >= std::variant_size_v<Variant>)
644 return {};
645 else
646 return index == 0
647 ? Variant{std::in_place_index<I>}
648 : variant_from_index<Variant, I + 1>(index - 1);
649 }
650 void mpi_bcast( nc_att_t& data) const
651 {
652 // We need to make sure that data holds the correct type on non-rank0
653 size_t idx = data.index();
654 MPI_Bcast( &idx, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
655 if( not m_rank0)
656 data = variant_from_index<nc_att_t>( idx);
657 // ... so that visit calls the correct bcast overload
658 std::visit( [this]( auto&& arg) { mpi_bcast(arg);}, data);
659 }
660
661 // Here we handle errors, such that if they occur on rank0 all ranks will
662 // throw
663 template<class F, class ... Args>
664 std::invoke_result_t<F, Args...> mpi_invoke( F&& f, Args&& ...args) const
665 {
666 using R = std::invoke_result_t<F, Args...>;
667 if ( m_readonly)
668 {
669 return std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
670 }
671 int err = NC_NOERR;
672 R r;
673 if( m_rank0)
674 {
675 try
676 {
677 r = std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
678 }
679 catch( const NC_Error& e) { err = e.error();}
680 }
681 mpi_bcast( err);
682 if( err)
683 throw NC_Error( err);
684 mpi_bcast( r);
685 return r;
686 }
687 template<class F, class ... Args>
688 void mpi_invoke_void( F&& f, Args&& ... args) const
689 {
690 if ( m_readonly)
691 {
692 std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
693 return;
694 }
695 int err = NC_NOERR;
696 if( m_rank0)
697 {
698 try
699 {
700 std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
701 }
702 catch(const NC_Error& e) { err = e.error(); }
703 }
704 mpi_bcast( err); // this makes all calls blocking if not readonly!
705 if( err)
706 throw NC_Error( err);
707 }
708
709
710
711 bool m_rank0;
712 bool m_readonly;
713 MPI_Comm m_comm;
714 SerialNcFile m_file;
715 // Buffer for device to host transfer, and dg::assign
716 mutable dg::detail::AnyVector<thrust::host_vector> m_buffer, m_receive;
717};
718
723
724}// namespace file
725}// namespace dg
NcFileMode
Convenience NetCDF file opening/create flags.
Definition nc_file.h:121
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
Call nc_open(path, NC_NOWRITE, ...);. Open an existing file for read-only access, fail if it does not...
Definition nc_file.h:122
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:269
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:210
void rename_att(std::string old_att_name, std::string new_att_name, std::string id="")
Rename an attribute of the variable id.
Definition nc_mpi_file.h:313
std::vector< std::string > get_var_dims(std::string name) const
Get the dimension names associated to variable name.
Definition nc_mpi_file.h:525
void set_grp(std::filesystem::path path="")
Change group to path.
Definition nc_mpi_file.h:180
std::map< std::string, nc_att_t > get_atts(std::string id="") const
Definition nc_mpi_file.h:297
std::list< std::filesystem::path > get_grps() const
Get all subgroups in the current group as absolute paths.
Definition nc_mpi_file.h:205
void del_att(std::string att_name, std::string id="")
Remove an attribute named att_name from variable id.
Definition nc_mpi_file.h:303
std::vector< std::string > get_dims(bool include_parents=true) const
Get all visible dimension names in the current group.
Definition nc_mpi_file.h:238
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:323
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:331
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:308
void rename_grp(std::string old_name, std::string new_name)
rename a subgroup in the current group from old_name to new_name
Definition nc_mpi_file.h:185
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:484
std::vector< std::string > get_unlim_dims() const
Get all visible unlimited dimension names in the current group.
Definition nc_mpi_file.h:243
std::filesystem::path get_current_path() const
Get the absolute path of the current group.
Definition nc_mpi_file.h:199
void def_grp_p(std::filesystem::path path)
Define a group named path and all required intermediary groups.
Definition nc_mpi_file.h:170
void put_att(const std::pair< std::string, nc_att_t > &att, std::string id="")
Put an individual attribute.
Definition nc_mpi_file.h:254
int get_format() const
Check the binary file format of the netCDF file.
Definition nc_mpi_file.h:155
void open(const std::filesystem::path &filename, enum NcFileMode mode=nc_nowrite)
Open/Create a netCDF file.
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:346
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:222
void def_dim(std::string name, size_t size)
Define a dimension named name of size size.
Definition nc_mpi_file.h:217
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:284
void put_var(std::string name, const std::vector< size_t > &start, T data)
Write a single data point.
Definition nc_mpi_file.h:392
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:278
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:263
bool is_open() const
Definition nc_mpi_file.h:125
bool grp_is_defined(std::filesystem::path path) const
Check for existence of the group given by path.
Definition nc_mpi_file.h:175
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:233
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:381
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:409
nc_type get_var_type(std::string name) const
Definition nc_mpi_file.h:519
T get_var_as(std::string name, const std::vector< size_t > &start={}) const
Convenience shortcut (scalar version)
Definition nc_mpi_file.h:505
MPINcFile(const MPINcFile &rhs)=delete
There can only be exactly one file handle per physical file.
void def_grp(std::string name)
Define a group named name in the current group.
Definition nc_mpi_file.h:165
size_t get_dim_size(std::string name) const
Get the size of the dimension named name.
Definition nc_mpi_file.h:227
void sync()
Call nc_sync.
Definition nc_mpi_file.h:142
int get_ncid() const noexcept
Get the ncid of the underlying NetCDF C-API.
Definition nc_mpi_file.h:149
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:292
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:193
void close()
Explicitly close a file.
Definition nc_mpi_file.h:134
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:399
ContainerType get_var_as(std::string name, const MPINcHyperslab &slab) const
Convenience shortcut (vector version)
Definition nc_mpi_file.h:495
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:428
bool var_is_defined(std::string name) const
Definition nc_mpi_file.h:513
std::list< std::string > get_var_names() const
Get a list of variable names in the current group.
Definition nc_mpi_file.h:531
~MPINcFile()=default
Close open nc file and release all resources.
bool dim_is_defined(std::string name) const
Definition nc_mpi_file.h:248
MPI_Comm communicator() const
Return MPI communicator set in constructor.
Definition nc_mpi_file.h:161
A NetCDF Hyperslab for MPINcFile.
Definition nc_hyperslab.h:152
const size_t * countp() const
Definition nc_hyperslab.h:269
const size_t * startp() const
Definition nc_hyperslab.h:267
MPI_Comm communicator() const
Definition nc_hyperslab.h:265
const std::vector< size_t > & count() const
Definition nc_hyperslab.h:259
unsigned ndim() const
Definition nc_hyperslab.h:254
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:660
void sync()
Call nc_sync.
Definition nc_file.h:266
std::vector< std::string > get_var_dims(std::string name) const
Get the dimension names associated to variable name.
Definition nc_file.h:1056
void def_grp(std::string name)
Define a group named name in the current group.
Definition nc_file.h:304
void put_att(const std::pair< std::string, nc_att_t > &att, std::string id="")
Put an individual attribute.
Definition nc_file.h:604
void del_att(std::string att_name, std::string id="")
Remove an attribute named att_name from variable id.
Definition nc_file.h:708
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:515
void rename_dim(std::string old_name, std::string new_name)
Rename a dimension from old_name to new_name.
Definition nc_file.h:487
void rename_att(std::string old_att_name, std::string new_att_name, std::string id="")
Rename an attribute of the variable id.
Definition nc_file.h:733
std::list< std::filesystem::path > get_grps_r() const
Get all subgroups recursively in the current group as absolute paths.
Definition nc_file.h:456
bool var_is_defined(std::string name) const
Definition nc_file.h:1031
std::list< std::string > get_var_names() const
Get a list of variable names in the current group.
Definition nc_file.h:1087
void put_atts(const Attributes &atts, std::string id="")
Write a collection of attributes to a NetCDF variable or file.
Definition nc_file.h:640
nc_type get_var_type(std::string name) const
Definition nc_file.h:1041
bool is_open() const noexcept
Definition nc_file.h:237
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:776
void def_grp_p(std::filesystem::path path)
Define a group named path and all required intermediary groups.
Definition nc_file.h:323
void set_grp(std::filesystem::path path="")
Change group to path.
Definition nc_file.h:386
std::filesystem::path get_current_path() const
Get the absolute path of the current group.
Definition nc_file.h:428
bool dim_is_defined(std::string name) const
Definition nc_file.h:590
void def_dim(std::string name, size_t size)
Define a dimension named name of size size.
Definition nc_file.h:479
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:928
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:668
int get_grpid() const noexcept
Get the NetCDF-C ID of the current group.
Definition nc_file.h:425
int get_format() const
Check the binary file format of the netCDF file.
Definition nc_file.h:287
void close()
Explicitly close a file.
Definition nc_file.h:252
bool grp_is_defined(std::filesystem::path path) const
Check for existence of the group given by path.
Definition nc_file.h:361
bool att_is_defined(std::string att_name, std::string id="") const
Definition nc_file.h:717
std::vector< std::string > get_unlim_dims() const
Get all visible unlimited dimension names in the current group.
Definition nc_file.h:564
void put_var(std::string name, const NcHyperslab &slab, const ContainerType &data)
Write data to a variable.
Definition nc_file.h:803
std::vector< std::string > get_dims(bool include_parents=true) const
Get all visible dimension names in the current group.
Definition nc_file.h:532
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:885
int get_ncid() const noexcept
Get the ncid of the underlying NetCDF C-API.
Definition nc_file.h:278
size_t get_dim_size(std::string name) const
Get the size of the dimension named name.
Definition nc_file.h:502
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:757
std::map< std::string, T > get_atts_as(std::string id="") const
Read all NetCDF attributes of a certain type.
Definition nc_file.h:685
std::list< std::filesystem::path > get_grps() const
Get all subgroups in the current group as absolute paths.
Definition nc_file.h:436
void rename_grp(std::string old_name, std::string new_name)
rename a subgroup in the current group from old_name to new_name
Definition nc_file.h:415
void open(const std::filesystem::path &filename, enum NcFileMode mode=nc_nowrite)
Open/Create a netCDF file.
Definition nc_file.h:205