Skip to content

Commit

Permalink
Merge pull request #892 from sstsimulator/devel
Browse files Browse the repository at this point in the history
Automatically Merged using SST Master Branch Merger
  • Loading branch information
sst-autotester authored Dec 9, 2022
2 parents a8bb2e0 + 5ce052c commit 62904a7
Show file tree
Hide file tree
Showing 28 changed files with 813 additions and 162 deletions.
3 changes: 3 additions & 0 deletions src/sst/core/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ nobase_dist_sst_HEADERS = \
profile/clockHandlerProfileTool.h \
profile/eventHandlerProfileTool.h \
profile/syncProfileTool.h \
profile/componentProfileTool.h \
rankInfo.h \
simulation.h \
sparseVectorMap.h \
Expand All @@ -82,6 +83,7 @@ nobase_dist_sst_HEADERS = \
eli/interfaceInfo.h \
eli/paramsInfo.h \
eli/portsInfo.h \
eli/profilePointInfo.h \
eli/simpleInfo.h \
eli/statsInfo.h \
eli/subcompSlotInfo.h \
Expand Down Expand Up @@ -192,6 +194,7 @@ sst_core_sources = \
profile/clockHandlerProfileTool.cc \
profile/eventHandlerProfileTool.cc \
profile/syncProfileTool.cc \
profile/componentProfileTool.cc \
simulation.cc \
stringize.cc \
subcomponent.cc \
Expand Down
27 changes: 15 additions & 12 deletions src/sst/core/baseComponent.cc
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,10 @@ BaseComponent::registerClock(const std::string& freq, Clock::HandlerBase* handle
TimeConverter* tc = sim_->registerClock(freq, handler, CLOCKPRIORITY);

// Check to see if there is a profile tool installed
auto* tool = sim_->getProfileTool<Profile::ClockHandlerProfileTool>(SST_PROFILE_TOOL_CLOCK);
auto tools = sim_->getProfileTool<Profile::ClockHandlerProfileTool>("clock");

if ( tool != nullptr ) {
for ( auto* tool : tools ) {
ClockHandlerMetaData mdata(my_info->getID(), getName(), getType());

// Add the receive profiler to the handler
handler->addProfileTool(tool, mdata);
}
Expand All @@ -136,11 +135,10 @@ BaseComponent::registerClock(const UnitAlgebra& freq, Clock::HandlerBase* handle
TimeConverter* tc = sim_->registerClock(freq, handler, CLOCKPRIORITY);

// Check to see if there is a profile tool installed
auto* tool = sim_->getProfileTool<Profile::ClockHandlerProfileTool>(SST_PROFILE_TOOL_CLOCK);
auto tools = sim_->getProfileTool<Profile::ClockHandlerProfileTool>("clock");

if ( tool != nullptr ) {
for ( auto* tool : tools ) {
ClockHandlerMetaData mdata(my_info->getID(), getName(), getType());

// Add the receive profiler to the handler
handler->addProfileTool(tool, mdata);
}
Expand All @@ -160,11 +158,10 @@ BaseComponent::registerClock(TimeConverter* tc, Clock::HandlerBase* handler, boo
TimeConverter* tcRet = sim_->registerClock(tc, handler, CLOCKPRIORITY);

// Check to see if there is a profile tool installed
auto* tool = sim_->getProfileTool<Profile::ClockHandlerProfileTool>(SST_PROFILE_TOOL_CLOCK);
auto tools = sim_->getProfileTool<Profile::ClockHandlerProfileTool>("clock");

if ( tool != nullptr ) {
for ( auto* tool : tools ) {
ClockHandlerMetaData mdata(my_info->getID(), getName(), getType());

// Add the receive profiler to the handler
handler->addProfileTool(tool, mdata);
}
Expand Down Expand Up @@ -303,8 +300,8 @@ BaseComponent::configureLink(const std::string& name, TimeConverter* time_base,
tmp->setFunctor(handler);

// Check to see if there is a profile tool installed
auto* tool = sim_->getProfileTool<Profile::EventHandlerProfileTool>(SST_PROFILE_TOOL_EVENT);
if ( tool != nullptr ) {
auto tools = sim_->getProfileTool<Profile::EventHandlerProfileTool>("event");
for ( auto& tool : tools ) {
EventHandlerMetaData mdata(my_info->getID(), getName(), getType(), name);

// Add the receive profiler to the handler
Expand Down Expand Up @@ -589,7 +586,7 @@ BaseComponent::vfatal(
std::string type_tree = my_info->getType();
ComponentInfo* parent = my_info->parent_info;
while ( parent != nullptr ) {
type_tree = parent->type + "/" + type_tree;
type_tree = parent->type + "." + type_tree;
parent = parent->parent_info;
}

Expand Down Expand Up @@ -839,4 +836,10 @@ BaseComponent::performGlobalStatisticOutput()
sim_->getStatisticsProcessingEngine()->performGlobalStatisticOutput(false);
}

std::vector<Profile::ComponentProfileTool*>
BaseComponent::getComponentProfileTools(const std::string& point)
{
return sim_->getProfileTool<Profile::ComponentProfileTool>(point);
}

} // namespace SST
29 changes: 29 additions & 0 deletions src/sst/core/baseComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "sst/core/eli/elementinfo.h"
#include "sst/core/event.h"
#include "sst/core/oneshot.h"
#include "sst/core/profile/componentProfileTool.h"
#include "sst/core/simulation.h"
#include "sst/core/sst_types.h"
#include "sst/core/statapi/statbase.h"
Expand Down Expand Up @@ -486,6 +487,32 @@ class BaseComponent
*/
void performGlobalStatisticOutput();

/** Registers a profiling point.
This function will register a profiling point.
@param point Point to resgister
@return Either a pointer to a created T::ProfilePoint or nullptr if not enabled.
*/
template <typename T>
typename T::ProfilePoint* registerProfilePoint(const std::string& pointName)
{
std::string full_point_name = getType() + "." + pointName;
auto tools = getComponentProfileTools(full_point_name);
if ( tools.size() == 0 ) return nullptr;

typename T::ProfilePoint* ret = new typename T::ProfilePoint();
for ( auto* x : tools ) {
T* tool = dynamic_cast<T*>(x);
if ( nullptr == tool ) {
// Not the right type, fatal
fatal(
CALL_INFO_LONG, 1, "ERROR: wrong type of profiling tool for profiling point %s)\n",
pointName.c_str());
}
ret->registerProfilePoint(tool, pointName, getId(), getName(), getType());
}
return ret;
}

/** Loads a module from an element Library
* @param type Fully Qualified library.moduleName
* @param params Parameters the module should use for configuration
Expand Down Expand Up @@ -820,6 +847,8 @@ class BaseComponent
// Return the Units for the statisticName from the ElementInfoStatistic
// std::string getComponentInfoStatisticUnits(const std::string& statisticName) const;

std::vector<Profile::ComponentProfileTool*> getComponentProfileTools(const std::string& point);

private:
ComponentInfo* my_info = nullptr;
Simulation_impl* sim_ = nullptr;
Expand Down
1 change: 1 addition & 0 deletions src/sst/core/component.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Component : public BaseComponent
ELI::ProvidesPorts,
ELI::ProvidesSubComponentSlots,
ELI::ProvidesStats,
ELI::ProvidesProfilePoints,
ELI::ProvidesAttributes)

/** Constructor. Generally only called by the factory class.
Expand Down
6 changes: 3 additions & 3 deletions src/sst/core/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -994,7 +994,7 @@ ConfigHelper::usage()
}

const char sdl_indicator[] = "(S)";
const uint32_t sdl_start = 33;
const uint32_t sdl_start = 34;
const uint32_t desc_start = sdl_start + sizeof(sdl_indicator);
const uint32_t desc_width = MAX_WIDTH - desc_start;

Expand All @@ -1014,9 +1014,9 @@ ConfigHelper::usage()
}

uint32_t npos = 0;
if ( sstOptions[i].opt.val ) { npos += fprintf(stderr, " -%c, ", (char)sstOptions[i].opt.val); }
if ( sstOptions[i].opt.val ) { npos += fprintf(stderr, "-%c ", (char)sstOptions[i].opt.val); }
else {
npos += fprintf(stderr, " ");
npos += fprintf(stderr, " ");
}
npos += fprintf(stderr, "--%s", sstOptions[i].opt.name);
if ( sstOptions[i].opt.has_arg != no_argument ) { npos += fprintf(stderr, "=%s", sstOptions[i].argName); }
Expand Down
10 changes: 10 additions & 0 deletions src/sst/core/eli/elementinfo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ ProvidesSubComponentSlots::toString(std::ostream& os) const
}
}

void
ProvidesProfilePoints::toString(std::ostream& os) const
{
os << " Profile Points (" << getProfilePoints().size() << " total)\n";
for ( auto& item : getProfilePoints() ) {
os << " " << item.name << ": " << (item.description == nullptr ? "<empty>" : item.description) << " ["
<< (item.superclass == nullptr ? "<none>" : item.superclass) << "]\n";
}
}

void
ProvidesStats::toString(std::ostream& os) const
{
Expand Down
1 change: 1 addition & 0 deletions src/sst/core/eli/elementinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "sst/core/eli/interfaceInfo.h"
#include "sst/core/eli/paramsInfo.h"
#include "sst/core/eli/portsInfo.h"
#include "sst/core/eli/profilePointInfo.h"
#include "sst/core/eli/simpleInfo.h"
#include "sst/core/eli/statsInfo.h"
#include "sst/core/eli/subcompSlotInfo.h"
Expand Down
9 changes: 7 additions & 2 deletions src/sst/core/eli/elibase.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,19 @@ struct ElementInfoSubComponentSlot
const char* superclass;
};

struct ElementInfoProfilePoint
{
const char* name;
const char* description;
const char* superclass;
};

struct ElementInfoAttribute
{
const char* name;
const char* value;
};

typedef ElementInfoSubComponentSlot ElementInfoSubComponentHook;

namespace ELI {

// Function used to combine the parent and child ELI information.
Expand Down
89 changes: 89 additions & 0 deletions src/sst/core/eli/profilePointInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright 2009-2022 NTESS. Under the terms
// of Contract DE-NA0003525 with NTESS, the U.S.
// Government retains certain rights in this software.
//
// Copyright (c) 2009-2022, NTESS
// All rights reserved.
//
// This file is part of the SST software package. For license
// information, see the LICENSE file in the top level directory of the
// distribution.

#ifndef SST_CORE_ELI_PROFILEPOINTINFO_H
#define SST_CORE_ELI_PROFILEPOINTINFO_H

#include "sst/core/eli/elibase.h"

#include <string>
#include <vector>

namespace SST {
namespace ELI {

template <class T, class Enable = void>
struct InfoProfilePoints
{
static const std::vector<SST::ElementInfoProfilePoint>& get()
{
static std::vector<SST::ElementInfoProfilePoint> var = {};
return var;
}
};

template <class T>
struct InfoProfilePoints<T, typename MethodDetect<decltype(T::ELI_getProfilePoints())>::type>
{
static const std::vector<SST::ElementInfoProfilePoint>& get() { return T::ELI_getProfilePoints(); }
};

class ProvidesProfilePoints
{
public:
const std::vector<ElementInfoProfilePoint>& getProfilePoints() const { return points_; }

void toString(std::ostream& os) const;

template <class XMLNode>
void outputXML(XMLNode* node) const
{
int idx = 0;
for ( const ElementInfoProfilePoint& point : points_ ) {
auto* element = new XMLNode("ProfilePoint");
element->SetAttribute("Index", idx);
element->SetAttribute("Name", point.name);
element->SetAttribute("Description", point.description ? point.description : "none");
element->SetAttribute("Interface", point.superclass ? point.superclass : "none");
node->LinkEndChild(element);
++idx;
}
}

protected:
template <class T>
ProvidesProfilePoints(T* UNUSED(t)) : points_(InfoProfilePoints<T>::get())
{}

private:
std::vector<ElementInfoProfilePoint> points_;
};

} // namespace ELI
} // namespace SST

// clang-format off
#define SST_ELI_DOCUMENT_PROFILE_POINTS(...) \
static const std::vector<SST::ElementInfoProfilePoint>& ELI_getProfilePoints() \
{ \
static std::vector<SST::ElementInfoProfilePoint> var = { __VA_ARGS__ }; \
auto parent = SST::ELI::InfoProfilePoints< \
std::conditional<(__EliDerivedLevel > __EliBaseLevel), __LocalEliBase, __ParentEliBase>::type>::get(); \
SST::ELI::combineEliInfo(var, parent); \
return var; \
}
// clang-format on
#define SST_ELI_DELETE_PROFILE_POINT(point) \
{ \
point, nullptr, nullptr \
}

#endif // SST_CORE_ELI_PROFILEPOINTINFO_H
42 changes: 42 additions & 0 deletions src/sst/core/factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,48 @@ Factory::GetComponentInfoStatisticUnits(const std::string& type, const std::stri
return nullptr;
}

bool
Factory::isProfilePointValid(const std::string& type, const std::string& point)
{
std::string elemlib, elem;
std::tie(elemlib, elem) = parseLoadName(type);
// ensure library is already loaded...
if ( loaded_libraries.find(elemlib) == loaded_libraries.end() ) { findLibrary(elemlib); }

const std::vector<ElementInfoProfilePoint>* pointNames = nullptr;

// Check to see if library is loaded into new
// ElementLibraryDatabase
auto* lib = ELI::InfoDatabase::getLibrary<Component>(elemlib);
std::stringstream err;
if ( lib ) {
auto* compInfo = lib->getInfo(elem);
if ( compInfo ) { pointNames = &compInfo->getProfilePoints(); }
}
if ( nullptr == pointNames ) {
auto* lib = ELI::InfoDatabase::getLibrary<SubComponent>(elemlib);
if ( lib ) {
auto* subcompInfo = lib->getInfo(elem);
if ( subcompInfo ) { pointNames = &subcompInfo->getProfilePoints(); }
}
}

std::string tmp = elemlib + "." + elem;

if ( pointNames == nullptr ) {
out.fatal(
CALL_INFO, 1, "can't find requested component or subcomponent '%s' when searching for profile point\n ",
tmp.c_str());
return false;
}

for ( auto p : *pointNames ) {
if ( p.name == point ) return true;
}
return false;
}


Module*
Factory::CreateModule(const std::string& type, Params& params)
{
Expand Down
7 changes: 7 additions & 0 deletions src/sst/core/factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,13 @@ class Factory
*/
std::string GetComponentInfoStatisticUnits(const std::string& type, const std::string& statisticName);

/** Get a list of allowed ports for a given component type.
* @param type - Type of component in lib.name format
* @param point = Profile point to check
* @return True if this is a valid profile point
*/
bool isProfilePointValid(const std::string& type, const std::string& point);

private:
friend int ::main(int argc, char** argv);

Expand Down
Loading

0 comments on commit 62904a7

Please sign in to comment.