Skip to content

Commit

Permalink
Merge pull request #3 from caps-tum/update_hwloc_parser
Browse files Browse the repository at this point in the history
Update hwloc parser
  • Loading branch information
stepanvanecek authored Oct 5, 2022
2 parents 9ee9794 + ec434c3 commit 270a236
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 45 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
cmake_policy(SET CMP0048 NEW)
project(sys-sage VERSION 0.2.2 LANGUAGES C CXX )
project(sys-sage VERSION 0.3.0 LANGUAGES C CXX )

cmake_minimum_required(VERSION 3.12.0)
set (CMAKE_CXX_STANDARD 17)
set (CMAKE_CXX_STANDARD 20)
set (CXX_STANDARD_REQUIRED ON)
set (CMAKE_CXX_FLAGS " -Wall -O0")

Expand Down
27 changes: 20 additions & 7 deletions src/Topology.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ void Component::InsertChild(Component * child)
child->SetParent(this);
children.push_back(child);
}
int Component::RemoveChild(Component * child)
{
return std::erase(children, child);
}
Component* Component::GetChild(int _id)
{
for(Component* child: children)
Expand Down Expand Up @@ -311,27 +315,34 @@ int Component::GetId(){return id;}

void Component::SetParent(Component* _parent){parent = _parent;}

string Chip::GetVendor(){return vendor;}
void Chip::SetVendor(string _vendor){vendor = _vendor;}
string Chip::GetModel(){return model;}
void Chip::SetModel(string _model){model = _model;}

int Numa::GetSize(){return size;}
int Cache::GetCacheLevel(){return cache_level;}
long long Cache::GetCacheSize(){return cache_size;}
int Cache::GetCacheAssociativityWays(){return cache_associativity_ways;}

Component::Component(int _id, string _name, int _componentType) : id(_id), name(_name), componentType(_componentType){}
Component::Component(int _id, string _name, int _componentType) : id(_id), name(_name), componentType(_componentType) { count = -1;}
Component::Component() :Component(0,"unknown",SYS_SAGE_COMPONENT_NONE){}

Topology::Topology():Component(0, "topology", SYS_SAGE_COMPONENT_TOPOLOGY){}
Topology::Topology():Component(0, "sys-sage Topology", SYS_SAGE_COMPONENT_TOPOLOGY){}

Memory::Memory():Component(0, "Memory", SYS_SAGE_COMPONENT_MEMORY){}

Storage::Storage():Component(0, "Storage", SYS_SAGE_COMPONENT_STORAGE){}

Node::Node(int _id):Component(_id, "sys-sage node", SYS_SAGE_COMPONENT_NODE){}
Node::Node(int _id):Component(_id, "Node", SYS_SAGE_COMPONENT_NODE){}
Node::Node():Node(0){}

Chip::Chip(int _id):Component(_id, "Chip", SYS_SAGE_COMPONENT_CHIP){}
Chip::Chip(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_CHIP){}
Chip::Chip(int _id):Chip(_id, "Chip"){}
Chip::Chip():Chip(0){}

Cache::Cache(int _id, int _cache_level, unsigned long long _cache_size, int _associativity): Component(_id, "cache", SYS_SAGE_COMPONENT_CACHE), cache_level(_cache_level), cache_size(_cache_size), cache_associativity_ways(_associativity){}
Cache::Cache(int _id, int _cache_level, unsigned long long _cache_size, int _associativity, int _cache_line_size): Component(_id, "Cache", SYS_SAGE_COMPONENT_CACHE), cache_level(_cache_level), cache_size(_cache_size), cache_associativity_ways(_associativity), cache_line_size(_cache_line_size){}
Cache::Cache(int _id, int _cache_level, unsigned long long _cache_size, int _associativity): Cache(_id, _cache_level, _cache_size, _associativity, 0){}
Cache::Cache():Cache(0,0,0,0){}

Subdivision::Subdivision(int _id, string _name, int _componentType): Component(_id, _name, _componentType){}
Expand All @@ -342,8 +353,10 @@ Numa::Numa(int _id, int _size):Subdivision(_id, "Numa", SYS_SAGE_COMPONENT_NUMA)
Numa::Numa(int _id):Numa(_id, 0){}
Numa::Numa():Numa(0){}

Core::Core(int _id):Component(_id, "Core", SYS_SAGE_COMPONENT_CORE){}
Core::Core(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_CORE){}
Core::Core(int _id):Core(_id, "Core"){}
Core::Core():Core(0){}

Thread::Thread(int _id):Component(_id, "Thread", SYS_SAGE_COMPONENT_THREAD){}
Thread::Thread(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_THREAD){}
Thread::Thread(int _id):Thread(_id, "Thread"){}
Thread::Thread():Thread(0){}
31 changes: 31 additions & 0 deletions src/Topology.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ class Component {
*/
void InsertChild(Component * child);
/**
//TODO
@return how many elements were deleted (normally, 0 or 1 should be possible)
*/
int RemoveChild(Component * child);
/**
Define a parent to the component. This is usually used when inserting a component in the tree (by calling InsertChild on the parent, and calling SetParent on the child).
@param parent - a pointer to a Component (or any class instance that inherits from Component).
@see InsertChild()
Expand Down Expand Up @@ -262,6 +267,7 @@ class Component {
int id; /**< Numeric ID of the component. There is no requirement for uniqueness of the ID, however it is advised to have unique IDs at least in the realm of parent's children. Some tree search functions, which take the id as a search parameter search for first match, so the user is responsible to manage uniqueness in the realm of the search subtree (or should be aware of the consequences of not doing so). Component's ID is set by the constructor, and is retrieved via int GetId(); */
int depth; /**< TODO not implemented */
string name; /**< Name of the component (as a string). */
int count; /**< Can be used to represent multiple Components with the same properties. By default, it represents only 1 component, and is set to -1. */
/**
Component type of the component. The component type denotes of which class the instance is (Often the components are stored as Component*, even though they are a member of one of the child classes)
\n This attribute is constant, set by the constructor, and READONLY.
Expand Down Expand Up @@ -348,6 +354,11 @@ class Memory : public Component {
\n componentType=>SYS_SAGE_COMPONENT_MEMORY
*/
Memory();
/**
!!Should normally not be used!! Helper function of XML dump generation.
@see exportToXml(Component* root, string path = "", std::function<int(string,void*,string*)> custom_search_attrib_key_fcn = NULL);
*/
xmlNodePtr CreateXmlSubtree();
private:
long long size; /**< size/capacity of the memory element*/
bool is_volatile; /**< is volatile? */
Expand All @@ -366,6 +377,11 @@ class Storage : public Component {
\n componentType=>SYS_SAGE_COMPONENT_STORAGE
*/
Storage();
/**
!!Should normally not be used!! Helper function of XML dump generation.
@see exportToXml(Component* root, string path = "", std::function<int(string,void*,string*)> custom_search_attrib_key_fcn = NULL);
*/
xmlNodePtr CreateXmlSubtree();
private:
long long size; /**< size/capacity of the storage device */
};
Expand All @@ -390,7 +406,19 @@ class Chip : public Component {
\n componentType=>SYS_SAGE_COMPONENT_CHIP
*/
Chip(int _id);
Chip(int _id, string _name);
void SetVendor(string _vendor);
string GetVendor();
void SetModel(string _model);
string GetModel();
/**
!!Should normally not be used!! Helper function of XML dump generation.
@see exportToXml(Component* root, string path = "", std::function<int(string,void*,string*)> custom_search_attrib_key_fcn = NULL);
*/
xmlNodePtr CreateXmlSubtree();
private:
string vendor;
string model;
};

/**
Expand All @@ -415,6 +443,7 @@ class Cache : public Component {
@see Cache()
*/
Cache(int _id, int _cache_level, unsigned long long _cache_size, int _associativity);
Cache(int _id, int _cache_level, unsigned long long _cache_size, int _associativity, int _cache_line_size);
/**
@returns cache level of this cache
*/
Expand Down Expand Up @@ -544,6 +573,7 @@ class Core : public Component {
@param _id - id of the component
*/
Core(int _id);
Core(int _id, string _name);
private:
};

Expand All @@ -567,6 +597,7 @@ class Thread : public Component {
@param _id - id of the component
*/
Thread(int _id);
Thread(int _id, string _name);
#ifdef CAT_AWARE //defined in CAT_aware.cpp
/**
!!! Only if compiled with CAT_AWARE functionality, only for Intel CPUs !!!
Expand Down
145 changes: 118 additions & 27 deletions src/parsers/hwloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ using namespace std;
vector<string> xmlRelevantNames
{
"topology",
"object"
"object",
"info"
};

vector<string> xmlRelevantObjectTypes
Expand All @@ -22,11 +23,13 @@ vector<string> xmlRelevantObjectTypes
"L1Cache",
"NUMANode",
"Core",
"PU"
"PU",
"Group"
};




string xmlGetPropStr(xmlNode* node, string key)
{
string val;
Expand All @@ -51,7 +54,7 @@ Component* createChildC(string type, xmlNode* node)
{
s = xmlGetPropStr(node, "os_index");
int id = stoi(s.empty()?"0":s);
c = (Component*)new Chip(id);
c = (Component*)new Chip(id, "socket");
}
else if(!type.compare("Cache") || !type.compare("L3Cache") || !type.compare("L2Cache") || !type.compare("L1Cache"))
{
Expand All @@ -63,8 +66,10 @@ Component* createChildC(string type, xmlNode* node)
int cache_level = stoi(s.empty()?"0":s);
s = xmlGetPropStr(node, "cache_associativity");
int associativity = stoi(s.empty()?"0":s);
s = xmlGetPropStr(node, "cache_linesize");
int cache_line_size = stoi(s.empty()?"0":s);

c = (Component*)new Cache(id, cache_level, size, associativity);
c = (Component*)new Cache(id, cache_level, size, associativity, cache_line_size);
}
else if(!type.compare("NUMANode"))
{
Expand All @@ -86,7 +91,7 @@ Component* createChildC(string type, xmlNode* node)
s = xmlGetPropStr(node, "os_index");
int id = stoi(s.empty()?"0":s);
//cout << "adding thread " << id << endl;
c = (Component*)new Thread(id);
c = (Component*)new Thread(id, "HW_thread");
}
else
{
Expand All @@ -106,40 +111,115 @@ int xmlProcessChildren(Component* c, xmlNode* parent, int level)
//interested in object or topology nodes
if(find(xmlRelevantNames.begin(), xmlRelevantNames.end(), name) != xmlRelevantNames.end())
{
string type = xmlGetPropStr(child, "type");
if(name == "info"){
string name = xmlGetPropStr(child, "name");
if(!name.compare("CPUVendor")){
string value = xmlGetPropStr(child, "value");
if(c->GetComponentType() == SYS_SAGE_COMPONENT_CHIP)
((Chip*)c)->SetVendor(value);
}
else if(!name.compare("CPUModel")){
string value = xmlGetPropStr(child, "value");
if(c->GetComponentType() == SYS_SAGE_COMPONENT_CHIP)
((Chip*)c)->SetModel(value);
}
}
else //name == object, topology
{
string type = xmlGetPropStr(child, "type");

// for (int i = 0; i < level; ++i)
// cout << " " ;
// cout << name << " - " << type << endl;
// for (int i = 0; i < level; ++i)
// cout << " " ;
// cout << name << " - " << type << endl;

//if relevant object, it will be inserted in the topology
if(find(xmlRelevantObjectTypes.begin(), xmlRelevantObjectTypes.end(), type) != xmlRelevantObjectTypes.end())
{
Component * childC;
if(!type.compare("Machine")) //node is already existing param
//if relevant object, it will be inserted in the topology
if(find(xmlRelevantObjectTypes.begin(), xmlRelevantObjectTypes.end(), type) != xmlRelevantObjectTypes.end())
{
childC = c;
//cout << "already inserted " << type << endl;
Component * childC;
if(!type.compare("Machine")) //node is already existing param
{
childC = c;
//cout << "already inserted " << type << endl;
}
else
{
//cout << "inserting " << type << " to " << c->GetName() << endl;
childC = createChildC(type, child);

bool inserted_as_sibling = false;
if(childC->GetComponentType() == SYS_SAGE_COMPONENT_CACHE)
{//make a cache a child of NUMA, if it is a sibling
vector<Component*>* siblings = c->GetChildren();
for(Component* sibling : *siblings){
if(sibling->GetComponentType() == SYS_SAGE_COMPONENT_NUMA) {
sibling->InsertChild(childC);
inserted_as_sibling = true;
break;
}
}
}
else if(childC->GetComponentType() == SYS_SAGE_COMPONENT_NUMA)
{//make a (already inserted)cache a child of NUMA, if it is a sibling
vector<Component*>* siblings = c->GetChildren();
for(Component* sibling: *siblings){
if(sibling->GetComponentType() == SYS_SAGE_COMPONENT_CACHE) {
c->RemoveChild(sibling);
c->InsertChild(childC);
childC->InsertChild(childC);
sibling->InsertChild(sibling);
inserted_as_sibling = true;
break;
}
}
}
if(!inserted_as_sibling)
c->InsertChild(childC);
}
xmlProcessChildren(childC, child, level+1);
}
else
{
//cout << "inserting " << type << " to " << c->GetName() << endl;
childC = createChildC(type, child);
c->InsertChild(childC);
//cout << "not inserting " << type << " to " << c->GetName() << endl;
xmlProcessChildren(c, child, level+1);
}
xmlProcessChildren(childC, child, level+1);
}
else
{
//cout << "not inserting " << type << " to " << c->GetName() << endl;
xmlProcessChildren(c, child, level+1);
}

}
}
}
return 0;
}

int removeUnknownCompoents(Component* c){
vector<Component*>* children = c->GetChildren();
vector<Component*> children_copy;
for(Component* child : *children){
children_copy.push_back(child);
}

int ret = 0;
for(Component* child : children_copy){
if(child->GetComponentType() == SYS_SAGE_COMPONENT_NONE){
vector<Component*>* grandchildren = child->GetChildren();
int num_grandchildren = grandchildren->size();
if(num_grandchildren >= 1) {
int removed = c->RemoveChild(child);
for(Component * grandchild : *grandchildren){
c->InsertChild(grandchild);
}
delete child;
ret += num_grandchildren - 1;
}
else {
c->RemoveChild(child);
delete child;
}
}
ret += removeUnknownCompoents(child);
}
return ret;
}

//parses a hwloc output and adds it to topology
int parseHwlocOutput(Node* n, string topoPath)
{
Expand All @@ -152,8 +232,19 @@ int parseHwlocOutput(Node* n, string topoPath)

xmlNode *root= xmlDocGetRootElement(document);

int err = xmlProcessChildren((Component*)n, root, 0);
int err = xmlProcessChildren(n, root, 0);
if(err != 0){
std::cerr << "parseHwlocOutput on file " << topoPath << " failed on xmlProcessChildren" << std::endl;
return err;
}

err = removeUnknownCompoents(n);
if(err != 0){
std::cerr << "parseHwlocOutput on file " << topoPath << " failed on removeUnknownCompoents BUT WILL CONTINUE" << std::endl;
//return ret;
}

xmlFreeDoc(document);
return err;
//return err;
return 0;
}
Loading

0 comments on commit 270a236

Please sign in to comment.