186 const std::string& dir,
const std::string& name,
191 const std::string& compression,
192 F&& f,
bool is_checkpoint)
197 AMREX_ASSERT(
sizeof(
typename PC::ParticleType::RealType) == 4 ||
198 sizeof(
typename PC::ParticleType::RealType) == 8);
200 constexpr int NStructReal = PC::NStructReal;
201 constexpr int NStructInt = PC::NStructInt;
207 int nrc = PC::ParticleType::is_soa_particle ?
208 pc.NumRealComps() + NStructReal - AMREX_SPACEDIM : pc.NumRealComps() + NStructReal;
213#ifdef AMREX_USE_HDF5_ASYNC
216 async_vol_es_wait_particle();
219 es_par_g = H5EScreate();
223 std::string pdir = dir;
224 if ( ! pdir.empty() && pdir[pdir.size()-1] !=
'/') { pdir +=
'/'; }
227 if ( ! pc.GetLevelDirectoriesCreated()) {
239 hid_t fid, grp, fapl, comp_dtype;
245 comp_dtype = H5Tcreate (H5T_COMPOUND, 2 * AMREX_SPACEDIM *
sizeof(
int));
246 if (1 == AMREX_SPACEDIM) {
247 H5Tinsert (comp_dtype,
"lo_i", 0 *
sizeof(
int), H5T_NATIVE_INT);
248 H5Tinsert (comp_dtype,
"hi_i", 1 *
sizeof(
int), H5T_NATIVE_INT);
250 else if (2 == AMREX_SPACEDIM) {
251 H5Tinsert (comp_dtype,
"lo_i", 0 *
sizeof(
int), H5T_NATIVE_INT);
252 H5Tinsert (comp_dtype,
"lo_j", 1 *
sizeof(
int), H5T_NATIVE_INT);
253 H5Tinsert (comp_dtype,
"hi_i", 2 *
sizeof(
int), H5T_NATIVE_INT);
254 H5Tinsert (comp_dtype,
"hi_j", 3 *
sizeof(
int), H5T_NATIVE_INT);
256 else if (3 == AMREX_SPACEDIM) {
257 H5Tinsert (comp_dtype,
"lo_i", 0 *
sizeof(
int), H5T_NATIVE_INT);
258 H5Tinsert (comp_dtype,
"lo_j", 1 *
sizeof(
int), H5T_NATIVE_INT);
259 H5Tinsert (comp_dtype,
"lo_k", 2 *
sizeof(
int), H5T_NATIVE_INT);
260 H5Tinsert (comp_dtype,
"hi_i", 3 *
sizeof(
int), H5T_NATIVE_INT);
261 H5Tinsert (comp_dtype,
"hi_j", 4 *
sizeof(
int), H5T_NATIVE_INT);
262 H5Tinsert (comp_dtype,
"hi_k", 5 *
sizeof(
int), H5T_NATIVE_INT);
267 particle_io_flags(pc.GetParticles().size());
268 for (
int lev = 0; lev < std::ssize(pc.GetParticles()); lev++)
270 const auto& pmap = pc.GetParticles(lev);
271 for (
const auto& kv : pmap)
273 auto& flags = particle_io_flags[lev][kv.first];
274 particle_detail::fillFlags(flags, kv.second, f);
280 if(pc.GetUsePrePost())
282 nparticles = pc.GetNParticlesPrePost();
283 maxnextid = pc.GetMaxNextIDPrePost();
287 nparticles = particle_detail::countFlags(particle_io_flags, pc);
288 maxnextid = PC::ParticleType::NextID();
290 PC::ParticleType::NextID(maxnextid);
294 std::string HDF5FileName = pdir;
295 if ( ! HDF5FileName.empty() && HDF5FileName[HDF5FileName.size()-1] !=
'/')
298 HDF5FileName += name;
299 HDF5FileName +=
".h5";
300 pc.HdrFileNamePrePost = HDF5FileName;
307 char setstripe[1024];
308 int stripe_count = 128;
310 char *stripe_count_str = getenv(
"HDF5_STRIPE_COUNT");
311 char *stripe_size_str = getenv(
"HDF5_STRIPE_SIZE");
312 if (stripe_count_str) {
313 stripe_count = atoi(stripe_count_str);
316 if (stripe_size_str) {
317 stripe_size = atoi(stripe_size_str);
320 if (set_stripe == 1) {
321 snprintf(setstripe,
sizeof setstripe,
"lfs setstripe -c %d -S %dm %s", stripe_count, stripe_size, pdir.c_str());
322 std::cout <<
"Setting stripe parameters for HDF5 output: " << setstripe << std::endl;
326 fid = H5Fcreate(HDF5FileName.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
335 std::string versionName = is_checkpoint ? PC::CheckpointVersion() : PC::PlotfileVersion();
336 if (
sizeof(
typename PC::ParticleType::RealType) == 4) {
337 versionName +=
"_single";
339 versionName +=
"_double";
344 int num_output_real = 0;
345 for (
int i = 0; i < std::ssize(write_real_comp); ++i) {
346 if (write_real_comp[i]) { ++num_output_real; }
349 int num_output_int = 0;
350 for (
int i = 0; i < pc.NumIntComps() + NStructInt; ++i) {
351 if (write_int_comp[i]) { ++num_output_int; }
355 int ndim = AMREX_SPACEDIM;
356 grp = H5Gcreate(fid,
"Chombo_global", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
361 int ncomp = num_output_real + num_output_int;
368 int real_comp_count = AMREX_SPACEDIM;
370 for (
int i = 0; i < std::ssize(write_real_comp); ++i ) {
371 if (write_real_comp[i]) {
373 snprintf(comp_name,
sizeof comp_name,
"real_component_%d", real_comp_count);
383 int int_comp_count = 2;
385 for (
int i = 0; i < NStructInt + pc.NumIntComps(); ++i ) {
386 if (write_int_comp[i]) {
387 snprintf(comp_name,
sizeof comp_name,
"int_component_%d", int_comp_count);
400 int finest_level = pc.finestLevel();
403 char level_name[128];
406 hid_t dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
407 H5Pset_fill_time(dcpl_id, H5D_FILL_TIME_NEVER);
409 for (
int lev = 0; lev <= finest_level; ++lev) {
410 snprintf(level_name,
sizeof level_name,
"level_%d", lev);
412 grp = H5Gcreate(fid, level_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
414 std::cout <<
"H5Gcreate [" << level_name <<
"] failed!" << std::endl;
419 ngrids = pc.ParticleBoxArray(lev).size();
425 int mfs_size = 2 * AMREX_SPACEDIM;
426 hsize_t mfs_dim = (hsize_t)ngrids;
428 hid_t mfs_dset_space = H5Screate_simple(1, &mfs_dim, NULL);
429 hid_t mfs_dset= H5Dcreate(grp,
"boxes", comp_dtype, mfs_dset_space, H5P_DEFAULT, dcpl_id, H5P_DEFAULT);
432 for(
int j = 0; j < pc.ParticleBoxArray(lev).size(); ++j) {
433 for(
int i = 0; i < AMREX_SPACEDIM; ++i) {
434 vbox[(j * mfs_size) + i] = pc.ParticleBoxArray(lev)[j].smallEnd(i);
435 vbox[(j * mfs_size) + i + AMREX_SPACEDIM] = pc.ParticleBoxArray(lev)[j].bigEnd(i);
439 status = H5Dwrite(mfs_dset, comp_dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &(vbox[0]));
441 std::string msg(
"ParticleContainer::WriteHDF5ParticleDataSync(): unable to write boxes dataset");
445 H5Sclose(mfs_dset_space);
462 pp.
query(
"particles_nfiles",nOutFiles);
463 if(nOutFiles == -1) nOutFiles = NProcs;
465 pc.nOutFilesPrePost = nOutFiles;
467 fapl = H5Pcreate (H5P_FILE_ACCESS);
474#ifdef AMREX_USE_HDF5_ASYNC
475 fid = H5Fopen_async(HDF5FileName.c_str(), H5F_ACC_RDWR, fapl, es_par_g);
477 fid = H5Fopen(HDF5FileName.c_str(), H5F_ACC_RDWR, fapl);
484 for (
int lev = 0; lev <= pc.finestLevel(); lev++)
486 snprintf(level_name,
sizeof level_name,
"level_%d", lev);
487#ifdef AMREX_USE_HDF5_ASYNC
488 grp = H5Gopen_async(fid, level_name, H5P_DEFAULT, es_par_g);
490 grp = H5Gopen(fid, level_name, H5P_DEFAULT);
495 gotsome = (pc.nParticlesAtLevelPrePost[lev] > 0);
497 gotsome = (pc.NumberOfParticlesAtLevel(lev) > 0);
502 MultiFab state(pc.ParticleBoxArray(lev),
503 pc.ParticleDistributionMap(lev),
513 pc.filePrefixPrePost[lev] = HDF5FileName;
518 pc.WriteParticlesHDF5(lev, grp, which, count, where,
519 write_real_comp, write_int_comp,
521 particle_io_flags, is_checkpoint);
524 pc.whichPrePost[lev] = which;
525 pc.countPrePost[lev] = count;
526 pc.wherePrePost[lev] = where;
534#ifdef AMREX_USE_HDF5_ASYNC
535 H5Gclose_async(grp, es_par_g);
541 H5Tclose(comp_dtype);
544#ifdef AMREX_USE_HDF5_ASYNC
545 H5Fclose_async(fid, es_par_g);