Skip to content

Commit

Permalink
Merge tag '2025-01-10' into push-2025-01-10
Browse files Browse the repository at this point in the history
Change-Id: I653900d5eda49611da161c8ed40761404e223211
  • Loading branch information
rdementi committed Jan 10, 2025
2 parents e90ee4b + b802d0d commit ed9227b
Show file tree
Hide file tree
Showing 13 changed files with 257 additions and 8 deletions.
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,9 @@
[submodule "perfmon"]
path = perfmon
url = https://github.com/intel/perfmon
[submodule "src/pugixml"]
path = src/pugixml
url = https://github.com/zeux/pugixml.git
[submodule "Intel-PMT"]
path = Intel-PMT
url = https://github.com/intel/Intel-PMT.git
22 changes: 22 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,28 @@ if(PCM_FUZZ)
message(STATUS "CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}")
endif(PCM_FUZZ)

#######################
# pugixml dependency
#######################

add_library(PCM_PUGIXML INTERFACE) # interface library for pugixml
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/pugixml/src/pugixml.cpp")
message(STATUS "Local pugixml exists: ${CMAKE_CURRENT_SOURCE_DIR}/src/pugixml/src/pugixml.cpp")
set(PCM_PUGIXML_CPP ${CMAKE_CURRENT_SOURCE_DIR}/src/pugixml/src/pugixml.cpp)
add_compile_definitions(PCM_PUGIXML_AVAILABLE)
else()
message(STATUS "Local pugixml doesn't exist")
# message(WARNING
# " ${CMAKE_CURRENT_SOURCE_DIR}/src/pugixml/src/pugixml.cpp doesn't exist\n"
# " Use `git clone --recursive` flag when cloning pcm repository to clone pugixml submodule as well or\n"
# " update submodule with command 'git submodule update --init --recursive' or\n"
# " run 'git clone https//github.com/zeux/pugixml.git' in 'src' directory to get pugixml library")
endif()

#######################
# End of pugixml dependency section
#######################

#######################
# Install
#######################
Expand Down
1 change: 1 addition & 0 deletions Intel-PMT
Submodule Intel-PMT added at 76f9e9
2 changes: 1 addition & 1 deletion perfmon
Submodule perfmon updated 229 files
4 changes: 2 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ set(PROJECT_NAMES pcm pcm-numa pcm-latency pcm-power pcm-msr pcm-memory pcm-tsx

set(MINIMUM_OPENSSL_VERSION 1.1.1)

file(GLOB COMMON_SOURCES pcm-accel-common.cpp msr.cpp cpucounters.cpp pci.cpp mmio.cpp tpmi.cpp pmt.cpp bw.cpp utils.cpp topology.cpp debug.cpp threadpool.cpp uncore_pmu_discovery.cpp)
file(GLOB COMMON_SOURCES pcm-accel-common.cpp msr.cpp cpucounters.cpp pci.cpp mmio.cpp tpmi.cpp pmt.cpp bw.cpp utils.cpp topology.cpp debug.cpp threadpool.cpp uncore_pmu_discovery.cpp ${PCM_PUGIXML_CPP})

if (APPLE)
file(GLOB UNUX_SOURCES dashboard.cpp)
Expand Down Expand Up @@ -154,7 +154,7 @@ if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSIO
endif()

if(SIMDJSON_IS_APPLICABLE)
find_package(simdjson QUIET) # Working form Ububtu 22.04
find_package(simdjson QUIET) # Working form Ubuntu 22.04
if(simdjson_FOUND)
message(STATUS "System SIMDJSON is used")
target_link_libraries(PCM_SIMDJSON INTERFACE simdjson::simdjson)
Expand Down
7 changes: 5 additions & 2 deletions src/cpucounters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2027,7 +2027,7 @@ void PCM::initUncoreObjects()

//TPMIHandle::setVerbose(true);
try {
if (TPMIHandle::getNumInstances() == (size_t)num_sockets)
if (isServerCPU() && TPMIHandle::getNumInstances() == (size_t)num_sockets)
{
// std::cerr << "DEBUG: TPMIHandle::getNumInstances(): " << TPMIHandle::getNumInstances() << "\n";
UFSStatus.resize(num_sockets);
Expand Down Expand Up @@ -3159,7 +3159,10 @@ PCM::PCM() :
std::cerr << "\n";
#endif

uncorePMUDiscovery = std::make_shared<UncorePMUDiscovery>();
if (isServerCPU())
{
uncorePMUDiscovery = std::make_shared<UncorePMUDiscovery>();
}

initUncoreObjects();

Expand Down
8 changes: 7 additions & 1 deletion src/pci.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,14 @@ int32 PciHandle::read64(uint64 offset, uint64 * value)
warnAlignment<4>("PciHandle::read64", false, offset);
if (hDriver != INVALID_HANDLE_VALUE)
{
if (offset & 7)
{
// this driver supports only 8-byte aligned reads
// use read32 for unaligned reads
uint32* value32Ptr = (uint32*)value;
return read32(offset, value32Ptr) + read32(offset + sizeof(uint32), value32Ptr + 1);
}
PCICFG_Request req;
// ULONG64 result;
DWORD reslength = 0;
req.bus = bus;
req.dev = device;
Expand Down
2 changes: 1 addition & 1 deletion src/pcm-iio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2240,7 +2240,7 @@ int mainThrows(int argc, char * argv[])
catch (std::exception & e)
{
std::cerr << "Error info:" << e.what() << "\n";
std::cerr << "Event configure file have the problem and cause the program exit, please double check it!\n";
std::cerr << "The event configuration file (" << ev_file_name << ") cannot be loaded. Please verify the file. Exiting.\n";
exit(EXIT_FAILURE);
}

Expand Down
44 changes: 44 additions & 0 deletions src/pcm-raw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ void print_usage(const string & progname)

bool verbose = false;
double defaultDelay = 1.0; // in seconds
TelemetryDB telemDB;

PCM::RawEventConfig initCoreConfig()
{
Expand Down Expand Up @@ -973,6 +974,37 @@ AddEventStatus addEvent(PCM::RawPMUConfigs & curPMUConfigs, string eventStr)
}
const auto configArray = split(configStr, ',');
bool fixed = false;
std::string lookup;
auto pmtAddRecord = [&lookup, &pmuName, &config](const std::vector<TelemetryDB::PMTRecord> & records) -> AddEventStatus
{
if (pmuName == "pmt")
{
if (records.empty())
{
cerr << "ERROR: lookup \"" << lookup << "\" not found in PMT telemetry database\n";
return AddEventStatus::Failed;
}
if (records.size() > 1)
{
cerr << "ERROR: lookup \"" << lookup << "\" is ambiguous in PMT telemetry database\n\n";
for (const auto & record : records)
{
cerr << " ";
record.print(cerr);
cerr << "\n";
}
return AddEventStatus::Failed;
}
config.second = records[0].fullName;
assert(records.size() == 1);
config.first[PCM::PMTEventPosition::UID] = records[0].uid;
config.first[PCM::PMTEventPosition::offset] = records[0].qWordOffset;
config.first[PCM::PMTEventPosition::type] = (records[0].sampleType == "Snapshot") ? PCM::MSRType::Static : PCM::MSRType::Freerun;
config.first[PCM::PMTEventPosition::lsb] = records[0].lsb;
config.first[PCM::PMTEventPosition::msb] = records[0].msb;
}
return AddEventStatus::OK;
};
for (const auto & item : configArray)
{
if (match(item, "config=", &config.first[0]))
Expand Down Expand Up @@ -1009,6 +1041,16 @@ AddEventStatus addEvent(PCM::RawPMUConfigs & curPMUConfigs, string eventStr)
if (check_for_injections(config.second))
return AddEventStatus::Failed;
}
else if (pcm_sscanf(item) >> s_expect("lookup=") >> setw(255) >> lookup)
{
if (pmtAddRecord(telemDB.lookup(lookup)) != AddEventStatus::OK)
return AddEventStatus::Failed;
}
else if (pcm_sscanf(item) >> s_expect("ilookup=") >> setw(255) >> lookup)
{
if (pmtAddRecord(telemDB.ilookup(lookup)) != AddEventStatus::OK)
return AddEventStatus::Failed;
}
else if (item == "fixed")
{
fixed = true;
Expand Down Expand Up @@ -2343,6 +2385,8 @@ int mainThrows(int argc, char * argv[])
bool reset_pmu = false;
PCM* m = PCM::getInstance();

telemDB.loadFromXML("Intel-PMT");

parsePID(argc, argv, pid);

#ifdef PCM_SIMDJSON_AVAILABLE
Expand Down
138 changes: 138 additions & 0 deletions src/pmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
#include <vector>
#include <unordered_map>
#include <iostream>
#include <algorithm>
#include <cctype>

#ifdef PCM_PUGIXML_AVAILABLE
#include "pugixml/src/pugixml.hpp"
#endif

#ifdef __linux__
#include <unistd.h>
Expand Down Expand Up @@ -79,6 +85,16 @@ class TelemetryArrayLinux : public TelemetryArrayInterface
}
return t.at(uid).size();
}
static std::vector<size_t> getUIDs()
{
auto t = getTelemetryFiles();
std::vector<size_t> result;
for (auto & guid : t)
{
result.push_back(guid.first);
}
return result;
}
virtual ~TelemetryArrayLinux() override
{
}
Expand Down Expand Up @@ -124,6 +140,7 @@ class TelemetryArrayDummy : public TelemetryArrayInterface
public:
TelemetryArrayDummy(const size_t /* uid */, const size_t /* instance */) {};
static size_t numInstances(const size_t /* uid */) { return 0; };
static std::vector<size_t> getUIDs() { return std::vector<size_t>(); };
virtual ~TelemetryArrayDummy() override {};
size_t size() override { return 0;}; // in bytes
void load() override {};
Expand All @@ -150,6 +167,15 @@ size_t TelemetryArray::numInstances(const size_t uid)
#endif
}

std::vector<size_t> TelemetryArray::getUIDs()
{
#ifdef __linux__
return TelemetryArrayLinux::getUIDs();
#else
return TelemetryArrayDummy::getUIDs();
#endif
}

TelemetryArray::~TelemetryArray() {}

size_t TelemetryArray::size()
Expand All @@ -170,4 +196,116 @@ uint64 TelemetryArray::get(size_t qWordOffset, size_t lsb, size_t msb)
return impl->get(qWordOffset, lsb, msb);
}


bool TelemetryDB::loadFromXML(const std::string& pmtXMLPath)
{
#ifdef PCM_PUGIXML_AVAILABLE
pugi::xml_document doc;
auto result = doc.load_file((pmtXMLPath + "/xml/pmt.xml").c_str());

if (!result)
{
std::cerr << "Error: failed to load " << pmtXMLPath << "/xml/pmt.xml" << std::endl;
return false;
}

constexpr bool debug = false;

auto guids = TelemetryArray::getUIDs();
for (pugi::xml_node mapping: doc.child("pmt").child("mappings").children("mapping"))
{
auto guid = read_number(mapping.attribute("guid").value());
if (std::find(guids.begin(), guids.end(), guid) == guids.end())
{
// std::cerr << " guid " << std::hex << guid << " not found in telemetry files" << std::endl;
continue;
}
if (debug) std::cout << "Found mapping with guid: " << mapping.attribute("guid").value() << std::endl;
if (debug) std::cout << " Description: " << mapping.child("description").text().as_string() << std::endl;
const auto xmlset = mapping.child("xmlset");
const auto basedir = xmlset.child("basedir").text().as_string();
const auto aggregator = xmlset.child("aggregator").text().as_string();
const auto aggregator_path = pmtXMLPath + "/xml/" + basedir + "/" + aggregator;
if (debug) std::cout << " Aggregator XML path: " << aggregator_path << std::endl;

pugi::xml_document aggregatorDoc;
auto aggregatorResult = aggregatorDoc.load_file(aggregator_path.c_str());
if (!aggregatorResult)
{
std::cerr << "Error: failed to load " << aggregator_path << std::endl;
return false;
}

auto aggregatorNode = aggregatorDoc.child("TELEM:Aggregator");
const std::string aggregatorName = aggregatorNode.child("TELEM:name").text().as_string();
if (debug) std::cout << " Agregator name: " << aggregatorName << std::endl;
PMTRecord record;
record.uid = guid;
for (pugi::xml_node sampleGroup: aggregatorNode.children("TELEM:SampleGroup"))
{
const auto sampleID = sampleGroup.attribute("sampleID").as_uint();
if (debug) std::cout << " SampleID: " << sampleID << std::endl;
record.qWordOffset = sampleID;
for (pugi::xml_node sample: sampleGroup.children("TELC:sample"))
{
const auto name = sample.attribute("name").as_string();
const std::string sampleSubGroup = sample.child("TELC:sampleSubGroup").text().as_string();
record.fullName = aggregatorName + "." + sampleSubGroup + "." + name;
record.sampleType = sample.child("TELC:sampleType").text().as_string();
record.lsb = sample.child("TELC:lsb").text().as_uint();
record.msb = sample.child("TELC:msb").text().as_uint();
record.description = sample.child("TELC:description").text().as_string();
if (debug) std::cout << " ";
if (debug) record.print(std::cout);
records.push_back(record);
}
}

if (debug) std::cout << std::endl;
}

return true;
#else
(void)pmtXMLPath; // suppress warning
std::cerr << "INFO: pugixml library is not available" << std::endl;
return false;
#endif
}

std::vector<TelemetryDB::PMTRecord> TelemetryDB::lookup(const std::string & name)
{
std::vector<PMTRecord> result;
for (auto & record : records)
{
if (record.fullName.find(name) != std::string::npos)
{
result.push_back(record);
}
}
return result;
}

std::vector<TelemetryDB::PMTRecord> TelemetryDB::ilookup(const std::string & name)
{
std::vector<PMTRecord> result;
auto to_lower = [](const std::string & s) -> std::string
{
std::string result;
for (auto c : s)
{
result.push_back(std::tolower(c));
}
return result;
};
for (auto & record : records)
{
if (to_lower(record.fullName).find(to_lower(name)) != std::string::npos)
{
result.push_back(record);
}
}
return result;
}


}; // namespace pcm
28 changes: 28 additions & 0 deletions src/pmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "types.h"
#include <memory>
#include <vector>

namespace pcm {

Expand All @@ -28,10 +29,37 @@ class TelemetryArray : public TelemetryArrayInterface
public:
TelemetryArray(const size_t /* uid */, const size_t /* instance */);
static size_t numInstances(const size_t /* uid */);
static std::vector<size_t> getUIDs();
virtual ~TelemetryArray() override;
size_t size() override; // in bytes
void load() override;
uint64 get(size_t qWordOffset, size_t lsb, size_t msb) override;
};

class TelemetryDB
{
public:
struct PMTRecord
{
size_t uid;
std::string fullName;
std::string sampleType;
size_t qWordOffset;
uint32 lsb;
uint32 msb;
std::string description;
void print(std::ostream & os) const
{
os << "uid: " << uid << " fullName: " << fullName << " description: \"" << description <<
"\" sampleType: " << sampleType << " qWordOffset: " << qWordOffset << " lsb: " << lsb << " msb: " << msb << std::endl;
}
};
std::vector<PMTRecord> records;
TelemetryDB() = default;
bool loadFromXML(const std::string& pmtXMLPath);
virtual ~TelemetryDB() = default;
std::vector<PMTRecord> lookup(const std::string & name);
std::vector<PMTRecord> ilookup(const std::string & name);
};

} // namespace pcm
Loading

0 comments on commit ed9227b

Please sign in to comment.