121 const std::string& dir,
const std::string& name,
126 const std::string& compression,
127 F&& f,
bool is_checkpoint)
132 AMREX_ASSERT(
sizeof(
typename PC::ParticleType::RealType) == 4 ||
133 sizeof(
typename PC::ParticleType::RealType) == 8);
135 constexpr int NStructReal = PC::NStructReal;
136 constexpr int NStructInt = PC::NStructInt;
144#ifdef AMREX_USE_HDF5_ASYNC
147 async_vol_es_wait_particle();
150 es_par_g = H5EScreate();
154 std::string pdir = dir;
155 if ( ! pdir.empty() && pdir[pdir.size()-1] !=
'/') { pdir +=
'/'; }
158 if ( ! pc.GetLevelDirectoriesCreated()) {
170 hid_t fid, grp, fapl, comp_dtype;
176 comp_dtype = H5Tcreate (H5T_COMPOUND, 2 * AMREX_SPACEDIM *
sizeof(
int));
177 if (1 == AMREX_SPACEDIM) {
178 H5Tinsert (comp_dtype,
"lo_i", 0 *
sizeof(
int), H5T_NATIVE_INT);
179 H5Tinsert (comp_dtype,
"hi_i", 1 *
sizeof(
int), H5T_NATIVE_INT);
181 else if (2 == AMREX_SPACEDIM) {
182 H5Tinsert (comp_dtype,
"lo_i", 0 *
sizeof(
int), H5T_NATIVE_INT);
183 H5Tinsert (comp_dtype,
"lo_j", 1 *
sizeof(
int), H5T_NATIVE_INT);
184 H5Tinsert (comp_dtype,
"hi_i", 2 *
sizeof(
int), H5T_NATIVE_INT);
185 H5Tinsert (comp_dtype,
"hi_j", 3 *
sizeof(
int), H5T_NATIVE_INT);
187 else if (3 == AMREX_SPACEDIM) {
188 H5Tinsert (comp_dtype,
"lo_i", 0 *
sizeof(
int), H5T_NATIVE_INT);
189 H5Tinsert (comp_dtype,
"lo_j", 1 *
sizeof(
int), H5T_NATIVE_INT);
190 H5Tinsert (comp_dtype,
"lo_k", 2 *
sizeof(
int), H5T_NATIVE_INT);
191 H5Tinsert (comp_dtype,
"hi_i", 3 *
sizeof(
int), H5T_NATIVE_INT);
192 H5Tinsert (comp_dtype,
"hi_j", 4 *
sizeof(
int), H5T_NATIVE_INT);
193 H5Tinsert (comp_dtype,
"hi_k", 5 *
sizeof(
int), H5T_NATIVE_INT);
198 particle_io_flags(pc.GetParticles().size());
199 for (
int lev = 0; lev < pc.GetParticles().size(); lev++)
201 const auto& pmap = pc.GetParticles(lev);
202 for (
const auto& kv : pmap)
204 auto& flags = particle_io_flags[lev][kv.first];
205 particle_detail::fillFlags(flags, kv.second, f);
211 if(pc.GetUsePrePost())
213 nparticles = pc.GetNParticlesPrePost();
214 maxnextid = pc.GetMaxNextIDPrePost();
218 nparticles = particle_detail::countFlags(particle_io_flags, pc);
219 maxnextid = PC::ParticleType::NextID();
221 PC::ParticleType::NextID(maxnextid);
225 std::string HDF5FileName = pdir;
226 if ( ! HDF5FileName.empty() && HDF5FileName[HDF5FileName.size()-1] !=
'/')
229 HDF5FileName += name;
230 HDF5FileName +=
".h5";
231 pc.HdrFileNamePrePost = HDF5FileName;
238 char setstripe[1024];
239 int stripe_count = 128;
241 char *stripe_count_str = getenv(
"HDF5_STRIPE_COUNT");
242 char *stripe_size_str = getenv(
"HDF5_STRIPE_SIZE");
243 if (stripe_count_str) {
244 stripe_count = atoi(stripe_count_str);
247 if (stripe_size_str) {
248 stripe_size = atoi(stripe_size_str);
251 if (set_stripe == 1) {
252 snprintf(setstripe,
sizeof setstripe,
"lfs setstripe -c %d -S %dm %s", stripe_count, stripe_size, pdir.c_str());
253 std::cout <<
"Setting stripe parameters for HDF5 output: " << setstripe << std::endl;
257 fid = H5Fcreate(HDF5FileName.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
266 std::string versionName = is_checkpoint ? PC::CheckpointVersion() : PC::PlotfileVersion();
267 if (
sizeof(
typename PC::ParticleType::RealType) == 4) {
268 versionName +=
"_single";
270 versionName +=
"_double";
275 int num_output_real = 0;
276 for (
int i = 0; i < pc.NumRealComps() + NStructReal; ++i) {
277 if (write_real_comp[i]) { ++num_output_real; }
280 int num_output_int = 0;
281 for (
int i = 0; i < pc.NumIntComps() + NStructInt; ++i) {
282 if (write_int_comp[i]) { ++num_output_int; }
286 int ndim = AMREX_SPACEDIM;
287 grp = H5Gcreate(fid,
"Chombo_global", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
292 int ncomp = num_output_real + num_output_int;
299 int real_comp_count = AMREX_SPACEDIM;
301 for (
int i = 0; i < NStructReal + pc.NumRealComps(); ++i ) {
302 if (write_real_comp[i]) {
304 snprintf(comp_name,
sizeof comp_name,
"real_component_%d", real_comp_count);
314 int int_comp_count = 2;
316 for (
int i = 0; i < NStructInt + pc.NumIntComps(); ++i ) {
317 if (write_int_comp[i]) {
318 snprintf(comp_name,
sizeof comp_name,
"int_component_%d", int_comp_count);
331 int finest_level = pc.finestLevel();
334 char level_name[128];
337 hid_t dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
338 H5Pset_fill_time(dcpl_id, H5D_FILL_TIME_NEVER);
340 for (
int lev = 0; lev <= finest_level; ++lev) {
341 snprintf(level_name,
sizeof level_name,
"level_%d", lev);
343 grp = H5Gcreate(fid, level_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
345 std::cout <<
"H5Gcreate [" << level_name <<
"] failed!" << std::endl;
350 ngrids = pc.ParticleBoxArray(lev).size();
356 int mfs_size = 2 * AMREX_SPACEDIM;
357 hsize_t mfs_dim = (hsize_t)ngrids;
359 hid_t mfs_dset_space = H5Screate_simple(1, &mfs_dim, NULL);
360 hid_t mfs_dset= H5Dcreate(grp,
"boxes", comp_dtype, mfs_dset_space, H5P_DEFAULT, dcpl_id, H5P_DEFAULT);
363 for(
int j = 0; j < pc.ParticleBoxArray(lev).size(); ++j) {
364 for(
int i = 0; i < AMREX_SPACEDIM; ++i) {
365 vbox[(j * mfs_size) + i] = pc.ParticleBoxArray(lev)[j].smallEnd(i);
366 vbox[(j * mfs_size) + i + AMREX_SPACEDIM] = pc.ParticleBoxArray(lev)[j].bigEnd(i);
370 status = H5Dwrite(mfs_dset, comp_dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &(vbox[0]));
372 std::string msg(
"ParticleContainer::WriteHDF5ParticleDataSync(): unable to write boxes dataset");
376 H5Sclose(mfs_dset_space);
393 pp.
query(
"particles_nfiles",nOutFiles);
394 if(nOutFiles == -1) nOutFiles = NProcs;
396 pc.nOutFilesPrePost = nOutFiles;
398 fapl = H5Pcreate (H5P_FILE_ACCESS);
405#ifdef AMREX_USE_HDF5_ASYNC
406 fid = H5Fopen_async(HDF5FileName.c_str(), H5F_ACC_RDWR, fapl, es_par_g);
408 fid = H5Fopen(HDF5FileName.c_str(), H5F_ACC_RDWR, fapl);
415 for (
int lev = 0; lev <= pc.finestLevel(); lev++)
417 snprintf(level_name,
sizeof level_name,
"level_%d", lev);
418#ifdef AMREX_USE_HDF5_ASYNC
419 grp = H5Gopen_async(fid, level_name, H5P_DEFAULT, es_par_g);
421 grp = H5Gopen(fid, level_name, H5P_DEFAULT);
426 gotsome = (pc.nParticlesAtLevelPrePost[lev] > 0);
428 gotsome = (pc.NumberOfParticlesAtLevel(lev) > 0);
433 MultiFab state(pc.ParticleBoxArray(lev),
434 pc.ParticleDistributionMap(lev),
444 pc.filePrefixPrePost[lev] = HDF5FileName;
449 pc.WriteParticlesHDF5(lev, grp, which, count, where,
450 write_real_comp, write_int_comp,
452 particle_io_flags, is_checkpoint);
455 pc.whichPrePost[lev] = which;
456 pc.countPrePost[lev] = count;
457 pc.wherePrePost[lev] = where;
465#ifdef AMREX_USE_HDF5_ASYNC
466 H5Gclose_async(grp, es_par_g);
472 H5Tclose(comp_dtype);
475#ifdef AMREX_USE_HDF5_ASYNC
476 H5Fclose_async(fid, es_par_g);