@@ -159,6 +159,79 @@ RankSyncParallelSkip::getSignals(int& end, int& usr, int& alrm)
159159 return sig_end_ || sig_usr_ || sig_alrm_;
160160}
161161
162+ void
163+ RankSyncParallelSkip::setShutdownFlags (bool enter_shutdown, Simulation_impl::ShutdownMode_t shutdown_mode)
164+ {
165+ // SKK This must be atomic because it can be set from any thread
166+ // printf("Enter rankSync setFlags: \n input: enter_interactive %d, enter_shutdown %d, shutdown_mode %d \n",
167+ // enter_interactive, enter_shutdown, shutdown_mode);
168+ if (enter_shutdown) {
169+ enter_shutdown_.store (enter_shutdown);
170+ shutdown_mode_.store (static_cast <unsigned >(shutdown_mode));
171+ }
172+ // printf("Exit rankSync setFlags: \n input: enter_interactive %d, enter_shutdown %d, shutdown_mode %d \n",
173+ // enter_interactive_.load(), enter_shutdown_.load(), shutdown_mode_.load());
174+ }
175+
176+
177+ void
178+ RankSyncParallelSkip::setFlags (bool enter_interactive, bool enter_shutdown, Simulation_impl::ShutdownMode_t shutdown_mode)
179+ {
180+ // SKK This must be atomic because it can be set from any thread
181+ // printf("Enter threadSync setFlags: \n input: enter_interactive %d, enter_shutdown %d, shutdown_mode %d \n",
182+ // enter_interactive, enter_shutdown, shutdown_mode);
183+ if (enter_interactive)
184+ enter_interactive_.store (enter_interactive);
185+
186+ setShutdownFlags (enter_shutdown, shutdown_mode);
187+
188+ // printf("Exit threadSync setFlags: \n input: enter_interactive %d, enter_shutdown %d, shutdown_mode %d \n",
189+ // enter_interactive_.load(), enter_shutdown_.load(), shutdown_mode_.load());
190+ }
191+
192+ void
193+ RankSyncParallelSkip::getShutdownFlags ( bool & enter_shutdown, Simulation_impl::ShutdownMode_t& shutdown_mode)
194+ {
195+ enter_shutdown = enter_shutdown_.load ();
196+ switch (shutdown_mode_) {
197+ case 0 :
198+ shutdown_mode = Simulation_impl::ShutdownMode_t::SHUTDOWN_CLEAN;
199+ break ;
200+ case 1 :
201+ shutdown_mode = Simulation_impl::ShutdownMode_t::SHUTDOWN_SIGNAL;
202+ break ;
203+ case 2 :
204+ shutdown_mode = Simulation_impl::ShutdownMode_t::SHUTDOWN_EMERGENCY;
205+ break ;
206+ }
207+
208+ // printf("ExitthreadSync getFlags: \n input: enter_interactive %d, enter_shutdown %d, shutdown_mode %d \n",
209+ // enter_interactive, enter_shutdown, shutdown_mode);
210+ }
211+
212+ void
213+ RankSyncParallelSkip::getFlags ( bool & enter_interactive, bool & enter_shutdown, Simulation_impl::ShutdownMode_t& shutdown_mode)
214+ {
215+
216+ enter_interactive = enter_interactive_.load ();
217+ getShutdownFlags ( enter_shutdown, shutdown_mode);
218+
219+ // printf("ExitthreadSync getFlags: \n input: enter_interactive %d, enter_shutdown %d, shutdown_mode %d \n",
220+ // enter_interactive, enter_shutdown, shutdown_mode);
221+ }
222+
223+ void
224+ RankSyncParallelSkip::clearFlags ()
225+ {
226+ enter_interactive_.store (false );
227+ enter_shutdown_.store (false );
228+ shutdown_mode_.store (0 );
229+
230+ // printf("Clear Flags: enter_interactive %d, enter_shutdown %d, shutdown_mode %d\n",
231+ // enter_interactive_, enter_shutdown_, shutdown_mode_);
232+
233+ }
234+
162235uint64_t
163236RankSyncParallelSkip::getDataSize () const
164237{
@@ -187,6 +260,31 @@ RankSyncParallelSkip::execute(int thread)
187260 }
188261}
189262
263+ void
264+ RankSyncParallelSkip::interactiveExchange ()
265+ {
266+ #ifdef SST_CONFIG_HAVE_MPI
267+ int32_t local_flags[1 ] = { static_cast <int32_t >(enter_interactive_) };
268+ int32_t global_flags[1 ] = { 0 };
269+ MPI_Allreduce (&local_flags, &global_flags, 1 , MPI_INT32_T, MPI_MAX, MPI_COMM_WORLD);
270+
271+ enter_interactive_ = global_flags[0 ];
272+ #endif
273+ }
274+
275+ void
276+ RankSyncParallelSkip::shutdownExchange ()
277+ {
278+ #ifdef SST_CONFIG_HAVE_MPI
279+ int32_t local_flags[2 ] = { static_cast <int32_t >(enter_shutdown_), static_cast <int32_t >(shutdown_mode_) };
280+ int32_t global_flags[2 ] = { 0 , 0 };
281+ MPI_Allreduce (&local_flags, &global_flags, 2 , MPI_INT32_T, MPI_MAX, MPI_COMM_WORLD);
282+
283+ enter_shutdown_ = global_flags[0 ];
284+ shutdown_mode_ = global_flags[1 ];
285+ #endif
286+ }
287+
190288void
191289RankSyncParallelSkip::exchange_slave (int thread)
192290{
@@ -385,6 +483,14 @@ RankSyncParallelSkip::exchange_master(int UNUSED(thread))
385483 sig_usr_ = global_signals[1 ];
386484 sig_alrm_ = global_signals[2 ];
387485
486+ int32_t local_flags[3 ] = { static_cast <int32_t >(enter_interactive_), static_cast <int32_t >(enter_shutdown_), static_cast <int32_t >(shutdown_mode_) };
487+ int32_t global_flags[3 ] = { 0 , 0 , 0 };
488+ MPI_Allreduce (&local_flags, &global_flags, 3 , MPI_INT32_T, MPI_MAX, MPI_COMM_WORLD);
489+
490+ enter_interactive_ = global_flags[0 ];
491+ enter_shutdown_ = global_flags[1 ];
492+ shutdown_mode_ = global_flags[2 ];
493+
388494#endif
389495}
390496
@@ -507,5 +613,8 @@ RankSyncParallelSkip::deserializeMessage(comm_recv_pair* msg)
507613int RankSyncParallelSkip::sig_end_ (0 );
508614int RankSyncParallelSkip::sig_usr_ (0 );
509615int RankSyncParallelSkip::sig_alrm_ (0 );
616+ std::atomic<bool > RankSyncParallelSkip::enter_interactive_ (false );
617+ std::atomic<bool > RankSyncParallelSkip::enter_shutdown_ (false );
618+ std::atomic<unsigned > RankSyncParallelSkip::shutdown_mode_ (0 );
510619
511620} // namespace SST
0 commit comments