Skip to content

Commit 59c02c7

Browse files
committed
WIP: parallel support for interactive console
1 parent 48ea028 commit 59c02c7

File tree

11 files changed

+481
-49
lines changed

11 files changed

+481
-49
lines changed

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

Lines changed: 126 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ SimpleDebugger::SimpleDebugger(Params& params) :
4949
[this](std::vector<std::string>& tokens) { cmd_verbose(tokens); } },
5050
{ "rankinfo", "ri", "print current rank and thread IDs", ConsoleCommandGroup::GENERAL,
5151
[this](std::vector<std::string>& tokens) { cmd_rankInfo(tokens); } },
52+
{ "info", "info", "\"current\"|\"all\" print summary for current thread or all threads", ConsoleCommandGroup::GENERAL,
53+
[this](std::vector<std::string>& tokens) { cmd_info(tokens); } },
54+
{ "thread", "thd", "[threadID]: switch to specified thread ID", ConsoleCommandGroup::GENERAL,
55+
[this](std::vector<std::string>& tokens) { cmd_thread(tokens); } },
5256
{ "confirm", "cfm", "<true/false>: set confirmation requests on (default) or off", ConsoleCommandGroup::GENERAL,
5357
[this](std::vector<std::string>& tokens) { cmd_setConfirm(tokens); } },
5458
{ "pwd", "pwd", "print the current working directory in the object map", ConsoleCommandGroup::NAVIGATION,
@@ -195,22 +199,59 @@ SimpleDebugger::~SimpleDebugger()
195199
}
196200

197201
void
202+
SimpleDebugger::summary()
203+
{
204+
#if 0
205+
RankInfo info = getRank();
206+
RankInfo nRanks = getNumRanks();
207+
std::count << "\n(Rank:" << info.rank << " / " << nRanks.rank
208+
<< " Thread:" << info.thread << "/" << nRanks.thread
209+
<< ")\n";
210+
std::cout << "-- Trigger Status\n";
211+
#endif
212+
213+
std::cout << "-- Component Summary\n";
214+
#if 0
215+
std::vector<std::string> tokens;
216+
if (nullptr == obj_) {
217+
obj_ = getComponentObjectMap();
218+
}
219+
cmd_ls(tokens);
220+
#else
221+
SST::Core::Serialization::ObjectMap* baseObj = getComponentObjectMap();
222+
auto& vars = baseObj->getVariables();
223+
for (auto& x : vars) {
224+
if (x.second->isFundamental()) {
225+
std::cout << x.first << " = " << x.second->get() << " (" << x.second->getType() << ")" << std::endl;
226+
}
227+
else {
228+
std::cout << x.first.c_str() << "/ (" << x.second->getType() << ")\n";
229+
}
230+
}
231+
#endif
232+
}
233+
234+
int
198235
SimpleDebugger::execute(const std::string& msg)
199236
{
200-
printf("Entering interactive mode at time %" PRI_SIMTIME " \n", getCurrentSimCycle());
237+
RankInfo info = getRank();
238+
RankInfo nRanks = getNumRanks();
239+
printf("\n---- Rank%d:Thread%d: Entering interactive mode at time %" PRI_SIMTIME " \n", info.rank, info.thread, getCurrentSimCycle());
201240
printf("%s\n", msg.c_str());
202241

203242
if ( nullptr == obj_ ) {
204243
obj_ = getComponentObjectMap();
205244
}
206245
done = false;
246+
retState = -1;
247+
207248

208249
std::string line;
209250
while ( !done ) {
210251

211252
try {
212253
// User input prompt
213-
std::cout << "> " << std::flush;
254+
std::cout << "R" << info.rank << ":T" << info.thread << "> " << std::flush;
214255

215256
if ( !injectedCommand.str().empty() ) {
216257
// Injected command stream (currently just one command)
@@ -252,6 +293,7 @@ SimpleDebugger::execute(const std::string& msg)
252293
std::cout << "Parsing error. Ignoring " << line << std::endl;
253294
}
254295
}
296+
return retState;
255297
}
256298

257299
// Invoke the command.
@@ -397,6 +439,7 @@ SimpleDebugger::cmd_verbose(std::vector<std::string>& tokens)
397439
}
398440
}
399441

442+
void
400443
SimpleDebugger::cmd_rankInfo(std::vector<std::string>& UNUSED(tokens)) {
401444

402445
RankInfo info = getRank();
@@ -405,6 +448,77 @@ SimpleDebugger::cmd_rankInfo(std::vector<std::string>& UNUSED(tokens)) {
405448
<< ", Thread " << info.thread << "/" << nRanks.thread << std::endl;
406449
}
407450

451+
void
452+
SimpleDebugger::cmd_info(std::vector<std::string>& UNUSED(tokens)) {
453+
454+
if (tokens.size() != 2) {
455+
printf("Invalid format for info command (info \"current\"|\"all\")\n");
456+
return;
457+
}
458+
459+
RankInfo info = getRank();
460+
RankInfo nRanks = getNumRanks();
461+
if (tokens[1] == "current") {
462+
std::cout << "Rank " << info.rank << "/" << nRanks.rank
463+
<< ", Thread " << info.thread << "/" << nRanks.thread << std::endl;
464+
}
465+
else if (tokens[1] == "all") {
466+
if (nRanks.rank == 1 && nRanks.thread == 1) {
467+
std::cout << "Rank " << info.rank << "/" << nRanks.rank
468+
<< ", Thread " << info.thread << "/" << nRanks.thread << std::endl;
469+
}
470+
else {
471+
// Return to syncmanager to print summary for all threads
472+
retState = -2; // summary info
473+
done = true;
474+
}
475+
}
476+
else {
477+
printf("Invalid argument for info command: %s (info \"current\"|\"all\")\n", tokens[1].c_str());
478+
return;
479+
}
480+
}
481+
482+
// thread <threadID> : switches to new thread
483+
void
484+
SimpleDebugger::cmd_thread(std::vector<std::string>& tokens) {
485+
486+
if (tokens.size() != 2) {
487+
printf("Invalid format for thread command (thread <threadID>)\n");
488+
return;
489+
}
490+
491+
RankInfo info = getRank();
492+
RankInfo nRanks = getNumRanks();
493+
int threadID;
494+
495+
// Get threadID
496+
try {
497+
threadID = std::stoi(tokens[1]);
498+
}
499+
catch (const std::invalid_argument& e) {
500+
std::cout << "Invalid argument for threadID: " << tokens[1] << std::endl;
501+
return;
502+
}
503+
catch (const std::out_of_range& e) {
504+
std::cout << "Out of range for threadID: " << tokens[1] << std::endl;
505+
return;
506+
}
507+
508+
// Check if valid threadID
509+
if (threadID < 0 || threadID >= nRanks.thread) {
510+
printf("ThreadID %d out of range (0:%d)\n", threadID, nRanks.thread-1);
511+
return;
512+
}
513+
514+
// If not current thread, set retState and done flag
515+
if (threadID != info.thread) {
516+
retState = threadID;
517+
done = true;
518+
}
519+
return;
520+
}
521+
408522

409523
// pwd: print current working directory
410524
void
@@ -457,10 +571,20 @@ SimpleDebugger::get_listing_strings(std::list<std::string>& list)
457571
void
458572
SimpleDebugger::cmd_cd(std::vector<std::string>& tokens)
459573
{
574+
#if 0
460575
if ( tokens.size() != 2 ) {
461576
printf("Invalid format for cd command (cd <obj>)\n");
462577
return;
463578
}
579+
#else
580+
// skk This works but does it leave anything hanging around?
581+
// I see in objmap selectParent it does a deactivate, so not sure if I need
582+
// to deactivate everything on the way back up the hierarchy.
583+
if (tokens.size() == 1) {
584+
obj_ = getComponentObjectMap();
585+
return;
586+
}
587+
#endif
464588

465589
// Allow for trailing '/'
466590
std::string selection = tokens[1];

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ class SimpleDebugger : public SST::InteractiveConsole
137137
explicit SimpleDebugger(Params& params);
138138
~SimpleDebugger();
139139
140-
void execute(const std::string& msg) override;
140+
int execute(const std::string& msg) override;
141+
void summary() override;
141142
142143
// Callbacks from command line completions
143144
void get_listing_strings(std::list<std::string>&);
@@ -152,6 +153,7 @@ class SimpleDebugger : public SST::InteractiveConsole
152153
153154
SST::Core::Serialization::ObjectMap* obj_ = nullptr;
154155
bool done = false;
156+
int retState = -1; // -1 done, positive number is threadID
155157
156158
bool autoCompleteEnable = true;
157159
@@ -182,6 +184,8 @@ class SimpleDebugger : public SST::InteractiveConsole
182184
void cmd_help(std::vector<std::string>& UNUSED(tokens));
183185
void cmd_verbose(std::vector<std::string>& (tokens));
184186
void cmd_rankInfo(std::vector<std::string>& UNUSED(tokens));
187+
void cmd_info(std::vector<std::string>& UNUSED(tokens));
188+
void cmd_thread(std::vector<std::string>& tokens);
185189
void cmd_pwd(std::vector<std::string>& UNUSED(tokens));
186190
void cmd_ls(std::vector<std::string>& UNUSED(tokens));
187191
void cmd_cd(std::vector<std::string>& tokens);

src/sst/core/interactiveAction.h

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "sst/core/action.h"
1616
// Can include this because this header is not installed
1717
#include "sst/core/simulation_impl.h"
18+
#include "sst/core/interactiveConsole.h"
1819

1920
#include <string>
2021

@@ -31,26 +32,68 @@ class InteractiveAction : public Action
3132
Create a new InteractiveAction object for the simulation core to initiate interactive mode
3233
*/
3334
InteractiveAction(Simulation_impl* sim, const std::string& msg) :
34-
Action(),
3535
sim_(sim),
3636
msg_(msg)
3737
{
3838
setPriority(INTERACTIVEPRIOIRTY);
3939
}
4040

4141
~InteractiveAction() {}
42+
#if 1
43+
/**
44+
Indicates InteractiveAction should be inserted into the
45+
TimeVortex. The insertion will only happen for serial runs, as
46+
InteractiveAction is managed by the SyncManager in parallel
47+
runs.
48+
*/
49+
void insertIntoTimeVortex(SimTime_t time) {
50+
// If this is a serial job, insert this into
51+
// the time TimeVortex. If it is parallel, then the
52+
// InteractiveAction is managed by the SyncManager.
53+
//std::cout << "skk: insertIntoTimeVortex called\n";
54+
RankInfo num_ranks = sim_->getNumRanks();
55+
//if (num_ranks.rank == 1 && num_ranks.thread == 1) {
56+
//std::cout << " skk: insertIntoTimeVortex insertActivity\n";
57+
sim_->insertActivity(time, this);
58+
//}
59+
}
60+
#endif
61+
#if 0
62+
/** Break to interactive console next time check() is called */
63+
void setInteractiveConsole() {
64+
sim_->enter_interactive_ = true;
65+
}
66+
#endif
4267

4368
/** Called by TimeVortex to trigger interactive mode. */
4469
void execute() override
4570
{
4671
sim_->enter_interactive_ = true;
47-
sim_->interactive_msg_ = msg_;
72+
sim_->interactive_msg_ = msg_;
4873
delete this;
4974
}
75+
#if 0
76+
/** Called by SyncManager to check whether to break to console */
77+
void check(SimTime_t UNUSED(current_time)) {
78+
// Do I need to check current time like checkpoint action?
79+
// Assuming no, because IC is not periodic
80+
// if ((current_time == next_sim_time_) || generate_) {
81+
//std::cout << "skk: check\n";
82+
if (sim_->enter_interactive_ == true) {
83+
sim_->enter_interactive_ = false; // IC may schedule IC again
84+
if (sim_->interactive_ != nullptr)
85+
sim_->interactive_->execute(sim_->interactive_msg_);
86+
}
87+
}
88+
#endif
89+
5090

5191
private:
5292
Simulation_impl* sim_;
5393
std::string msg_;
94+
95+
// Do I need flag here for break to interactive like ckptAction?
96+
// Currently using sim_->enter_interactive_
5497
};
5598

5699
} // namespace SST

src/sst/core/interactiveConsole.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,18 @@ InteractiveConsole::getTimeConverter(const std::string& time)
9696
{
9797
return Simulation_impl::getSimulation()->getTimeLord()->getTimeConverter(time);
9898
}
99+
#if 0
100+
bool
101+
InteractiveConsole::getInteractiveFlag() {
102+
Simulation_impl* sim = Simulation_impl::getSimulation();
103+
return sim->enter_interactive_;
104+
}
105+
#endif
99106

100107
void
101108
InteractiveConsole::schedule_interactive(SimTime_t time_offset, const std::string& msg)
102109
{
110+
//std::cout << "skk: IC: schedule_interactive\n";
103111
Simulation_impl* sim = Simulation_impl::getSimulation();
104112
InteractiveAction* act = new InteractiveAction(sim, msg);
105113
sim->insertActivity(getCurrentSimCycle() + time_offset, act);
@@ -114,7 +122,8 @@ InteractiveConsole::getComponentObjectMap()
114122
void
115123
InteractiveConsole::simulationShutdown()
116124
{
117-
Simulation_impl::getSimulation()->endSimulation();
125+
//Simulation_impl::getSimulation()->endSimulation();
126+
Simulation_impl::getSimulation()->signalShutdown(false);
118127
}
119128

120129

src/sst/core/interactiveConsole.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ class InteractiveConsole
5858
virtual ~InteractiveConsole() = default;
5959

6060
/** Called by TimeVortex to trigger checkpoint on simulation clock interval - not used in parallel simulation */
61-
virtual void execute(const std::string& msg) = 0;
61+
virtual int execute(const std::string& msg) = 0;
62+
/** Called by SyncManager to get summary info for each thread */
63+
virtual void summary() = 0;
6264

6365
protected:
6466
// Functions that can be called by child class

0 commit comments

Comments
 (0)