From 65291e03049016df9dbda0cb9658d1313f5fd115 Mon Sep 17 00:00:00 2001 From: Giovanni LB Date: Wed, 31 May 2023 19:58:42 -0300 Subject: [PATCH] SWDEV-380521: Fixed perfetto data corruption for roctx and terminal. Added MPI rank to timeline. Change-Id: I9d133c495b2809891f5df8b3e6504df13beb3d4e [ROCm/rocprofiler commit: dd85b1d5287ad409d685bfff7d70e06ea21b6a1f] --- projects/rocprofiler/CHANGELOG.md | 2 + .../rocprofiler/plugin/perfetto/perfetto.cpp | 42 +++++++------- .../featuretests/profiler/profiler_gtest.cpp | 55 ++++++++++++++----- .../featuretests/profiler/profiler_gtest.h | 20 +++++-- 4 files changed, 78 insertions(+), 41 deletions(-) diff --git a/projects/rocprofiler/CHANGELOG.md b/projects/rocprofiler/CHANGELOG.md index 7472de9ec7..065f56210a 100644 --- a/projects/rocprofiler/CHANGELOG.md +++ b/projects/rocprofiler/CHANGELOG.md @@ -229,8 +229,10 @@ The resulting `a.out` will depend on - Support for MI300 XCC modes for rocprof v2. - MI300 individual XCC counters dumped per-xcc as separate records but with same record-id and kernel dispatch info - Naming for MPI ranks. Filenames containing "%rank" are replaced by variables "MPI_RANK", "OMPI_COMM_WORLD_RANK" or "MV2_COMM_WORLD_RANK". +- MPI Rank will appear in perfetto track names. ### Fixed - Samples are fixed to show the new usage of phases. - Plugin option validates the plugin names. - Fixing rocsys, for rocsys options, rocsys -h can be called - "--output-file" option ignored when no output folder was specified. +- Perfetto crash when using ROCTX and/or no output file specified. diff --git a/projects/rocprofiler/plugin/perfetto/perfetto.cpp b/projects/rocprofiler/plugin/perfetto/perfetto.cpp index 9bd7443f93..552a46dbbe 100644 --- a/projects/rocprofiler/plugin/perfetto/perfetto.cpp +++ b/projects/rocprofiler/plugin/perfetto/perfetto.cpp @@ -97,12 +97,6 @@ class perfetto_plugin_t { const char* temp_file_name = getenv("OUT_FILE_NAME"); output_file_name = temp_file_name ? std::string(temp_file_name) + "_" : ""; - if (output_dir == nullptr && temp_file_name == nullptr) { - stream_.copyfmt(std::cout); - stream_.clear(std::cout.rdstate()); - stream_.basic_ios::rdbuf(std::cout.rdbuf()); - return; - } if (output_dir == nullptr) output_dir = "./"; @@ -186,37 +180,39 @@ class perfetto_plugin_t { } std::string replace_MPI_macros(std::string output_file_name) { - std::unordered_map MPI_BUILTINS = { - {"MPI_RANK", "%rank"}, - {"OMPI_COMM_WORLD_RANK", "%rank"}, - {"MV2_COMM_WORLD_RANK", "%rank"} + std::vector MPI_BUILTINS = { + "MPI_RANK", "OMPI_COMM_WORLD_RANK", "MV2_COMM_WORLD_RANK" }; bIsMPI = false; - for (const auto& [envvar, key] : MPI_BUILTINS) { - size_t key_find = output_file_name.rfind(key); - if (key_find == std::string::npos) continue; // Does not contain a %?rank var + for (const char* envvar : MPI_BUILTINS) { + const char* rank_env_var = getenv(envvar); + if (rank_env_var == nullptr) continue; // MPI var is does not exist - const char* env_var_set = getenv(envvar); - if (env_var_set == nullptr) continue; // MPI_COMM_WORLD_x var is does not exist - - int rank = atoi(env_var_set); - output_file_name = output_file_name.substr(0, key_find) + std::to_string(rank) - + output_file_name.substr(key_find + std::string(key).size()); - if (!bIsMPI) - MPI_rank = rank; + MPI_rank = atoi(rank_env_var); bIsMPI = true; + break; } + size_t key_find = output_file_name.rfind("%rank"); + if (key_find != std::string::npos) { // Contains a %?rank string + output_file_name = output_file_name.substr(0, key_find) + std::to_string(MPI_rank) + + output_file_name.substr(key_find + std::string("%rank").size()); + } return output_file_name; } std::string get_thread_track_str() { - return rocprofiler::string_printf("Node: %s Process ID: %lu Thread ID:", hostname_, GetPid()); + if (!bIsMPI) + rocprofiler::string_printf("Node: %s Process ID: %lu Thread ID:", hostname_, GetPid()); + std::stringstream thread_track_str; + thread_track_str << "Rank: " << MPI_rank << " (" << hostname_ + << ") Process ID:" << GetPid() << " Thread ID:"; + return thread_track_str.str(); } std::string get_device_track_str() { - return rocprofiler::string_printf("Node: %s Device:", hostname_); + return rocprofiler::string_printf("Node: %s Device:", hostname_); } const char* GetDomainName(rocprofiler_tracer_activity_domain_t domain) { diff --git a/projects/rocprofiler/tests/featuretests/profiler/profiler_gtest.cpp b/projects/rocprofiler/tests/featuretests/profiler/profiler_gtest.cpp index 3811a472e4..c2849f375e 100644 --- a/projects/rocprofiler/tests/featuretests/profiler/profiler_gtest.cpp +++ b/projects/rocprofiler/tests/featuretests/profiler/profiler_gtest.cpp @@ -62,7 +62,6 @@ static void init_test_path() { } } - /** * Sets application enviornment by seting HSA_TOOLS_LIB. */ @@ -1322,18 +1321,24 @@ TEST(ProfilerMPTest, WhenRunningMultiProcessTestItPasses) { */ /* -void FilePluginTest::RunApplication(const char* app_name, const char* appParams) { +void PluginTests::RunApplication(const char* app_name, const char* appParams) { if (is_installed_path()) return; // Only run these tests from build init_test_path(); unsetenv("OUTPUT_FOLDER"); std::stringstream os; - os << binary_path << " --hsa-activity " << appParams << " "; + os << binary_path << appParams << " "; os << test_app_path << app_name; ProcessApplication(os); } +void PluginTests::ProcessApplication(std::stringstream& ss) { + FILE* handle = popen(ss.str().c_str(), "r"); + ASSERT_NE(handle, nullptr); + pclose(handle); +} + bool FilePluginTest::hasFileInDir(const std::string& filename, const char* directory) { if (is_installed_path()) return true; // Only run these tests from build @@ -1346,12 +1351,6 @@ bool FilePluginTest::hasFileInDir(const std::string& filename, const char* direc return false; } -void FilePluginTest::ProcessApplication(std::stringstream& ss) { - FILE* handle = popen(ss.str().c_str(), "r"); - ASSERT_NE(handle, nullptr); - pclose(handle); -} - class VectorAddFileOnlyTest : public FilePluginTest { protected: virtual void SetUp() { @@ -1373,7 +1372,7 @@ TEST_F(VectorAddFileOnlyTest, WhenRunningProfilerWithFilePluginTest) { class VectorAddFolderOnlyTest : public FilePluginTest { protected: virtual void SetUp() { - RunApplication("hip_vectoradd", "-d ./plugin_test_folder_path"); + RunApplication("hip_vectoradd", " --hsa-activity --hip-activity -d ./plugin_test_folder_path"); } virtual void TearDown() { std::experimental::filesystem::remove_all("./plugin_test_folder_path"); } bool hasFile(){ return hasFileInDir("", "./plugin_test_folder_path"); } @@ -1386,7 +1385,7 @@ TEST_F(VectorAddFolderOnlyTest, WhenRunningProfilerWithFilePluginTest) { class VectorAddFileAndFolderTest : public FilePluginTest { protected: virtual void SetUp() { - RunApplication("hip_vectoradd", "-d ./plugin_test_folder_path -o file_test_name"); + RunApplication("hip_vectoradd", " --hip-activity -d ./plugin_test_folder_path -o file_test_name"); } virtual void TearDown() { std::experimental::filesystem::remove_all("./plugin_test_folder_path"); } bool hasFile(){ return hasFileInDir("file_test_name", "./plugin_test_folder_path"); } @@ -1400,7 +1399,7 @@ class VectorAddFilenameMPITest : public FilePluginTest { protected: virtual void SetUp() { setenv("MPI_RANK", "7", true); - RunApplication("hip_vectoradd", "-d ./plugin_test_folder_path -o test_%rank_"); + RunApplication("hip_vectoradd", " --hip-activity -d ./plugin_test_folder_path -o test_%rank_"); } virtual void TearDown() { std::experimental::filesystem::remove_all("./plugin_test_folder_path"); @@ -1412,4 +1411,34 @@ class VectorAddFilenameMPITest : public FilePluginTest { TEST_F(VectorAddFilenameMPITest, WhenRunningProfilerWithFilePluginTest) { EXPECT_EQ(hasFile(), true); } -*/ \ No newline at end of file + +bool PerfettoPluginTest::hasFileInDir(const std::string& filename, const char* directory) { + if (is_installed_path()) return true; // Only run these tests from build + + for (const auto& entry : std::experimental::filesystem::directory_iterator(directory)) { + std::string entrypath = std::string(entry.path().filename()); + if (entrypath.find(".pftrace") == std::string::npos) + continue; + if (entrypath.substr(0, filename.size()) == filename) + return true; + } + return false; +} + +class VectorAddPerfettoMPITest : public PerfettoPluginTest { + protected: + virtual void SetUp() { + setenv("MPI_RANK", "7", true); + RunApplication("hip_vectoradd", " -d ./plugin_test_folder_path -o test_%rank_ --plugin perfetto"); + } + virtual void TearDown() { + std::experimental::filesystem::remove_all("./plugin_test_folder_path"); + unsetenv("MPI_RANK"); + } + bool hasFile(){ return hasFileInDir("test_7_", "./plugin_test_folder_path"); } +}; + +TEST_F(VectorAddPerfettoMPITest, WhenRunningProfilerWithPerfettoTest) { + EXPECT_EQ(hasFile(), true); +} +*/ diff --git a/projects/rocprofiler/tests/featuretests/profiler/profiler_gtest.h b/projects/rocprofiler/tests/featuretests/profiler/profiler_gtest.h index a6c0da8c45..0cd0e6d324 100644 --- a/projects/rocprofiler/tests/featuretests/profiler/profiler_gtest.h +++ b/projects/rocprofiler/tests/featuretests/profiler/profiler_gtest.h @@ -116,16 +116,26 @@ class ProfilerTest : public ApplicationParser { /* --------------------------------------------------------------------------*/ /* -class FilePluginTest : public ::testing::Test { +class PluginTests : public ::testing::Test { public: //!< Sets application environment by seting rocprofv2. void RunApplication(const char* app_name, const char* appParams); - - //!< Checks wether a file beginning with "filename" exists in "directory" - static bool hasFileInDir(const std::string& filename, const char* directory); private: //!< Runs a given appllication with the hsa activity. void ProcessApplication(std::stringstream& ss); -}; */ +}; + +class FilePluginTest : public PluginTests { + public: + //!< Checks wether a file beginning with "filename" exists in "directory" + static bool hasFileInDir(const std::string& filename, const char* directory); +}; + +class PerfettoPluginTest : public PluginTests { + public: + //!< Checks wether a file beginning with "filename" and ending with "pftrace" exists in "directory" + static bool hasFileInDir(const std::string& filename, const char* directory); +}; +*/ #endif // TESTS_FEATURETESTS_PROFILER_GTESTS_APPS_PROFILER_GTEST_H_