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);
119 MPI_Barrier( m_comm);
135 MPI_Barrier( m_comm);
172 void set_grp( std::filesystem::path path =
"")
230 std::vector<std::string>
get_dims(
bool include_parents =
true)
const
246 void put_att (
const std::pair<std::string, nc_att_t>& att, std::string
id =
"")
250 mpi_invoke_void( [
this](
auto&&...xs) { m_file.
put_att(
251 std::forward<
decltype(xs)>(xs)...);}, att, id);
254 template<
class S,
class T>
255 void put_att(
const std::tuple<S,nc_type, T>& att, std::string
id =
"")
260 template<
class Attributes = std::map<std::
string, nc_att_t> >
261 void put_atts(
const Attributes& atts, std::string
id =
"")
270 T
get_att_as(std::string att_name, std::string
id =
"")
const
289 std::map<std::string, nc_att_t>
get_atts( std::string
id =
"")
const
295 void del_att( std::string att_name, std::string
id =
"")
306 new_att_name, std::string
id =
"")
314 template<
class T,
class Attributes = std::map<std::
string, nc_att_t>>
316 const std::vector<std::string>& dim_names,
317 const Attributes& atts = {})
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 = {})
328 xtype, dim_names, atts);
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>>>
339 const ContainerType& data)
341 int grpid = m_file.
get_grpid(), varid = 0;
344 if( m_readonly or m_rank0)
346 e = nc_inq_varid( grpid, name.c_str(), &varid);
350 MPI_Bcast( &e, 1, dg::getMPIDataType<int>(), 0, m_comm);
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>)
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);
365 detail::put_vara_detail( grpid, varid, slab, data_ref, receive, m_comm);
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,
375 const ContainerType& data)
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)
390 template<
class T,
class Attributes = std::map<std::
string, nc_att_t>>
400 template<
class ContainerType,
class Attributes = std::map<std::
string, nc_att_t>>
402 const Attributes& atts,
403 const MPI_Vector<ContainerType>& abscissas)
405 unsigned size = abscissas.size(), global_size = 0;
406 MPI_Reduce( &size, &global_size, 1, MPI_UNSIGNED, MPI_SUM, 0,
407 abscissas.communicator());
410 put_var( name, {abscissas}, abscissas);
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>>>
421 ContainerType& data)
const
423 int grpid = m_file.
get_grpid(), varid = 0;
426 if( m_readonly or m_rank0)
428 e = nc_inq_varid( grpid, name.c_str(), &varid);
432 MPI_Bcast( &e, 1, dg::getMPIDataType<int>(), 0, m_comm);
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>());
440 for(
unsigned u=0; u<slab.
ndim(); u++)
441 size *= slab.
count()[u];
443 if constexpr ( dg::has_policy_v<ContainerType, dg::CudaTag>)
445 m_buffer.template set<value_type>( size);
446 auto& buffer = m_buffer.template get<value_type>( );
448 err = detail::get_vara_T( grpid, varid,
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);
456 dg::assign ( buffer, data_ref);
460 data_ref.resize( size);
462 err = detail::get_vara_T( grpid, varid,
464 thrust::raw_pointer_cast(data_ref.data()));
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);
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
508 template<
class ContainerType>
509 void set_comm( MPI_Vector<ContainerType>& x, MPI_Comm comm, dg::MPIVectorTag)
const
511 x.set_communicator(comm);
513 template<
class ContainerType>
514 void set_comm( ContainerType& x, MPI_Comm comm, dg::AnyVectorTag)
const
518 template<
class ContainerType>
519 const ContainerType& get_ref(
const MPI_Vector<ContainerType>& x, dg::MPIVectorTag)
const
523 template<
class ContainerType>
524 const ContainerType& get_ref(
const ContainerType& x, dg::AnyVectorTag)
const
528 template<
class ContainerType>
529 ContainerType& get_ref( MPI_Vector<ContainerType>& x, dg::MPIVectorTag)
const
533 template<
class ContainerType>
534 ContainerType& get_ref( ContainerType& x, dg::AnyVectorTag)
const
540 void mpi_bcast( T& data)
const
542 MPI_Bcast( &data, 1, dg::getMPIDataType<T>(), 0, m_comm);
544 void mpi_bcast( std::string& data)
const
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);
551 void mpi_bcast( std::filesystem::path& data)
const
553 std::string name = data.generic_string();
559 void mpi_bcast( std::vector<T>& data)
const
561 size_t len = data.size();
562 MPI_Bcast( &len, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
564 for(
unsigned u=0; u<len; u++)
566 if constexpr ( std::is_same_v<T, bool>)
577 void mpi_bcast( std::list<T>& data)
const
579 size_t len = data.size();
580 MPI_Bcast( &len, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
582 for(
auto it = data.begin(); it != data.end(); it++)
585 template<
class K,
class T>
586 void mpi_bcast( std::map<K,T>& data)
const
588 size_t len = data.size();
589 MPI_Bcast( &len, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
591 std::vector<T> values;
594 for (
const auto& pair : data)
596 keys.push_back( pair.first);
597 values.push_back( pair.second);
604 for(
unsigned u=0; u<len; u++)
605 data[keys[u]] = values[u];
610 template <
class Variant, std::
size_t I = 0>
611 Variant variant_from_index(std::size_t index)
const
614 if constexpr( I >= std::variant_size_v<Variant>)
618 ? Variant{std::in_place_index<I>}
619 : variant_from_index<Variant, I + 1>(index - 1);
621 void mpi_bcast(
nc_att_t& data)
const
624 size_t idx = data.index();
625 MPI_Bcast( &idx, 1, dg::getMPIDataType<size_t>(), 0, m_comm);
627 data = variant_from_index<nc_att_t>( idx);
629 std::visit( [
this](
auto&& arg) { mpi_bcast(arg);}, data);
634 template<
class F,
class ... Args>
635 std::invoke_result_t<F, Args...> mpi_invoke( F&& f, Args&& ...args)
const
637 using R = std::invoke_result_t<F, Args...>;
640 return std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
648 r = std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
650 catch(
const NC_Error& e) { err = e.error();}
654 throw NC_Error( err);
658 template<
class F,
class ... Args>
659 void mpi_invoke_void( F&& f, Args&& ... args)
const
663 std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
671 std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
673 catch(
const NC_Error& e) { err = e.error(); }
677 throw NC_Error( err);
687 mutable dg::detail::AnyVector<thrust::host_vector> m_buffer, m_receive;
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