4#include "dg/backend/mpi_datatype.h"
66 open( filename, mode);
85 MPI_Comm_compare( this->m_comm, rhs.m_comm, &result);
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);
108 void open(
const std::filesystem::path& filename,
114 MPI_Comm_rank( m_comm, &rank);
115 m_rank0 = (rank == 0);
121 MPI_Barrier( m_comm);
137 MPI_Barrier( m_comm);
180 void set_grp( std::filesystem::path path =
"")
238 std::vector<std::string>
get_dims(
bool include_parents =
true)
const
254 void put_att (
const std::pair<std::string, nc_att_t>& att, std::string
id =
"")
258 mpi_invoke_void( [
this](
auto&&...xs) { m_file.
put_att(
259 std::forward<
decltype(xs)>(xs)...);}, att, id);
262 template<
class S,
class T>
263 void put_att(
const std::tuple<S,nc_type, T>& att, std::string
id =
"")
268 template<
class Attributes = std::map<std::
string, nc_att_t> >
269 void put_atts(
const Attributes& atts, std::string
id =
"")
278 T
get_att_as(std::string att_name, std::string
id =
"")
const
297 std::map<std::string, nc_att_t>
get_atts( std::string
id =
"")
const
303 void del_att( std::string att_name, std::string
id =
"")
314 new_att_name, std::string
id =
"")
322 template<
class T,
class Attributes = std::map<std::
string, nc_att_t>>
324 const std::vector<std::string>& dim_names,
325 const Attributes& atts = {})
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 = {})
336 xtype, dim_names, atts);
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>>>
347 const ContainerType& data)
349 int grpid = m_file.
get_grpid(), varid = 0;
352 if( m_readonly or m_rank0)
354 e = nc_inq_varid( grpid, name.c_str(), &varid);
358 MPI_Bcast( &e, 1, dg::getMPIDataType<int>(), 0, m_comm);
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>)
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);
373 detail::put_vara_detail( grpid, varid, slab, data_ref, receive, m_comm);
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,
383 const ContainerType& data)
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)
398 template<
class T,
class Attributes = std::map<std::
string, nc_att_t>>
408 template<
class ContainerType,
class Attributes = std::map<std::
string, nc_att_t>>
410 const Attributes& atts,
411 const MPI_Vector<ContainerType>& abscissas)
413 unsigned size = abscissas.size(), global_size = 0;
414 MPI_Reduce( &size, &global_size, 1, MPI_UNSIGNED, MPI_SUM, 0,
415 abscissas.communicator());
418 put_var( name, {abscissas}, abscissas);
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>>>
429 ContainerType& data)
const
431 int grpid = m_file.
get_grpid(), varid = 0;
434 if( m_readonly or m_rank0)
436 e = nc_inq_varid( grpid, name.c_str(), &varid);
440 MPI_Bcast( &e, 1, dg::getMPIDataType<int>(), 0, m_comm);
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>());
448 for(
unsigned u=0; u<slab.
ndim(); u++)
449 size *= slab.
count()[u];
451 if constexpr ( dg::has_policy_v<ContainerType, dg::CudaTag>)
453 m_buffer.template set<value_type>( size);
454 auto& buffer = m_buffer.template get<value_type>( );
456 err = detail::get_vara_T( grpid, varid,
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);
464 dg::assign ( buffer, data_ref);
468 data_ref.resize( size);
470 err = detail::get_vara_T( grpid, varid,
472 thrust::raw_pointer_cast(data_ref.data()));
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);
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
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>>>
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
537 template<
class ContainerType>
538 void set_comm( MPI_Vector<ContainerType>& x, MPI_Comm comm, dg::MPIVectorTag)
const
540 x.set_communicator(comm);
542 template<
class ContainerType>
543 void set_comm( ContainerType&, MPI_Comm, dg::AnyVectorTag)
const
547 template<
class ContainerType>
548 const ContainerType& get_ref(
const MPI_Vector<ContainerType>& x, dg::MPIVectorTag)
const
552 template<
class ContainerType>
553 const ContainerType& get_ref(
const ContainerType& x, dg::AnyVectorTag)
const
557 template<
class ContainerType>
558 ContainerType& get_ref( MPI_Vector<ContainerType>& x, dg::MPIVectorTag)
const
562 template<
class ContainerType>
563 ContainerType& get_ref( ContainerType& x, dg::AnyVectorTag)
const
569 void mpi_bcast( T& data)
const
571 MPI_Bcast( &data, 1, dg::getMPIDataType<T>(), 0, m_comm);
573 void mpi_bcast( std::string& data)
const
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);
580 void mpi_bcast( std::filesystem::path& data)
const
582 std::string name = data.generic_string();
588 void mpi_bcast( std::vector<T>& data)
const
590 size_t len = data.size();
591 MPI_Bcast( &len, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
593 for(
unsigned u=0; u<len; u++)
595 if constexpr ( std::is_same_v<T, bool>)
606 void mpi_bcast( std::list<T>& data)
const
608 size_t len = data.size();
609 MPI_Bcast( &len, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
611 for(
auto it = data.begin(); it != data.end(); it++)
614 template<
class K,
class T>
615 void mpi_bcast( std::map<K,T>& data)
const
617 size_t len = data.size();
618 MPI_Bcast( &len, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
620 std::vector<T> values;
623 for (
const auto& pair : data)
625 keys.push_back( pair.first);
626 values.push_back( pair.second);
633 for(
unsigned u=0; u<len; u++)
634 data[keys[u]] = values[u];
639 template <
class Variant, std::
size_t I = 0>
640 Variant variant_from_index(std::size_t index)
const
643 if constexpr( I >= std::variant_size_v<Variant>)
647 ? Variant{std::in_place_index<I>}
648 : variant_from_index<Variant, I + 1>(index - 1);
650 void mpi_bcast(
nc_att_t& data)
const
653 size_t idx = data.index();
654 MPI_Bcast( &idx, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
656 data = variant_from_index<nc_att_t>( idx);
658 std::visit( [
this](
auto&& arg) { mpi_bcast(arg);}, data);
663 template<
class F,
class ... Args>
664 std::invoke_result_t<F, Args...> mpi_invoke( F&& f, Args&& ...args)
const
666 using R = std::invoke_result_t<F, Args...>;
669 return std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
677 r = std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
679 catch(
const NC_Error& e) { err = e.error();}
683 throw NC_Error( err);
687 template<
class F,
class ... Args>
688 void mpi_invoke_void( F&& f, Args&& ... args)
const
692 std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
700 std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
702 catch(
const NC_Error& e) { err = e.error(); }
706 throw NC_Error( err);
716 mutable dg::detail::AnyVector<thrust::host_vector> m_buffer, m_receive;
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