Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Push 2025 01 10 #899

Merged
merged 18 commits into from
Jan 10, 2025
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
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
26 changes: 24 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2022-2024, Intel Corporation
# Copyright (c) 2022-2025, Intel Corporation

cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.12)

project(PCM)

Expand Down 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
Loading
Loading