From 7b2f68e7983f587a964661814c7dd11c989c91db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Crnobrnja=20Maleti=C4=87?= Date: Thu, 11 Dec 2025 16:36:01 +0100 Subject: [PATCH] Handle cpu name having colons (#2155) * Handle cpu name having colons * Adding tests to verify * clang-format fix --------- Co-authored-by: bgopesh --- .../source/lib/rocprofiler-sdk/agent.cpp | 37 ++++++++------ .../source/lib/tests/common/parse.cpp | 49 +++++++++++++++++++ 2 files changed, 72 insertions(+), 14 deletions(-) diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/agent.cpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/agent.cpp index fe5af0c1d6..70f9bb5ff2 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/agent.cpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/agent.cpp @@ -137,7 +137,7 @@ parse_cpu_info() for(const auto& itr : bitr) { auto match = sdk::parse::tokenize(itr, std::vector{": "}); - if(match.size() == 2) + if(match.size() >= 2) { auto get_stol = [_label = std::string_view{itr}](const auto& _value) -> long { try @@ -153,24 +153,33 @@ parse_cpu_info() return 0; }; - const auto& value = match.back(); + // For cases with multiple colons, join all tokens after the first one + // e.g. "model name : AMD EPYC : 100-000000248" split into + // ["model name", "AMD EPYC", "100-000000248"] with the last two tokens joined + // back together with ": " + std::string value; + if(match.size() == 2) + { + value = match.back(); + } + else + { + // Join all tokens after the first one with ": " separator + for(size_t i = 1; i < match.size(); ++i) + { + if(i > 1) value += ": "; + value += match[i]; + } + } if(itr.find("vendor_id") == 0) info_v.vendor_id = value; else if(itr.find("model name") == 0) { - info_v.model_name = value; - size_t first_colon_pos = value.find(':'); - // This handles the case where the model name has multiple colons - // Example "model name : AMD EPYC : 100-000000248" - if(first_colon_pos != std::string::npos) - { - // Extract the model name after the first colon - info_v.model_name = value.substr(first_colon_pos + 1); - // Remove leading and trailing whitespaces - info_v.model_name = - sdk::parse::strip(std::string{info_v.model_name}, " \t\n\v\f\r"); - } + info_v.model_name = value; + // Remove leading and trailing whitespaces + info_v.model_name = + sdk::parse::strip(std::string{info_v.model_name}, " \t\n\v\f\r"); } else if(itr.find("processor") == 0) info_v.processor = get_stol(value); diff --git a/projects/rocprofiler-sdk/source/lib/tests/common/parse.cpp b/projects/rocprofiler-sdk/source/lib/tests/common/parse.cpp index 5e3b63c85f..dc6995c28f 100644 --- a/projects/rocprofiler-sdk/source/lib/tests/common/parse.cpp +++ b/projects/rocprofiler-sdk/source/lib/tests/common/parse.cpp @@ -68,3 +68,52 @@ TEST(parse, strip) test_message, stripped_message); } + +TEST(parse, cpu_info_model_name) +{ + // Simulate the logic in agent.cpp + auto parse_line = [](std::string_view line) -> std::string { + auto match = sdk::parse::tokenize(line, std::vector{": "}); + std::string model_name; + + if(match.size() >= 2) + { + std::string value; + if(match.size() == 2) + { + value = match.back(); + } + else + { + // Join all tokens after the first one with ": " separator + for(size_t i = 1; i < match.size(); ++i) + { + if(i > 1) value += ": "; + value += match[i]; + } + } + + if(line.find("model name") == 0) + { + model_name = value; + // Remove leading and trailing whitespaces + model_name = sdk::parse::strip(std::string{model_name}, " \t\n\v\f\r"); + } + } + return model_name; + }; + + // Case 1: Normal model name + { + const auto* line = "model name : AMD EPYC 7742 64-Core Processor"; + auto name = parse_line(line); + EXPECT_EQ(name, "AMD EPYC 7742 64-Core Processor"); + } + + // Case 2: Model name with colons (The bug fix case) + { + const auto* line = "model name : AMD EPYC : 100-000000248"; + auto name = parse_line(line); + EXPECT_EQ(name, "AMD EPYC : 100-000000248"); + } +}