Extension: Json and NetCDF utilities
#include "dg/file/file.h"
Loading...
Searching...
No Matches
easy_input.h
Go to the documentation of this file.
1#pragma once
2
3#include <exception>
4#include <netcdf.h>
5#include "dg/topology/grid.h"
6#ifdef MPI_VERSION
7#include "dg/backend/mpi_vector.h"
8#include "dg/topology/mpi_grid.h"
9#endif //MPI_VERSION
10#include "nc_error.h"
11#include "nc_hyperslab.h"
12
18namespace dg
19{
20namespace file
21{
22
24namespace detail
25{
26
27template<class T>
28inline int get_var_T( int ncid, int varID, T* data)
29{
30 assert( false && "Type not supported!\n" );
31 return NC_EBADTYPE;
32}
33template<>
34inline int get_var_T<float>( int ncid, int varID, float* data){
35 return nc_get_var_float( ncid, varID, data);
36}
37template<>
38inline int get_var_T<double>( int ncid, int varID, double* data){
39 return nc_get_var_double( ncid, varID, data);
40}
41template<>
42inline int get_var_T<int>( int ncid, int varID, int* data){
43 return nc_get_var_int( ncid, varID, data);
44}
45template<>
46inline int get_var_T<unsigned>( int ncid, int varID, unsigned* data){
47 return nc_get_var_uint( ncid, varID, data);
48}
49template<class T>
50inline int get_vara_T( int ncid, int varID, const size_t* startp, const size_t* countp, T* data)
51{
52 assert( false && "Type not supported!\n" );
53 return NC_EBADTYPE;
54}
55template<>
56inline int get_vara_T<float>( int ncid, int varID, const size_t* startp, const size_t* countp, float* data){
57 return nc_get_vara_float( ncid, varID, startp, countp, data);
58}
59template<>
60inline int get_vara_T<double>( int ncid, int varID, const size_t* startp, const size_t* countp, double* data){
61 return nc_get_vara_double( ncid, varID, startp, countp, data);
62}
63template<>
64inline int get_vara_T<int>( int ncid, int varID, const size_t* startp, const size_t* countp, int* data){
65 return nc_get_vara_int( ncid, varID, startp, countp, data);
66}
67template<>
68inline int get_vara_T<unsigned>( int ncid, int varID, const size_t* startp, const size_t* countp, unsigned* data){
69 return nc_get_vara_uint( ncid, varID, startp, countp, data);
70}
71#ifdef MPI_VERSION
72template<class host_vector>
73void get_vara_detail(int ncid, int varid,
74 const MPINcHyperslab& slab,
75 host_vector& data,
76 thrust::host_vector<dg::get_value_type<host_vector>>& to_send,
77 MPI_Comm global_comm = MPI_COMM_WORLD
78 )
79{
80 MPI_Comm comm = slab.communicator();
81 // we need to identify the global root rank within the groups and mark the
82 // entire group
83 int local_root_rank = dg::file::detail::mpi_comm_global2local_rank(comm, 0,
84 global_comm);
85 if (local_root_rank == MPI_UNDEFINED)
86 return;
87 unsigned ndim = slab.ndim(); // same on all processes
88 int rank, size;
89 MPI_Comm_rank( comm, &rank);
90 MPI_Comm_size( comm, &size);
91
92 // Send start and count vectors to root
93 std::vector<size_t> r_start( rank == local_root_rank ? size * ndim : 0);
94 std::vector<size_t> r_count( rank == local_root_rank ? size * ndim : 0);
95 MPI_Gather( slab.startp(), ndim, dg::getMPIDataType<size_t>(),
96 &r_start[0], ndim, dg::getMPIDataType<size_t>(),
97 local_root_rank, comm);
98 MPI_Gather( slab.countp(), ndim, dg::getMPIDataType<size_t>(),
99 &r_count[0], ndim, dg::getMPIDataType<size_t>(),
100 local_root_rank, comm);
101
102 MPI_Datatype mpitype = dg::getMPIDataType<get_value_type<host_vector>>();
103 int err = NC_NOERR;
104 if( rank == local_root_rank )
105 {
106 // Sanity check
107 int ndims;
108 int e = nc_inq_varndims( ncid, varid, &ndims);
109 if( not e)
110 err = e;
111 if( (unsigned)ndims != slab.ndim())
112 err = 1001; // Our own error code
113
114 std::vector<size_t> sizes( size, 1);
115 for( int r = 0 ; r < size; r++)
116 for( unsigned u=0; u<ndim; u++)
117 sizes[r]*= r_count[r*ndim + u];
118
119 // host_vector could be a View
120 unsigned max_size = *std::max_element( sizes.begin(), sizes.end());
121 to_send.resize( max_size);
122 for( int r=0; r<size; r++)
123 {
124 if(r!=rank)
125 {
126 int e = detail::get_vara_T( ncid, varid, &r_start[r*ndim],
127 &r_count[r*ndim], to_send.data()); // read data
128 MPI_Send( to_send.data(), (int)sizes[r], mpitype, r, r, comm);
129 if( not e) err = e;
130 }
131 else // read own data
132 {
133 int e = detail::get_vara_T( ncid, varid, slab.startp(),
134 slab.countp(), thrust::raw_pointer_cast(data.data()));
135 if( not e) err = e;
136 }
137 }
138 }
139 else
140 {
141 size_t num = 1;
142 for( unsigned u=0; u<ndim; u++)
143 num*= slab.count()[u];
144 MPI_Status status;
145 MPI_Recv( thrust::raw_pointer_cast(data.data()), num, mpitype,
146 local_root_rank, rank, comm, &status);
147 }
148 MPI_Bcast( &err, 1, dg::getMPIDataType<int>(), local_root_rank, comm);
149 if( err)
150 throw NC_Error( err);
151 return;
152}
153
154// all comms must be same size
155template<class host_vector, class MPITopology>
156void get_vara_detail(int ncid, int varid, unsigned slice,
157 const MPITopology& grid, MPI_Vector<host_vector>& data,
158 bool vara, bool parallel = false)
159{
160 MPINcHyperslab slab( grid);
161 if( vara)
162 slab = MPINcHyperslab( slice, grid);
163 if( parallel)
164 {
165 file::NC_Error_Handle err;
166 err = detail::get_vara_T( ncid, varid,
167 slab.startp(), slab.countp(), data.data().data());
168 }
169 else
170 {
171 thrust::host_vector<dg::get_value_type<host_vector>> to_send;
172 get_vara_detail( ncid, varid, slab, data.data(), to_send);
173 }
174}
175#endif // MPI_VERSION
176} // namespace detail
178
203template<class host_vector, class Topology>
204void get_var( int ncid, int varid, const Topology& grid,
205 host_vector& data, bool parallel = true)
206{
208 err = detail::get_var_T( ncid, varid, data.data());
209}
210
232template<class host_vector, class Topology>
233void get_vara( int ncid, int varid, unsigned slice, const Topology& grid,
234 host_vector& data, bool parallel = true)
235{
237 NcHyperslab slab( slice, grid);
238 err = detail::get_vara_T( ncid, varid, slab.startp(), slab.countp(),
239 data.data());
240}
241// scalar data
242
257template<class T, class real_type>
258void get_var( int ncid, int varid, const RealGrid0d<real_type>& grid,
259 T& data, bool parallel = true)
260{
262 err = detail::get_var_T( ncid, varid, &data);
263}
280template<class T, class real_type>
281void get_vara( int ncid, int varid, unsigned slice, const RealGrid0d<real_type>& grid,
282 T& data, bool parallel = true)
283{
285 size_t count = 1;
286 size_t start = slice; // convert to size_t
287 err = detail::get_vara_T( ncid, varid, &start, &count, &data);
288}
289
291
293#ifdef MPI_VERSION
294
295template<class host_vector, class MPITopology>
296void get_var(int ncid, int varid, const MPITopology& grid,
297 dg::MPI_Vector<host_vector>& data, bool parallel = true)
298{
299 detail::get_vara_detail( ncid, varid, 0, grid, data, false, parallel);
300}
301
302template<class host_vector, class MPITopology>
303void get_vara(int ncid, int varid, unsigned slice,
304 const MPITopology& grid, dg::MPI_Vector<host_vector>& data,
305 bool parallel = true)
306{
307 detail::get_vara_detail( ncid, varid, slice, grid, data, true, parallel);
308}
309
310// scalar data
311
312template<class T, class real_type>
313void get_var( int ncid, int varid, const RealMPIGrid0d<real_type>& grid,
314 T& data, bool parallel = true)
315{
316 get_var( ncid, varid, dg::RealGrid0d<real_type>(), data, parallel);
317}
318
319template<class T, class real_type>
320void get_vara( int ncid, int varid, unsigned slice, const RealMPIGrid0d<real_type>& grid,
321 T& data, bool parallel = true)
322{
323 get_vara( ncid, varid, slice, dg::RealGrid0d<real_type>(), data, parallel);
324}
325#endif //MPI_VERSION
327
328}//namespace file
329}//namespace dg
void get_var(int ncid, int varid, const Topology &grid, host_vector &data, bool parallel=true)
DEPRECATED Convenience wrapper around nc_get_var.
Definition easy_input.h:204
void get_vara(int ncid, int varid, unsigned slice, const Topology &grid, host_vector &data, bool parallel=true)
DEPRECATED Convenience wrapper around nc_get_vara()
Definition easy_input.h:233
Definition easy_atts.h:15
DEPRECATED Empty utitlity class that handles return values of netcdf functions and throws NC_Error(st...
Definition nc_error.h:70
A NetCDF Hyperslab for SerialNcFile.
Definition nc_hyperslab.h:27
const size_t * countp() const
Definition nc_hyperslab.h:134
const size_t * startp() const
Definition nc_hyperslab.h:132