Skip to content

Commit 0dbf955

Browse files
committed
WIP: Add support for info current and all
1 parent f1b5e73 commit 0dbf955

File tree

2 files changed

+176
-45
lines changed

2 files changed

+176
-45
lines changed

src/sst/core/impl/interactive/simpleDebug.cc

Lines changed: 173 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ SimpleDebugger::SimpleDebugger(Params& params) :
6464
{ "info", "info", "\"current\"|\"all\" print summary for current thread or all threads",
6565
ConsoleCommandGroup::GENERAL, [this](std::vector<std::string>& tokens) { return cmd_info(tokens); }, true },
6666
{ "thread", "thd", "[threadID]: switch to specified thread ID", ConsoleCommandGroup::GENERAL,
67-
[this](std::vector<std::string>& tokens) { return cmd_thread(tokens); }, false },
67+
[this](std::vector<std::string>& tokens) { return cmd_thread(tokens); }, true },
6868
{ "rank", "rank", "[rankID]: switch to specified rank ID, same thread", ConsoleCommandGroup::GENERAL,
69-
[this](std::vector<std::string>& tokens) { return cmd_rank(tokens); }, false },
69+
[this](std::vector<std::string>& tokens) { return cmd_rank(tokens); }, true },
7070
{ "confirm", "cfm", "<true/false>: set confirmation requests on (default) or off", ConsoleCommandGroup::GENERAL,
7171
[this](std::vector<std::string>& tokens) { return cmd_setConfirm(tokens); }, true },
7272
{ "pwd", "pwd", "print the current working directory in the object map", ConsoleCommandGroup::NAVIGATION,
@@ -475,7 +475,7 @@ SimpleDebugger::dispatch_cmd(std::string& cmd)
475475
// Execute in this rank (multithreading)
476476
// Add handle multithreading here
477477
//succeed = consoleCommand.first.exec(tokens);
478-
handleCommandAll();
478+
handleCommand();
479479

480480
} else {
481481
// Send to remote rank
@@ -623,8 +623,16 @@ SimpleDebugger::cmd_verbose(std::vector<std::string>& tokens)
623623
return true;
624624
}
625625

626+
void
627+
SimpleDebugger::threadInfo() {
628+
RankInfo info = getRank();
629+
RankInfo nRanks = getNumRanks();
630+
std::cout << "Rank " << info.rank << "/" << nRanks.rank << ", Thread " << info.thread << "/" << nRanks.thread
631+
<< " (Process " << getppid() << ")" << std::endl;
632+
}
633+
626634
bool
627-
SimpleDebugger::cmd_info(std::vector<std::string>& UNUSED(tokens))
635+
SimpleDebugger::cmd_info(std::vector<std::string>& tokens)
628636
{
629637

630638
if ( tokens.size() != 2 ) {
@@ -634,26 +642,66 @@ SimpleDebugger::cmd_info(std::vector<std::string>& UNUSED(tokens))
634642

635643
RankInfo info = getRank();
636644
RankInfo nRanks = getNumRanks();
645+
646+
#if 1
647+
// SKK Must be executed by target rank because otherwise the process ID won't be correct
637648
if ( tokens[1] == "current" ) {
649+
if (current_rank == 0) {
650+
tokens.clear();
651+
tokens[0] = "threadInfo";
652+
handleCommand();
653+
} else {
654+
std::string cmd = "threadInfo";
655+
sendCommand(current_rank, current_thread, cmd);
656+
}
657+
}
658+
else if (tokens[1] == "all") {
659+
// Print info for rank 0
660+
int32_t orig_thread = current_thread;
661+
tokens.clear();
662+
tokens[0] = "threadInfoAll";
663+
for ( current_thread = 0; current_thread < nRanks.thread; current_thread++ ) {
664+
handleCommand();
665+
}
666+
current_thread == orig_thread;
667+
668+
// Print info for other ranks
669+
std::string cmd = "threadInfoAll";
670+
for ( int32_t rank_id = 0; rank_id < nRanks.rank; rank_id++ ) {
671+
sendCommand(rank_id, 0, cmd);
672+
}
673+
}
674+
else {
675+
printf("Invalid argument for info command: %s (info \"current\"|\"all\")\n", tokens[1].c_str());
676+
return false;
677+
}
638678

639-
std::cout << "Rank " << current_rank << "/" << nRanks.rank << ", Thread " << current_thread << "/" << nRanks.thread
679+
#else
680+
// SKK Must be executed by target rank because otherwise the process ID won't be correct
681+
if ( tokens[1] == "current" ) {
682+
std::cout << "Rank " << info.rank << "/" << nRanks.rank << ", Thread " << info.thread << "/" << nRanks.thread
640683
<< " (Process " << getppid() << ")" << std::endl;
684+
641685
}
642686
else if ( tokens[1] == "all" ) { // SKK Need to update this for multi-rank
687+
643688
if ( nRanks.rank == 1 && nRanks.thread == 1 ) {
644689
std::cout << "Rank " << info.rank << "/" << nRanks.rank << ", Thread " << info.thread << "/"
645690
<< nRanks.thread << " (Process " << getppid() << ")" << std::endl;
646691
}
647692
else {
693+
// Need to send to ALL ranks and have each rank print all threads
648694
// Return to syncmanager to print summary for all threads
649695
retState = SUMMARY; // summary info
650696
done = true;
651697
}
698+
652699
}
653700
else {
654701
printf("Invalid argument for info command: %s (info \"current\"|\"all\")\n", tokens[1].c_str());
655702
return false;
656703
}
704+
#endif
657705
return true;
658706
}
659707

@@ -693,9 +741,13 @@ SimpleDebugger::cmd_thread(std::vector<std::string>& tokens)
693741
#if 1
694742
// Set current thread
695743
if ( threadID != current_thread ) {
696-
current_thread = threadID;
697-
// May also need to do something to update the listings
698-
// and object map for the first time through
744+
current_thread = threadID;
745+
746+
// Send to other ranks
747+
// Loop like sendDone. Can I share this somehow?
748+
// change send DONE to sendCommandAll and just add cmd string?
749+
//std::stringstream ss << tokens[0] << " " << tokens[1];
750+
//sendCommandAll(ss.str());
699751
}
700752
#else
701753
// If not current thread, set retState and done flag
@@ -746,6 +798,8 @@ SimpleDebugger::cmd_rank(std::vector<std::string>& tokens)
746798
current_rank = rankID;
747799
// May also need to do something to update the listings
748800
// and object map for the first time through
801+
//std::stringstream ss << tokens[0] << " " << tokens[1];
802+
//sendCommandAll(ss.str());
749803
}
750804
#endif
751805
return true;
@@ -2396,7 +2450,8 @@ CommandRegistry::addHelp(std::string key, std::vector<std::string>& vec)
23962450
// Test new rank execute structure
23972451

23982452
bool
2399-
SimpleDebugger::handleCommandAll()
2453+
SimpleDebugger::handleCommand()
2454+
//(int32_t rank_id, int32_t thread_id)
24002455
{
24012456

24022457
RankInfo num_ranks_ = Simulation_impl::getSimulation()->getNumRanks();
@@ -2406,34 +2461,59 @@ SimpleDebugger::handleCommandAll()
24062461

24072462
// Wait for shared variables to be stored by T0 (unpack and tokenize)
24082463
exchange_barrier.wait();
2409-
// Get shared variables
2410-
//int32_t cmd_local = cmd.load();
2411-
//int32_t tid_local = tid.load();
24122464
bool succeed = true; // Change to false once debugged
24132465

24142466
if (tokens[0] == "done") {
24152467
done = true;
24162468
}
2469+
2470+
if (tokens[0] == "threadInfo" || tokens[0] == "threadInfoAll") {
2471+
if (rank_.thread == current_thread) {
2472+
#if 1
2473+
Output::getDefaultObject().output("**HandleCommand tinfo: R%d, T%d\n", rank_.rank, rank_.thread);
2474+
for (const std::string& token : tokens) {
2475+
Output::getDefaultObject().output(" %s", token.c_str());
2476+
}
2477+
Output::getDefaultObject().output("\n");
2478+
#endif
2479+
if (obj_ == nullptr) {
2480+
// Create a new ObjectMap
2481+
obj_ = getComponentObjectMap();
2482+
// Descend into the name_stack
2483+
cd_name_stack();
2484+
}
2485+
threadInfo();
2486+
result << "**Worker threadInfo: R" << rank_.rank << ", T" << rank_.thread << "\n";
2487+
2488+
} else {
2489+
//Output::getDefaultObject().output("Other threads do nothing\n");
2490+
}
2491+
2492+
}
24172493

24182494
// If not DONE, process command
2419-
if (!done) {
2495+
else if (!done) {
24202496
// If I am target thread, handle the incoming command
24212497
if (rank_.thread == current_thread) {
2422-
#if 0
2423-
//result.store(1);
2424-
result << "**Worker PRINT: R" << rank_.rank << ", T" << rank_.thread << "\n";
2425-
//Output::getDefaultObject().output("**Worker PRINT: R%d, T%d\n", rank_.rank, rank_.thread);
2426-
#else
2427-
Output::getDefaultObject().output("**HandleCommand: R%d, T%d\n",
2428-
rank_.rank, rank_.thread, tokens[0].c_str());
2498+
#if 1
2499+
Output::getDefaultObject().output("**HandleCommand: R%d, T%d\n", rank_.rank, rank_.thread);
24292500
for (const std::string& token : tokens) {
24302501
Output::getDefaultObject().output(" %s", token.c_str());
24312502
}
24322503
Output::getDefaultObject().output("\n");
2504+
#endif
2505+
2506+
if (obj_ == nullptr) {
2507+
// Create a new ObjectMap
2508+
obj_ = getComponentObjectMap();
2509+
// Descend into the name_stack
2510+
cd_name_stack();
2511+
}
24332512
auto consoleCommand = cmdRegistry.seek(tokens[0], CommandRegistry::SEARCH_TYPE::BUILTIN);
2513+
//Output::getDefaultObject().output("**HandleCommand: R%d, T%d\n", rank_.rank, rank_.thread);
24342514
succeed = consoleCommand.first.exec(tokens);
24352515
result << "**Worker CMD: R" << rank_.rank << ", T" << rank_.thread << "\n";
2436-
#endif
2516+
24372517
}
24382518
} else { // DONE
24392519
//result.store(0);
@@ -2510,6 +2590,7 @@ SimpleDebugger::sendCommand( int32_t rank_id, int32_t thread_id, std::string cm
25102590
void
25112591
SimpleDebugger::receiveCommand() {
25122592
//const int default_size = 100;
2593+
RankInfo num_ranks_ = Simulation_impl::getSimulation()->getNumRanks();
25132594
char* cmd_buffer;
25142595
int buf_size;
25152596
int position = 0;
@@ -2539,40 +2620,41 @@ SimpleDebugger::receiveCommand() {
25392620
MPI_Unpack(cmd_buffer, buf_size, &position, cmd_str, str_length, MPI_CHAR, MPI_COMM_WORLD);
25402621
//Output::getDefaultObject().output("Received: R%d, T%d, Sz%d, %s\n",
25412622
// rank_id, thread_id, str_length, cmd_str);
2542-
// Target thread processes command
2543-
2544-
// Create a new ObjectMap
2545-
// SKK this needs thought
2546-
// At a minimum need to get objmap the first time we enter thread
2547-
// may need to always do this?
2548-
if (obj_ == nullptr) {
2549-
obj_ = getComponentObjectMap();
2550-
2551-
// Descend into the name_stack
2552-
cd_name_stack();
2553-
}
2554-
// Tokenize
2555-
//std::vector<std::string> tokens; // SKK shared so all threads can access
2623+
current_rank = rank_id;
2624+
current_thread = thread_id;
2625+
2626+
// Tokenize cmd string (shared so all threads can access)
25562627
std::string cmd(cmd_str);
25572628
tokenize(tokens, cmd);
25582629

2559-
// Exec command fcn
2630+
// Set done for all threads
25602631
if (tokens[0] == "done") {
2561-
handleCommandAll();
2562-
} else {
2632+
handleCommand();
2633+
}
2634+
// Execute command for all threads
2635+
else if (tokens[0] == "threadInfo") {
2636+
handleCommand();
2637+
}
2638+
else if (tokens[0] == "threadInfoAll") {
2639+
for ( current_thread = 0; current_thread < num_ranks_.thread; current_thread++ ) {
2640+
handleCommand();
2641+
}
2642+
}
2643+
// Execute command for target thread
2644+
else {
25632645
auto consoleCommand = cmdRegistry.seek(tokens[0], CommandRegistry::SEARCH_TYPE::BUILTIN);
25642646
if ( consoleCommand.second ) {
25652647
if (consoleCommand.first.console()) {
25662648
// Console command, execute in this thread
2567-
Output::getDefaultObject().output("Error: Console command at remote rank: %s\n", tokens[0]);
2649+
Output::getDefaultObject().output("Error: Console command at remote rank: %s\n", tokens[0].c_str());
25682650
assert(false);
25692651
} else {
25702652
// Thread specific command, execute in target thread
25712653
//bool succeed = consoleCommand.first.exec(tokens);
2572-
handleCommandAll();
2654+
handleCommand();
25732655
}
25742656
} else {
2575-
Output::getDefaultObject().output("Error: Command not found in remote rank: %s\n", tokens[0]);
2657+
Output::getDefaultObject().output("Error: Command not found in remote rank: %s\n", tokens[0].c_str());
25762658
assert(false);
25772659
}
25782660
}
@@ -2581,10 +2663,57 @@ SimpleDebugger::receiveCommand() {
25812663
char* result_buffer;
25822664
buf_size = packResultBuffer(result, &result_buffer);
25832665
MPI_Send(result_buffer, buf_size, MPI_CHAR, dst, tag, MPI_COMM_WORLD);
2584-
Output::getDefaultObject().output("After R1T0 send\n");
2666+
//Output::getDefaultObject().output("After R1T0 send\n");
25852667

25862668
}
25872669

2670+
#if 0
2671+
void
2672+
SimpleDebugger::sendCommandAll(std::string cmd) {
2673+
RankInfo num_ranks_ = Simulation_impl::getSimulation()->getNumRanks();
2674+
RankInfo rank_ = Simulation_impl::getSimulation()->getRank();
2675+
char* cmd_buffer; // SKK Could share buffer
2676+
int str_length;
2677+
int buf_size;
2678+
int position = 0;
2679+
int tag = 0;
2680+
MPI_Status status;
2681+
char* result_buffer;
2682+
2683+
// Pack and Send message
2684+
str_length = cmd.length() + 1;
2685+
buf_size = 3 * sizeof(int32_t) + str_length;
2686+
cmd_buffer = (char*) malloc(buf_size);
2687+
2688+
int32_t thread_id = 0;
2689+
for (uint32_t rank_id = 1; rank_id < num_ranks_.rank; rank_id++ ) {
2690+
Output::getDefaultObject().output("sendCmdAll: R%d, T%d, bufsize: %d, strlen: %d, cmd: %s\n",
2691+
rank_id, thread_id, buf_size, str_length, cmd.c_str());
2692+
// Pack rank_id, thread_id, cmd str length, and cmd string
2693+
MPI_Pack(&rank_id, 1, MPI_INT32_T, cmd_buffer, buf_size, &position, MPI_COMM_WORLD);
2694+
MPI_Pack(&thread_id, 1, MPI_INT32_T, cmd_buffer, buf_size, &position, MPI_COMM_WORLD);
2695+
MPI_Pack(&str_length, 1, MPI_INT32_T, cmd_buffer, buf_size, &position, MPI_COMM_WORLD);
2696+
MPI_Pack(cmd.c_str(), str_length, MPI_CHAR, cmd_buffer, buf_size, &position, MPI_COMM_WORLD);
2697+
// Send command buffer to destination rank
2698+
//Output::getDefaultObject().output("After R0T0 pack: R%d, T%d, position:%d\n",
2699+
// rank_id, thread_id, position);
2700+
MPI_Send(cmd_buffer, position, MPI_PACKED, rank_id, tag, MPI_COMM_WORLD);
2701+
//Output::getDefaultObject().output("After R0T0 send: R%d, T%d, position:%d\n",
2702+
// rank_id, thread_id, position);
2703+
2704+
// Receive result string
2705+
// Probe for incoming message to get its length
2706+
MPI_Probe(rank_id, tag, MPI_COMM_WORLD, &status);
2707+
// Get the actual number of elements (characters)
2708+
MPI_Get_count(&status, MPI_CHAR, &buf_size);
2709+
result_buffer = (char*) malloc(buf_size * sizeof(char));
2710+
//Output::getDefaultObject().output("After R0T0 probe: bufsize: %d\n", buf_size);
2711+
MPI_Recv(result_buffer, buf_size, MPI_CHAR, rank_id, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
2712+
//Output::getDefaultObject().output("Result: %s", result_buffer);
2713+
} // End for each rank
2714+
}
2715+
#endif
2716+
25882717
void
25892718
SimpleDebugger::sendDone() {
25902719
RankInfo num_ranks_ = Simulation_impl::getSimulation()->getNumRanks();
@@ -2675,7 +2804,7 @@ SimpleDebugger::execute(const std::string& msg)
26752804
// Set done in local rank threads
26762805
tokens.clear();
26772806
tokens[0] = "done";
2678-
handleCommandAll();
2807+
handleCommand();
26792808

26802809
// Send done to remote ranks
26812810
sendDone();
@@ -2700,7 +2829,7 @@ SimpleDebugger::execute(const std::string& msg)
27002829

27012830
//while (!quit) {
27022831
while (!done) {
2703-
handleCommandAll();
2832+
handleCommand();
27042833
}
27052834
//Output::getDefaultObject().output("**Worker R%d T%d Exit Loop\n",
27062835
// rank_.rank, rank_.thread);

src/sst/core/impl/interactive/simpleDebug.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ class SimpleDebugger : public SST::InteractiveConsole
387387
//static Core::ThreadSafe::Barrier exchange_barrier;
388388
//static Core::ThreadSafe::Barrier process_barrier;
389389
390-
bool handleCommandAll();
390+
bool handleCommand();
391391
//bool handleCommandAll(std::atomic<int32_t>& tid, std::atomic<int32_t>& cmd, std::stringstream& result,
392392
// Core::ThreadSafe::Barrier& exchange_barrier, Core::ThreadSafe::Barrier& process_barrier);
393393
int packResultBuffer( std::stringstream& result, char** result_buffer);
@@ -396,8 +396,10 @@ class SimpleDebugger : public SST::InteractiveConsole
396396
//void rankParallelExecute();
397397
int consoleExecute(const std::string& msg);
398398
void sendCommand( int32_t rank_id, int32_t thread_id, std::string cmd);
399+
//void sendCommandAll(std::string cmd);
399400
void receiveCommand();
400401
void sendDone();
402+
void threadInfo();
401403
};
402404
403405
} // namespace SST::IMPL::Interactive

0 commit comments

Comments
 (0)