@@ -647,4 +647,106 @@ std::atomic<bool> RankSyncParallelSkip::enter_shutdown_(false);
647647std::atomic<unsigned > RankSyncParallelSkip::shutdown_mode_ (0 );
648648std::atomic<bool > RankSyncParallelSkip::generate_ckpt_ (false );
649649
650+ // SKK Test Producer Consumer
651+ int32_t RankSyncParallelSkip::test_rid_ (0 );
652+ int32_t RankSyncParallelSkip::test_tid_ (0 );
653+ int32_t RankSyncParallelSkip::test_cmd_ (0 ); // 0 = DONE, 1 = PRINT
654+
655+ void
656+ RankSyncParallelSkip::testManager ()
657+ {
658+ #ifdef SST_CONFIG_HAVE_MPI
659+ RankInfo rank_ = Simulation_impl::getSimulation ()->getRank ();
660+ int32_t cmd_buffer[3 ];
661+ int32_t result_buffer[1 ];
662+ int tag = 0 ;
663+ int src;
664+ int dst;
665+
666+ // Static variables shared between threads within the rank
667+ static std::atomic<int32_t > tid = 0 ;
668+ static std::atomic<int32_t > cmd = 0 ;
669+ static std::atomic<bool > done = false ;
670+ static std::atomic<int32_t > result = 0 ;
671+ static Core::ThreadSafe::Barrier exchange_barrier (num_ranks_.thread );
672+
673+ Output::getDefaultObject ().output (" ----ParallelSkip\n " );
674+
675+ if (rank_.rank == 0 && rank_.thread == 0 ) { // Handles send of commands
676+ // Send print command to all ranks/threads
677+ cmd_buffer[2 ] = 1 ; // PRINT
678+ for (uint32_t rindex = 1 ; rindex < num_ranks_.rank ; rindex++ ) {
679+ for ( uint32_t tindex = 0 ; tindex < num_ranks_.thread ; tindex++ ) {
680+ Output::getDefaultObject ().output (" **Mgr R%d T%d Send PRINT: Dest R%d, T%d\n " ,
681+ rank_.rank , rank_.thread , rindex, tindex);
682+ // Send print command to correct rank and wait for return
683+ cmd_buffer[0 ] = rindex;
684+ cmd_buffer[1 ] = tindex;
685+ dst = rindex;
686+ MPI_Send (cmd_buffer, 3 , MPI_INT32_T, dst, tag, MPI_COMM_WORLD );
687+ src = rindex;
688+ MPI_Recv (result_buffer, 1 , MPI_INT32_T, src, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
689+ assert (result_buffer[0 ] == 1 );
690+ } // for Threads
691+ } // for Ranks
692+ // Send done command to all ranks (can't use Bcast bc others don't know its coming)
693+ cmd_buffer[2 ] = 0 ; // DONE
694+ for (uint32_t rindex = 1 ; rindex < num_ranks_.rank ; rindex++ ) {
695+ Output::getDefaultObject ().output (" **Mgr R%d T%d Send DONE: Dest R%d\n " ,
696+ rank_.rank , rank_.thread , rindex);
697+ // Send done command to correct rank and wait for return
698+ cmd_buffer[0 ] = rindex;
699+ cmd_buffer[1 ] = 0 ;
700+ dst = rindex;
701+ MPI_Send (cmd_buffer, 3 , MPI_INT32_T, dst, tag, MPI_COMM_WORLD);
702+ } // for Ranks
703+
704+ } // end rank 0, thread 0
705+ else if (rank_.rank != 0 ) { // Other ranks
706+ Output::getDefaultObject ().output (" **Enter Worker: Rank:%d, Thread:%d\n " , rank_.rank , rank_.thread );
707+ src = 0 ;
708+ dst = 0 ;
709+ tag = 0 ;
710+ while (!done.load ()) {
711+ if (rank_.thread == 0 ) {
712+ MPI_Recv (cmd_buffer, 3 , MPI_INT32_T, src, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
713+ Output::getDefaultObject ().output (" **Worker R%d T%d Recv: R%d, T%d cmd%d\n " ,
714+ rank_.rank , rank_.thread , cmd_buffer[0 ], cmd_buffer[1 ], cmd_buffer[2 ]);
715+ tid.store (cmd_buffer[1 ]);
716+ cmd.store (cmd_buffer[2 ]);
717+ if (cmd_buffer[2 ] == 0 ) { // DONE
718+ done.store (true );
719+ Output::getDefaultObject ().output (" **Worker DONE: R%d, T%d\n " , rank_.rank , rank_.thread );
720+ }
721+ }
722+
723+ // Barrier before loading shared variables
724+ exchange_barrier.wait ();
725+
726+ // Not DONE, process command
727+ if (cmd.load () != 0 ) {
728+ if (rank_.thread == tid.load ()) {
729+ result.store (1 );
730+ Output::getDefaultObject ().output (" **Worker PRINT: R%d, T%d\n " , rank_.rank , rank_.thread );
731+ }
732+ // Wait to access result
733+ exchange_barrier.wait ();
734+ // Thread 0 sends cmd result back to Rank 0
735+ if (rank_.thread == 0 ) {
736+ result_buffer[0 ] = result.load ();
737+ MPI_Send (result_buffer, 1 , MPI_INT32_T, dst, tag, MPI_COMM_WORLD);
738+ Output::getDefaultObject ().output (" **Worker R%d T%d Send: R%d, T%d\n " ,
739+ rank_.rank , rank_.thread , cmd_buffer[0 ], cmd_buffer[1 ]);
740+ }
741+ }
742+
743+ } // while !done
744+ } // end other ranks
745+ else { // other R0 threads, do nothing for now
746+ Output::getDefaultObject ().output (" **Enter NOP: R%d, T%d\n " , rank_.rank , rank_.thread );
747+ } // other R0 threads
748+ #endif
749+ }
750+
751+
650752} // namespace SST
0 commit comments