Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
229 changes: 149 additions & 80 deletions src/sst/core/baseComponent.cc

Large diffs are not rendered by default.

264 changes: 219 additions & 45 deletions src/sst/core/baseComponent.h

Large diffs are not rendered by default.

20 changes: 0 additions & 20 deletions src/sst/core/component.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,6 @@ Component::Component(ComponentId_t id) :
// currentlyLoadingSubComponent = my_info;
}

void
Component::registerAsPrimaryComponent()
{
// Nop for now. Will put in complete semantics later
}

void
Component::primaryComponentDoNotEndSim()
{
int thread = Simulation_impl::getSimulation()->getRank().thread;
Simulation_impl::getSimulation()->getExit()->refInc(getId(), thread);
}

void
Component::primaryComponentOKToEndSim()
{
int thread = Simulation_impl::getSimulation()->getRank().thread;
Simulation_impl::getSimulation()->getExit()->refDec(getId(), thread);
}


void
Component::serialize_order(SST::Core::Serialization::serializer& ser)
Expand Down
41 changes: 0 additions & 41 deletions src/sst/core/component.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,47 +50,6 @@ class Component : public BaseComponent
explicit Component(ComponentId_t id);
virtual ~Component() override = default;

/** Register as a primary component, which allows the component to
specify when it is and is not OK to end simulation. The
simulator will not end simulation naturally (through use of
the Exit object) while any primary component has specified
primaryComponentDoNotEndSim(). However, it is still possible
for Actions other than Exit to end simulation. Once all
primary components have specified
primaryComponentOKToEndSim(), the Exit object will trigger and
end simulation.

This must be called during simulation wireup (i.e during the
constructor for the component). By default, the state of the
primary component is set to OKToEndSim.

If no component registers as a primary component, then the
Exit object will not be used for that simulation and
simulation termination must be accomplished through some other
mechanism (e.g. --stopAt flag, or some other Action object).

@sa Component::primaryComponentDoNotEndSim()
@sa Component::primaryComponentOKToEndSim()
*/
void registerAsPrimaryComponent();

/** Tells the simulation that it should not exit. The component
will remain in this state until a call to
primaryComponentOKToEndSim().

@sa Component::registerAsPrimaryComponent()
@sa Component::primaryComponentOKToEndSim()
*/
void primaryComponentDoNotEndSim();

/** Tells the simulation that it is now OK to end simulation.
Simulation will not end until all primary components have
called this function.

@sa Component::registerAsPrimaryComponent()
@sa Component::primaryComponentDoNotEndSim()
*/
void primaryComponentOKToEndSim();

void serialize_order(SST::Core::Serialization::serializer& ser) override;
ImplementSerializable(SST::Component)
Expand Down
2 changes: 1 addition & 1 deletion src/sst/core/componentExtension.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace SST {
ComponentExtension::ComponentExtension(ComponentId_t id) :
BaseComponent(id)
{
isExtension = true;
setAsExtension();
}

void
Expand Down
5 changes: 1 addition & 4 deletions src/sst/core/componentInfo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ ComponentInfo::ComponentInfo(ComponentId_t id, const std::string& name) :
link_map(nullptr),
component(nullptr),
params(nullptr),
portModules(nullptr),
stat_configs_(nullptr),
enabled_stat_names_(nullptr),
enabled_all_stats_(false),
Expand All @@ -49,7 +48,6 @@ ComponentInfo::ComponentInfo() :
link_map(nullptr),
component(nullptr),
params(nullptr),
portModules(nullptr),
stat_configs_(nullptr),
enabled_stat_names_(nullptr),
enabled_all_stats_(false),
Expand Down Expand Up @@ -89,7 +87,6 @@ ComponentInfo::ComponentInfo(ComponentId_t id, ComponentInfo* parent_info, const
link_map(nullptr),
component(nullptr),
params(/*new Params()*/ nullptr),
portModules(nullptr),
stat_configs_(nullptr),
enabled_stat_names_(nullptr),
enabled_all_stats_(false),
Expand Down Expand Up @@ -184,7 +181,7 @@ ComponentInfo::~ComponentInfo()
{
if ( link_map ) delete link_map;
if ( component ) {
component->my_info = nullptr;
component->my_info_ = nullptr;
delete component;
}

Expand Down
146 changes: 38 additions & 108 deletions src/sst/core/exit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,113 +24,68 @@ namespace SST {

Exit::Exit(int num_threads, bool single_rank) :
Action(),
// m_functor( new EventHandler<Exit,bool,Event*> (this,&Exit::handler ) ),
num_threads(num_threads),
m_refCount(0),
end_time(0),
single_rank(single_rank)
num_threads_(num_threads),
single_rank_(single_rank)
{
setPriority(EXITPRIORITY);
m_thread_counts = new unsigned int[num_threads];
for ( int i = 0; i < num_threads; i++ ) {
m_thread_counts[i] = 0;
thread_counts_ = new unsigned int[num_threads_];
for ( int i = 0; i < num_threads_; i++ ) {
thread_counts_[i] = 0;
}
}

Exit::~Exit()
{
m_idSet.clear();
delete[] thread_counts_;
}

bool
Exit::refInc(ComponentId_t id, uint32_t thread)
void
Exit::refInc(uint32_t thread)
{
std::lock_guard<Spinlock> lock(slock);
if ( m_idSet.find(id) != m_idSet.end() ) {
// CompMap_t comp_map = Simulation_impl::getSimulation()->getComponentMap();
// bool found_in_map = false;

// for(CompMap_t::iterator comp_map_itr = comp_map.begin();
// comp_map_itr != comp_map.end();
// ++comp_map_itr) {

// if(comp_map_itr->second->getId() == id) {
// found_in_map = true;
// break;
// }
// }

// if(found_in_map) {
// _DBG( Exit, "component (%s) multiple increment\n",
// Simulation_impl::getSimulation()->getComponent(id)->getName().c_str() );
// } else {
// _DBG( Exit, "component in construction increments exit multiple times.\n" );
// }
return true;
}

m_idSet.insert(id);

++m_refCount;
++m_thread_counts[thread];

return false;
std::lock_guard<Spinlock> lock(slock_);
++ref_count_;
++thread_counts_[thread];
}

bool
Exit::refDec(ComponentId_t id, uint32_t thread)
void
Exit::refDec(uint32_t thread)
{
std::lock_guard<Spinlock> lock(slock);
if ( m_idSet.find(id) == m_idSet.end() ) {
Simulation_impl::getSimulation()->getSimulationOutput().verbose(CALL_INFO, 1, 1,
"component (%s) multiple decrement\n",
Simulation_impl::getSimulation()->getComponent(id)->getName().c_str());
return true;
}

if ( m_refCount == 0 ) {
Simulation_impl::getSimulation()->getSimulationOutput().fatal(CALL_INFO, 1, "refCount is already 0\n");
return true;
std::lock_guard<Spinlock> lock(slock_);
if ( ref_count_ == 0 ) {
Simulation_impl::getSimulation()->getSimulationOutput().fatal(CALL_INFO, 1, "ref_count is already 0\n");
}

m_idSet.erase(id);
--ref_count_;
--thread_counts_[thread];

--m_refCount;
--m_thread_counts[thread];

if ( single_rank && num_threads == 1 && m_refCount == 0 ) {
end_time = Simulation_impl::getSimulation()->getCurrentSimCycle();
if ( single_rank_ && num_threads_ == 1 && ref_count_ == 0 ) {
end_time_ = Simulation_impl::getSimulation()->getCurrentSimCycle();
Simulation_impl* sim = Simulation_impl::getSimulation();
sim->insertActivity(sim->getCurrentSimCycle() + 1, this);
}
else if ( m_thread_counts[thread] == 0 ) {
else if ( thread_counts_[thread] == 0 ) {
SimTime_t end_time_new = Simulation_impl::getSimulation()->getCurrentSimCycle();
if ( end_time_new > end_time ) end_time = end_time_new;
if ( end_time_new > end_time_ ) end_time_ = end_time_new;
if ( Simulation_impl::getSimulation()->isIndependentThread() ) {
// Need to exit just this thread, so we'll need to use a
// StopAction
Simulation_impl* sim = Simulation_impl::getSimulation();
sim->insertActivity(sim->getCurrentSimCycle(), new StopAction());
}
}

return false;
}

unsigned int
Exit::getRefCount()
{
return m_refCount;
return ref_count_;
}

void
Exit::execute()
{
check();

// Only gets put into queue once, no need to reschedule
// SimTime_t next = Simulation_impl::getSimulation()->getCurrentSimCycle() + m_period->getFactor();
// Simulation_impl::getSimulation()->insertActivity(next, this);
check();
}

SimTime_t
Expand All @@ -139,25 +94,25 @@ Exit::computeEndTime()
#ifdef SST_CONFIG_HAVE_MPI
// Do an all_reduce to get the end_time
SimTime_t end_value;
if ( !single_rank ) {
MPI_Allreduce(&end_time, &end_value, 1, MPI_UINT64_T, MPI_MAX, MPI_COMM_WORLD);
end_time = end_value;
if ( !single_rank_ ) {
MPI_Allreduce(&end_time_, &end_value, 1, MPI_UINT64_T, MPI_MAX, MPI_COMM_WORLD);
end_time_ = end_value;
}
#endif
if ( single_rank ) {
endSimulation(end_time);
if ( single_rank_ ) {
endSimulation(end_time_);
}
return end_time;
return end_time_;
}

void
Exit::check()
{
int value = (m_refCount > 0);
int value = (ref_count_ > 0);
int out;

#ifdef SST_CONFIG_HAVE_MPI
if ( !single_rank ) {
if ( !single_rank_ ) {
MPI_Allreduce(&value, &out, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
}
else {
Expand All @@ -166,44 +121,19 @@ Exit::check()
#else
out = value;
#endif
global_count = out;
global_count_ = out;
// If out is 0, then it's time to end
if ( !out ) {
computeEndTime();
}
// else {
// // Reinsert into TimeVortex. We do this even when ending so that
// // it will get deleted with the TimeVortex on termination. We do
// // this in case we exit with a StopEvent instead. In that case,
// // there is no way to know if the Exit object is deleted in the
// // TimeVortex or not, so we just make sure it is always deleted
// // there.
// Simulation *sim = Simulation_impl::getSimulation();
// SimTime_t next = sim->getCurrentSimCycle() +
// sim->insertActivity( next, this );
// }
}

void
Exit::serialize_order(SST::Core::Serialization::serializer& ser)
std::string
Exit::toString() const
{
Action::serialize_order(ser);

SST_SER(num_threads);

if ( ser.mode() == SST::Core::Serialization::serializer::UNPACK ) {
m_thread_counts = new unsigned int[num_threads];
}

for ( int i = 0; i < num_threads; i++ ) {
SST_SER(m_thread_counts[i]);
}

SST_SER(m_refCount);
SST_SER(global_count);
SST_SER(m_idSet);
SST_SER(end_time);
SST_SER(single_rank);
std::stringstream buf;
buf << "Exit Action to be delivered at " << getDeliveryTime() << " with priority " << getPriority();
return buf.str();
}

} // namespace SST
Loading
Loading