From f1ef81e6c4dc77514eaa693e23fa764cdbc7aa84 Mon Sep 17 00:00:00 2001 From: Andrew Myers Date: Wed, 6 Mar 2024 16:03:23 -0600 Subject: [PATCH] Fix GPU restart for pure SoA particles (#3783) The proposed changes: - [x] fix a bug or incorrect behavior in AMReX - [ ] add new capabilities to AMReX - [ ] changes answers in the test suite to more than roundoff level - [ ] are likely to significantly affect the results of downstream AMReX users - [ ] include documentation in the code and/or rst files, if appropriate --------- Co-authored-by: Weiqun Zhang --- Src/Particle/AMReX_ParticleIO.H | 2 +- Src/Particle/AMReX_WriteBinaryParticleData.H | 61 ++++++++++++++------ 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/Src/Particle/AMReX_ParticleIO.H b/Src/Particle/AMReX_ParticleIO.H index 22c0c5a35f9..27ffb44a904 100644 --- a/Src/Particle/AMReX_ParticleIO.H +++ b/Src/Particle/AMReX_ParticleIO.H @@ -999,7 +999,7 @@ ParticleContainer_impl& idata, Vector& rdata, const PC& pc, int l idata.resize(np*iChunkSize); int num_output_real = 0; - for (int i = 0; i < pc.NumRealComps() + PC::NStructReal; ++i) { + for (int i = 0; i < (int) write_real_comp.size(); ++i) { if (write_real_comp[i]) { ++num_output_real; } } @@ -249,15 +249,18 @@ packIOData (Vector& idata, Vector& rdata, const PC& pc, int l } } - for (int j = 0; j < PC::SuperParticleType::NReal; j++) { - if (write_real_comp_d_ptr[j]) { + // extra SoA Real components + const int real_start_offset = PC::ParticleType::is_soa_particle ? AMREX_SPACEDIM : 0; // pure SoA: skip positions + for (int j = real_start_offset; j < PC::SuperParticleType::NReal; j++) { + const int write_comp_index = j-real_start_offset; + if (write_real_comp_d_ptr[write_comp_index]) { rdata_d_ptr[rout_index] = p.rdata(j); rout_index++; } } for (int j = 0; j < ptd.m_num_runtime_real; j++) { - if (write_real_comp_d_ptr[PC::SuperParticleType::NReal + j]) { + if (write_real_comp_d_ptr[PC::SuperParticleType::NReal+j-real_start_offset]) { rdata_d_ptr[rout_index] = ptd.m_runtime_rdata[j][pindex]; rout_index++; } @@ -336,13 +339,25 @@ packIOData (Vector& idata, Vector& rdata, const PC& pc, int l } } else { - amrex::ignore_unused(is_checkpoint); - // Int: id, cpu uint64_t idcpu = soa.GetIdCPUData()[pindex]; - *iptr = (int) ParticleIDWrapper(idcpu); - iptr += 1; - *iptr = (int) ParticleCPUWrapper(idcpu); - iptr += 1; + if (is_checkpoint) { + std::int32_t xi, yi; + std::uint32_t xu, yu; + xu = (std::uint32_t)((idcpu & 0xFFFFFFFF00000000LL) >> 32); + yu = (std::uint32_t)( idcpu & 0xFFFFFFFFLL); + std::memcpy(&xi, &xu, sizeof(xu)); + std::memcpy(&yi, &yu, sizeof(yu)); + *iptr = xi; + iptr += 1; + *iptr = yi; + iptr += 1; + } else { + // Int: id, cpu + *iptr = (int) ParticleIDWrapper(idcpu); + iptr += 1; + *iptr = (int) ParticleCPUWrapper(idcpu); + iptr += 1; + } // Real: position for (int j = 0; j < AMREX_SPACEDIM; j++) { rptr[j] = soa.GetRealData(j)[pindex]; } @@ -361,8 +376,7 @@ packIOData (Vector& idata, Vector& rdata, const PC& pc, int l // extra SoA Real components const int real_start_offset = PC::ParticleType::is_soa_particle ? AMREX_SPACEDIM : 0; // pure SoA: skip positions for (int j = real_start_offset; j < pc.NumRealComps(); j++) { - const int write_comp_offset = PC::ParticleType::is_soa_particle ? AMREX_SPACEDIM : 0; // pure SoA: skip positions - const int write_comp_index = PC::NStructReal+j-write_comp_offset; + const int write_comp_index = PC::NStructReal+j-real_start_offset; if (write_real_comp[write_comp_index]) { *rptr = (ParticleReal) soa.GetRealData(j)[pindex]; ++rptr; @@ -1032,12 +1046,25 @@ void WriteBinaryParticleDataAsync (PC const& pc, } } else { - // Ints: id, cpu uint64_t idcpu = soa.GetIdCPUData()[pindex]; - *iptr = (int) ParticleIDWrapper(idcpu); - iptr += 1; - *iptr = (int) ParticleCPUWrapper(idcpu); - iptr += 1; + if (is_checkpoint) { + std::int32_t xi, yi; + std::uint32_t xu, yu; + xu = (std::uint32_t)((idcpu & 0xFFFFFFFF00000000LL) >> 32); + yu = (std::uint32_t)( idcpu & 0xFFFFFFFFLL); + std::memcpy(&xi, &xu, sizeof(xu)); + std::memcpy(&yi, &yu, sizeof(yu)); + *iptr = xi; + iptr += 1; + *iptr = yi; + iptr += 1; + } else { + // Int: id, cpu + *iptr = (int) ParticleIDWrapper(idcpu); + iptr += 1; + *iptr = (int) ParticleCPUWrapper(idcpu); + iptr += 1; + } } // extra SoA Ints