Skip to content

Commit b6e6002

Browse files
authored
Merge pull request #488 from pdziekan/record_aux_halo
Record aux halo
2 parents d1c863e + 484eaf3 commit b6e6002

File tree

1 file changed

+66
-14
lines changed

1 file changed

+66
-14
lines changed

libmpdata++/output/hdf5.hpp

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ namespace libmpdataxx
5555
H5::PredType::NATIVE_FLOAT,
5656
flttype_output = H5::PredType::NATIVE_FLOAT; // using floats not to waste disk space
5757

58-
blitz::TinyVector<hsize_t, parent_t::n_dims> cshape, shape, chunk, srfcshape, srfcchunk, offst;
58+
blitz::TinyVector<hsize_t, parent_t::n_dims> cshape, shape, chunk, srfcshape, srfcchunk, offst, shape_h, chunk_h, offst_h, shape_mem_h, offst_mem_h;
5959
H5::DSetCreatPropList params;
6060

61-
H5::DataSpace sspace, cspace, srfcspace;
61+
H5::DataSpace sspace, cspace, srfcspace, sspace_h, sspace_mem_h;
6262
#if defined(USE_MPI)
6363
hid_t fapl_id;
6464
#endif
@@ -95,36 +95,56 @@ namespace libmpdataxx
9595
{
9696
// creating the dimensions
9797
// x,y,z
98-
offst = 0;
98+
offst = 0;
99+
offst_h = 0;
100+
offst_mem_h = 0;
99101

100102
for (int d = 0; d < parent_t::n_dims; ++d)
101-
shape[d] = this->mem->distmem.grid_size[d];
103+
{
104+
shape[d] = this->mem->distmem.grid_size[d]; // shape of arrays stored in file
105+
shape_h[d] = this->mem->distmem.grid_size[d] + 2 * this->halo; // shape of arrays with halos stored in files
106+
shape_mem_h[d] = this->mem->grid_size[d].length() + 2 * this->halo; // shape of the array with halo stored in memory of given MPI rank
107+
}
102108

103-
chunk = shape;
109+
chunk = shape;
110+
chunk_h = shape_h;
104111

105112
// there is one more coordinate than cell index in each dimension
106113
cshape = shape + 1;
107114

108115
srfcshape = shape;
109116
*(srfcshape.end()-1) = 1;
110-
sspace = H5::DataSpace(parent_t::n_dims, shape.data());
111-
srfcspace = H5::DataSpace(parent_t::n_dims, srfcshape.data());
112-
cspace = H5::DataSpace(parent_t::n_dims, cshape.data());
117+
118+
sspace = H5::DataSpace(parent_t::n_dims, shape.data());
119+
sspace_h = H5::DataSpace(parent_t::n_dims, shape_h.data());
120+
sspace_mem_h = H5::DataSpace(parent_t::n_dims, shape_mem_h.data());
121+
srfcspace = H5::DataSpace(parent_t::n_dims, srfcshape.data());
122+
cspace = H5::DataSpace(parent_t::n_dims, cshape.data());
113123

114124
#if defined(USE_MPI)
115125
if (this->mem->distmem.size() > 1)
116126
{
117127
shape[0] = this->mem->grid_size[0].length();
118128
cshape[0] = this->mem->grid_size[0].length();
119129

130+
shape_h[0] =
131+
this->mem->distmem.rank() == 0 || this->mem->distmem.rank() == this->mem->distmem.size()-1 ?
132+
this->mem->grid_size[0].length() + this->halo :
133+
this->mem->grid_size[0].length();
134+
135+
120136
if (this->mem->distmem.rank() == this->mem->distmem.size() - 1)
121137
cshape[0] += 1;
122138

123-
offst[0] = this->mem->grid_size[0].first();
139+
offst[0] = this->mem->grid_size[0].first();
140+
offst_h[0] = this->mem->distmem.rank() == 0 ? 0 : this->mem->grid_size[0].first() + this->halo;
141+
if (this->mem->distmem.rank() > 0)
142+
offst_mem_h[0] = this->halo;
124143

125144
// chunk size has to be common to all processes !
126-
// TODO: something better ?
127-
chunk[0] = ( (typename solver_t::real_t) (this->mem->distmem.grid_size[0])) / this->mem->distmem.size() + 0.5 ;
145+
// TODO: set to 1? Test performance...
146+
chunk[0] = ( (typename solver_t::real_t) (this->mem->distmem.grid_size[0])) / this->mem->distmem.size() + 0.5 ;
147+
chunk_h[0] = 1;//chunk[0];
128148
}
129149
#endif
130150

@@ -135,8 +155,10 @@ namespace libmpdataxx
135155
*(srfcchunk.end()-1) = 1;
136156

137157
params.setChunk(parent_t::n_dims, chunk.data());
158+
138159
#if !defined(USE_MPI)
139-
params.setDeflate(5); // TODO: move such constant to the header
160+
params.setDeflate(5); // TODO: move such constant to the header
161+
// TODO2: why not deflate without MPI?
140162
#endif
141163

142164
// creating variables
@@ -203,10 +225,10 @@ namespace libmpdataxx
203225
}
204226
}
205227

206-
std::string base_name()
228+
std::string base_name(const std::string &name = "timestep")
207229
{
208230
std::stringstream ss;
209-
ss << "timestep" << std::setw(10) << std::setfill('0') << this->timestep;
231+
ss << name << std::setw(10) << std::setfill('0') << this->timestep;
210232
return ss.str();
211233
}
212234

@@ -216,6 +238,12 @@ namespace libmpdataxx
216238
return base_name() + ".h5";
217239
}
218240

241+
std::string hdf_name(const std::string &base_name)
242+
{
243+
// TODO: add option of .nc extension for Paraview sake ?
244+
return base_name + ".h5";
245+
}
246+
219247
void record_all()
220248
{
221249
// in concurrent setup only the first solver does output
@@ -362,6 +390,30 @@ namespace libmpdataxx
362390
record_dsc_helper(aux, arr);
363391
}
364392

393+
// for array + halo
394+
void record_aux_halo_hlpr(const std::string &name, const typename solver_t::arr_t &arr, H5::H5File hdf)
395+
{
396+
assert(this->rank == 0);
397+
398+
params.setChunk(parent_t::n_dims, chunk_h.data());
399+
400+
auto aux = hdf.createDataSet(
401+
name,
402+
flttype_output,
403+
sspace_h,
404+
params
405+
);
406+
407+
// revert to default chunk
408+
params.setChunk(parent_t::n_dims, chunk.data());
409+
410+
auto space = aux.getSpace();
411+
space.selectHyperslab(H5S_SELECT_SET, shape_h.data(), offst_h.data());
412+
sspace_mem_h.selectHyperslab(H5S_SELECT_SET, shape_h.data(), offst_mem_h.data());
413+
414+
aux.write(arr.data(), flttype_solver, sspace_mem_h, space, dxpl_id);
415+
}
416+
365417
void record_scalar_hlpr(const std::string &name, const std::string &group_name, typename solver_t::real_t data, H5::H5File hdf)
366418
{
367419
assert(this->rank == 0);

0 commit comments

Comments
 (0)