diff --git a/.github/workflows/freebsd_build.yml b/.github/workflows/freebsd_build.yml index c6826fe4..a9559446 100644 --- a/.github/workflows/freebsd_build.yml +++ b/.github/workflows/freebsd_build.yml @@ -25,12 +25,12 @@ jobs: submodules: recursive - name: build in FreeBSD VM id: build - uses: cross-platform-actions/action@cdc9ee69ef84a5f2e59c9058335d9c57bcb4ac86 # v0.25.0 + uses: cross-platform-actions/action@2d97d42e1972a17b045fd709a422f7e55a86230d with: memory: 2048 shell: sh operating_system: freebsd - version: '14.1' + version: '14.2' run: | sudo mkdir -p /usr/local/etc/pkg/repos sudo sh -c 'echo "FreeBSD: { url: \"https://pkg.FreeBSD.org/\${ABI}/quarterly\", mirror_type: \"srv\", enabled: yes }" > /usr/local/etc/pkg/repos/FreeBSD.conf' diff --git a/.github/workflows/freebsd_scan_build.yml b/.github/workflows/freebsd_scan_build.yml index 53818ea8..c501f3e9 100644 --- a/.github/workflows/freebsd_scan_build.yml +++ b/.github/workflows/freebsd_scan_build.yml @@ -25,12 +25,12 @@ jobs: submodules: recursive - name: clang scan build in FreeBSD VM id: clang-scan-build - uses: cross-platform-actions/action@cdc9ee69ef84a5f2e59c9058335d9c57bcb4ac86 # v0.25.0 + uses: cross-platform-actions/action@2d97d42e1972a17b045fd709a422f7e55a86230d with: memory: 2048 shell: sh operating_system: freebsd - version: '14.1' + version: '14.2' run: | sudo mkdir -p /usr/local/etc/pkg/repos sudo sh -c 'echo "FreeBSD: { url: \"https://pkg.FreeBSD.org/\${ABI}/quarterly\", mirror_type: \"srv\", enabled: yes }" > /usr/local/etc/pkg/repos/FreeBSD.conf' diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f8f3ebf..df7e3730 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,6 +138,8 @@ if(UNIX) # APPLE, LINUX, FREE_BSD message(STATUS "CMAKE_CXX_FLAGS_DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}") message(STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + install(DIRECTORY "perfmon" DESTINATION ${CMAKE_INSTALL_DATADIR}/pcm) + endif(UNIX) if(PCM_FUZZ) diff --git a/Intel-PMT b/Intel-PMT index 5e72e20e..134c36d1 160000 --- a/Intel-PMT +++ b/Intel-PMT @@ -1 +1 @@ -Subproject commit 5e72e20ed6eb3b9a5532cf2a063a640b5f7891cf +Subproject commit 134c36d1d4dd344a9893e02e350554f3df507a80 diff --git a/perfmon b/perfmon index 4a897731..2336912d 160000 --- a/perfmon +++ b/perfmon @@ -1 +1 @@ -Subproject commit 4a897731495f4f68ad4a597b557fdf39d24b4601 +Subproject commit 2336912dd4f4f8f5313914dc30e4f1e87429ab5b diff --git a/src/pcm-raw.cpp b/src/pcm-raw.cpp index 743f8b02..9a2df544 100644 --- a/src/pcm-raw.cpp +++ b/src/pcm-raw.cpp @@ -65,6 +65,7 @@ void print_usage(const string & progname) cout << " -e cha/config=0,name=UNC_CHA_CLOCKTICKS/ -e imc/fixed,name=DRAM_CLOCKS/\n"; #ifdef PCM_SIMDJSON_AVAILABLE cout << " -e NAME where the NAME is an event from https://github.com/intel/perfmon event lists\n"; + cout << " -? | /? => print all events that can be monitored on the host platform along with a description\n"; cout << " -ep path | /ep path => path to event list directory (default is the current directory)\n"; #endif cout << " -yc | --yescores | /yc => enable specific cores to output\n"; @@ -217,16 +218,24 @@ bool initPMUEventMap() inited = true; const auto mapfile = "mapfile.csv"; const auto mapfilePath = eventFileLocationPrefix + "/" + mapfile; + const auto mapfilePathAlt = getInstallPathPrefix() + "perfmon/" + mapfile; std::ifstream in(mapfilePath); std::string line, item; if (!in.is_open()) { - cerr << "ERROR: File " << mapfilePath << " can't be open. \n"; - cerr << " Use -ep /perfmon option if you cloned PCM source repository recursively with submodules,\n"; - cerr << " or run 'git clone https://github.com/intel/perfmon' to download the perfmon event repository and use -ep option\n"; - cerr << " or download the file from https://raw.githubusercontent.com/intel/perfmon/main/" << mapfile << " \n"; - return false; + in.open(mapfilePathAlt); + if (!in.is_open()) + { + cerr << "ERROR: File " << mapfilePath << " or " << mapfilePathAlt << " can't be open. \n"; + #ifndef _MSC_VER + cerr << " run 'make install' in the pcm build directory if you cloned PCM source repository recursively with submodules, or\n"; + #endif + cerr << " use -ep /perfmon option if you cloned PCM source repository recursively with submodules,\n"; + cerr << " or run 'git clone https://github.com/intel/perfmon' to download the perfmon event repository and use -ep option\n"; + cerr << " or download the file from https://raw.githubusercontent.com/intel/perfmon/main/" << mapfile << " \n"; + return false; + } } int32 FMSPos = -1; int32 FilenamePos = -1; @@ -255,12 +264,12 @@ bool initPMUEventMap() cerr << "Can't read first line from " << mapfile << " \n"; return false; } - // cout << FMSPos << " " << FilenamePos << " " << EventTypetPos << "\n"; + DBG(1, FMSPos , " " , FilenamePos , " " , EventTypetPos); assert(FMSPos >= 0); assert(FilenamePos >= 0); assert(EventTypetPos >= 0); const std::string ourFMS = PCM::getInstance()->getCPUFamilyModelString(); - // cout << "Our FMS: " << ourFMS << "\n"; + DBG(1, "Our FMS: " , ourFMS); std::multimap eventFiles; cerr << "Matched event files:\n"; while (std::getline(in, line)) @@ -300,6 +309,7 @@ bool initPMUEventMap() { const std::string path1 = eventFileLocationPrefix + evfile.second; const std::string path2 = eventFileLocationPrefix + evfile.second.substr(evfile.second.rfind('/')); + const std::string path3 = getInstallPathPrefix() + "perfmon" + evfile.second; if (std::ifstream(path1).good()) { @@ -309,9 +319,13 @@ bool initPMUEventMap() { path = path2; } + else if (std::ifstream(path3).good()) + { + path = path3; + } else { - std::cerr << "ERROR: Can't open event file at location " << path1 << " or " << path2 << "\n"; + std::cerr << "ERROR: Can't open event file at location " << path1 << " or " << path2 << " or " << path3 << "\n"; printError(); return false; } @@ -351,7 +365,7 @@ bool initPMUEventMap() catch (std::exception& e) { cerr << "Error while opening and/or parsing " << path << " : " << e.what() << "\n"; - printError(); + printError(); return false; } } @@ -418,6 +432,15 @@ class EventMap { return res; } + static void print_event_description(const std::string &eventStr) { + if (PMUEventMapJSON.find(eventStr) != PMUEventMapJSON.end()) { + const auto eventObj = PMUEventMapJSON[eventStr]; + for (const auto & key : {"BriefDescription", "PublicDescription"}) + std::cout << key << " : " << eventObj[key] << "\n"; + return; + } + } + static void print_event(const std::string &eventStr) { if (PMUEventMapJSON.find(eventStr) != PMUEventMapJSON.end()) { const auto eventObj = PMUEventMapJSON[eventStr]; @@ -437,10 +460,43 @@ class EventMap { } } } + } + static void print_event_debug(const std::string &eventStr, const int debugLevel = 1) { + if (PMUEventMapJSON.find(eventStr) != PMUEventMapJSON.end()) { + const auto eventObj = PMUEventMapJSON[eventStr]; + for (const auto & keyValue : eventObj) + DBG(debugLevel, "JSON " , keyValue.key , " : " , keyValue.value); + } + + for (auto &EventMapTSV : PMUEventMapsTSV) { + if (EventMapTSV.find(eventStr) != EventMapTSV.end()) { + const auto &col_names = EventMapTSV["COL_NAMES"]; + const auto event = EventMapTSV[eventStr]; + if (EventMapTSV.find(eventStr) != EventMapTSV.end()) { + for (size_t i = 0 ; i < col_names.size() ; i++) + DBG(debugLevel, "TSV " , col_names[i] , " : " , event[i]); + } + } + } } }; +void printAllEventDescriptions() +{ + if (initPMUEventMap() == false) + { + cerr << "ERROR: PMU Event map can not be initialized\n"; + return; + } + for (const auto& event : PMUEventMapJSON) + { + std::cout << event.first << "\n"; + EventMap::print_event_description(event.first); + std::cout << "\n"; + } +} + AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEventStr) { if (initPMUEventMap() == false) @@ -448,8 +504,8 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven cerr << "ERROR: PMU Event map can not be initialized\n"; return AddEventStatus::Failed; } - // cerr << "Parsing event " << fullEventStr << "\n"; - // cerr << "size: " << fullEventStr.size() << "\n"; + DBG(2, "Parsing event " , fullEventStr); + DBG(2, "size: " , fullEventStr.size()); while (fullEventStr.empty() == false && fullEventStr.back() == ' ') { fullEventStr.resize(fullEventStr.size() - 1); // remove trailing spaces @@ -469,7 +525,9 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven const auto eventStr = EventTokens[0]; - // cerr << "size: " << eventStr.size() << "\n"; + EventMap::print_event_debug(eventStr); + + DBG(2, "size: " , eventStr.size()); PCM::RawEventConfig config = { {0,0,0,0,0}, "" }; std::string pmuName; @@ -623,7 +681,7 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven { std::string unit = EventMap::getField(eventStr, "Unit"); lowerCase(unit); - // std::cout << eventStr << " is uncore event for unit " << unit << "\n"; + DBG(2, eventStr , " is uncore event for unit " , unit); pmuName = (pmuNameMap.find(unit) == pmuNameMap.end()) ? unit : pmuNameMap[unit]; } @@ -631,9 +689,9 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven if (1) { - // cerr << "pmuName: " << pmuName << " full event "<< fullEventStr << " \n"; + DBG(2, "pmuName: " , pmuName , " full event ", fullEventStr); std::string CounterStr = EventMap::getField(eventStr, "Counter"); - // cout << "Counter: " << CounterStr << "\n"; + DBG(2, "Counter: " , CounterStr); int fixedCounter = -1; fixed = (pcm_sscanf(CounterStr) >> s_expect("Fixed counter ") >> fixedCounter) ? true : false; if (!fixed){ @@ -707,15 +765,15 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven }; for (const auto & registerKeyValue : PMUDeclObj) { - // cout << "Setting " << registerKeyValue.key << " : " << registerKeyValue.value << "\n"; + DBG(2, "Setting " , registerKeyValue.key , " : " , registerKeyValue.value); simdjson::dom::object fieldDescriptionObj = registerKeyValue.value; - // cout << " config: " << uint64_t(fieldDescriptionObj["Config"]) << "\n"; - // cout << " Position: " << uint64_t(fieldDescriptionObj["Position"]) << "\n"; + DBG(2, " config: " , uint64_t(fieldDescriptionObj["Config"])); + DBG(2, " Position: " , uint64_t(fieldDescriptionObj["Position"])); const std::string fieldNameStr{ registerKeyValue.key.begin(), registerKeyValue.key.end() }; if (fieldNameStr == "MSRIndex") { string fieldValueStr = EventMap::getField(eventStr, fieldNameStr); - // cout << "MSR field " << fieldNameStr << " value is " << fieldValueStr << " (" << read_number(fieldValueStr.c_str()) << ") offcore=" << offcore << "\n"; + DBG(2, "MSR field " , fieldNameStr , " value is " , fieldValueStr , " (" , read_number(fieldValueStr.c_str()) , ") offcore=" , offcore);; lowerCase(fieldValueStr); if (fieldValueStr == "0" || fieldValueStr == "0x00") { @@ -732,7 +790,7 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven } MSRIndexStr = MSRIndexes[offcoreEventIndex]; } - // cout << " MSR field " << fieldNameStr << " value is " << MSRIndexStr << " (" << read_number(MSRIndexStr.c_str()) << ") offcore=" << offcore << "\n"; + DBG(2, " MSR field " , fieldNameStr , " value is " , MSRIndexStr , " (" , read_number(MSRIndexStr.c_str()) , ") offcore=" , offcore); MSRObject = registerKeyValue.value[MSRIndexStr]; const string msrValueStr = EventMap::getField(eventStr, "MSRValue"); setMSRValue(msrValueStr); @@ -745,7 +803,7 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven } if (!EventMap::isField(eventStr, fieldNameStr)) { - // cerr << fieldNameStr << " not found\n"; + DBG(2, fieldNameStr , " not found"); if (fieldDescriptionObj["DefaultValue"].error() == NO_SUCH_FIELD) { cerr << "ERROR: DefaultValue not provided for field \"" << fieldNameStr << "\" in " << path << "\n"; @@ -773,7 +831,7 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven } fieldValueStr = offcoreCodes[offcoreEventIndex]; } - // cout << " field " << fieldNameStr << " value is " << fieldValueStr << " (" << read_number(fieldValueStr.c_str()) << ") offcore=" << offcore << "\n"; + DBG(2, " field " , fieldNameStr , " value is " , fieldValueStr , " (" , read_number(fieldValueStr.c_str()) , ") offcore=" , offcore); setConfig(config, fieldDescriptionObj, read_number(fieldValueStr.c_str()), position); } } @@ -921,13 +979,6 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven } } - /* - for (const auto& keyValue : eventObj) - { - cout << keyValue.key << " : " << keyValue.value << "\n"; - } - */ - printEvent(pmuName, fixed, config); return AddEventStatus::OK; @@ -2475,6 +2526,13 @@ int mainThrows(int argc, char * argv[]) extendPrintout = true; continue; } +#if PCM_SIMDJSON_AVAILABLE + else if (check_argument_equals(*argv, {"-?", "/?"})) + { + printAllEventDescriptions(); + return 0; + } +#endif else if (check_argument_equals(*argv, {"-single-header", "/single-header"})) { singleHeader = true; @@ -2736,9 +2794,6 @@ int mainThrows(int argc, char * argv[]) } m->globalUnfreezeUncoreCounters(); - //cout << "Time elapsed: " << dec << fixed << AfterTime - BeforeTime << " ms\n"; - //cout << "Called sleep function for " << dec << fixed << delay_ms << " ms\n"; - printAll(group, m, SysBeforeState, SysAfterState, BeforeState, AfterState, BeforeUncoreState, AfterUncoreState, BeforeSocketState, AfterSocketState, PMUConfigs, groupNr == nGroups); if (nGroups == 1) { diff --git a/src/simdjson b/src/simdjson index 078e2c90..7382dc2b 160000 --- a/src/simdjson +++ b/src/simdjson @@ -1 +1 @@ -Subproject commit 078e2c90739a80563fb425d7f7011f3a2c7b7da9 +Subproject commit 7382dc2be88e53fbc35cb50369b831855656f0fd