@@ -263,7 +263,14 @@ void ParticleCopyPlan::doHandShake (const Vector<Long>& Snds, Vector<Long>& Rcvs
263263{
264264 BL_PROFILE (" ParticleCopyPlan::doHandShake" );
265265 if (m_local) { doHandShakeLocal (Snds, Rcvs); }
266- else { doHandShakeGlobal (Snds, Rcvs); }
266+ else if (m_do_one_sided_comms) {
267+ #if defined(BL_USE_MPI3)
268+ doHandShakeOneSided (Snds, Rcvs);
269+ #else
270+ amrex::Abort (" ParticleCopyPlan::doHandShake: particles.do_one_sided_comms=1 requires MPI-3" );
271+ #endif
272+ }
273+ else { doHandShakeReduceScatter (Snds, Rcvs); }
267274}
268275
269276void ParticleCopyPlan::doHandShakeLocal (const Vector<Long>& Snds, Vector<Long>& Rcvs) const // NOLINT(readability-convert-member-functions-to-static)
@@ -333,7 +340,7 @@ void ParticleCopyPlan::doHandShakeAllToAll (const Vector<Long>& Snds, Vector<Lon
333340#endif
334341}
335342
336- void ParticleCopyPlan::doHandShakeGlobal (const Vector<Long>& Snds, Vector<Long>& Rcvs)
343+ void ParticleCopyPlan::doHandShakeReduceScatter (const Vector<Long>& Snds, Vector<Long>& Rcvs)
337344{
338345#ifdef AMREX_USE_MPI
339346 const int SeqNum = ParallelDescriptor::SeqNum ();
@@ -381,6 +388,50 @@ void ParticleCopyPlan::doHandShakeGlobal (const Vector<Long>& Snds, Vector<Long>
381388#endif
382389}
383390
391+ void ParticleCopyPlan::doHandShakeOneSided (const Vector<Long>& Snds, Vector<Long>& Rcvs)
392+ {
393+ #if defined(AMREX_USE_MPI) && defined(BL_USE_MPI3)
394+ const int MyProc = ParallelContext::MyProcSub ();
395+ const int NProcs = ParallelContext::NProcsSub ();
396+
397+ AMREX_ALWAYS_ASSERT (static_cast <int >(Snds.size ()) == NProcs);
398+ AMREX_ALWAYS_ASSERT (static_cast <int >(Rcvs.size ()) == NProcs);
399+
400+ std::fill (Rcvs.begin (), Rcvs.end (), 0 );
401+
402+ MPI_Win win;
403+ BL_MPI_REQUIRE (MPI_Win_create (Rcvs.dataPtr (),
404+ static_cast <MPI_Aint>(NProcs*sizeof (Long)),
405+ sizeof (Long),
406+ MPI_INFO_NULL,
407+ ParallelContext::CommunicatorSub (),
408+ &win));
409+
410+ BL_MPI_REQUIRE (MPI_Win_fence (0 , win));
411+
412+ for (int i = 0 ; i < NProcs; ++i)
413+ {
414+ if (i == MyProc || Snds[i] == 0 ) { continue ; }
415+
416+ BL_MPI_REQUIRE (MPI_Put (&Snds[i],
417+ 1 ,
418+ ParallelDescriptor::Mpi_typemap<Long>::type (),
419+ i,
420+ MyProc,
421+ 1 ,
422+ ParallelDescriptor::Mpi_typemap<Long>::type (),
423+ win));
424+ }
425+
426+ BL_MPI_REQUIRE (MPI_Win_fence (0 , win));
427+ BL_MPI_REQUIRE (MPI_Win_free (&win));
428+
429+ AMREX_ASSERT (Rcvs[MyProc] == 0 );
430+ #else
431+ amrex::ignore_unused (Snds,Rcvs);
432+ #endif
433+ }
434+
384435void communicateParticlesFinish (const ParticleCopyPlan& plan)
385436{
386437 BL_PROFILE (" amrex::communicateParticlesFinish" );
0 commit comments