From 9eaafe6b130ae744eec4899548a8080ce315f3bf Mon Sep 17 00:00:00 2001 From: "Nagaraj, Sriraksha" Date: Thu, 10 Jul 2025 11:41:12 -0500 Subject: [PATCH 1/2] [rocprofv3-avail] Documentation update and column formatting (#447) * addressing issues * doc fix * test fix * fix * fix formatting issue and doc update * fix column size * fix * fix formatting in output * tests fix * test fix * add new line * add new line * fix new line * fixing typo in using-rocprofv3-avail.rst --- source/bin/rocprofv3-avail.py | 111 ++++++++++++------ source/bin/rocprofv3.py | 2 +- source/bin/rocprofv3_avail_module/avail.py | 38 +++--- source/docs/how-to/using-pc-sampling.rst | 25 ++-- source/docs/how-to/using-rocprofv3-avail.rst | 44 +++---- source/lib/rocprofiler-sdk/CMakeLists.txt | 2 + .../rocprofiler-avail/CMakeLists.txt | 4 +- .../rocprofiler-avail/rocprofv3_avail.cpp | 0 .../rocprofiler-avail/rocprofv3_avail.hpp | 0 source/libexec/rocprofiler-sdk/CMakeLists.txt | 1 - tests/rocprofv3-avail/CMakeLists.txt | 4 +- tests/rocprofv3-avail/validate.py | 3 +- 12 files changed, 138 insertions(+), 96 deletions(-) rename source/{libexec => lib}/rocprofiler-sdk/rocprofiler-avail/CMakeLists.txt (94%) rename source/{libexec => lib}/rocprofiler-sdk/rocprofiler-avail/rocprofv3_avail.cpp (100%) rename source/{libexec => lib}/rocprofiler-sdk/rocprofiler-avail/rocprofv3_avail.hpp (100%) diff --git a/source/bin/rocprofv3-avail.py b/source/bin/rocprofv3-avail.py index 84e4b31a3bb..66d6ddb98ee 100755 --- a/source/bin/rocprofv3-avail.py +++ b/source/bin/rocprofv3-avail.py @@ -185,20 +185,32 @@ def get_basic_agent_info(info): return basic_info +def get_number_columns(max_name_len): + total_column_width = 120 + if sys.stdout.isatty(): + total_column_width = os.get_terminal_size().columns + width = total_column_width / (max_name_len + 1) + if width < 1: + return 1 + return int(width) + + def list_basic_agent(args, list_counters): - def print_agent_counter(counters, info): - names = ["{:20}".format(counter.name) for counter in counters] - print(" PMC:\n") - for idx in range(0, len(names), int(len(names) / 20)): - print( - " {}".format( - " ".join(names[idx : (idx + int(len(names) / 20))]) - ) - ) + def print_agent_counter(counters): + names_len = [len(counter.name) for counter in counters] + names = [ + "{name:{width}}".format(name=counter.name, width=max(names_len)) + for counter in counters + ] + columns = get_number_columns(max(names_len)) + print("{:30}:\n".format("PMC")) + for idx in range(0, len(names), columns): + print("{}".format(" ".join(names[idx : (idx + columns)]))) + print("\n") def print_basic_info(info): print("GPU:{}\n".format(info["logical_node_type_id"])) - print("\n".join([" {:20}: {}".format(key, itr) for key, itr in info.items()])) + print("\n".join(["{:30}:\t{}".format(key, itr) for key, itr in info.items()])) if not list_counters: print("\n") @@ -213,13 +225,13 @@ def print_basic_info(info): ): print_basic_info(get_basic_agent_info(info)) if list_counters: - print_agent_counter(agent_counters[agent], info) + print_agent_counter(agent_counters[agent]) break elif info["type"] == 2 and args.device is None: print_basic_info(get_basic_agent_info(info)) if list_counters: - print_agent_counter(agent_counters[agent], info) + print_agent_counter(agent_counters[agent]) def list_pc_sampling(args): @@ -228,7 +240,12 @@ def list_pc_sampling(args): print("Agents supporting PC Sampling\n") for agent in sampling_agents.keys(): info = agent_info_map[agent] - print("GPU:{}\nNAME:{}\n".format(info["logical_node_type_id"], info["name"])) + print( + "{:8}:\t{}\n{:8}:\t{}".format( + "GPU", info["logical_node_type_id"], "Name", info["name"] + ) + ) + print("\n") def info_pc_sampling(args): @@ -236,8 +253,12 @@ def info_pc_sampling(args): agent_info_map = avail.get_agent_info_map() for agent, configs in sampling_agents.items(): info = agent_info_map[agent] - print("GPU:{}\nNAME:{}".format(info["logical_node_type_id"], info["name"])) - print("configs:") + print( + "{:8}:\t{}\n{:8}:\t{}".format( + "GPU", info["logical_node_type_id"], "Name", info["name"] + ) + ) + print("{:8}:".format("configs")) for config in configs: print(config) print("\n") @@ -245,15 +266,16 @@ def info_pc_sampling(args): def listing(args): - def print_agent_counter(counters, info): - names = ["{:20}".format(counter.name) for counter in counters] - print("PMC:\n") - for idx in range(0, len(names), int(len(names) / 20)): - print( - " {}".format( - " ".join(names[idx : (idx + int(len(names) / 20))]) - ) - ) + def print_agent_counter(counters): + names_len = [len(counter.name) for counter in counters] + names = [ + "{name:{width}}".format(name=counter.name, width=max(names_len)) + for counter in counters + ] + columns = get_number_columns(max(names_len)) + print("{:30}:\n".format("PMC")) + for idx in range(0, len(names), columns): + print("{:30}".format(" ".join(names[idx : (idx + columns)]))) agent_counters = avail.get_counters() agent_info_map = avail.get_agent_info_map() @@ -264,12 +286,22 @@ def print_agent_counter(counters, info): and args.device is not None and info["logical_node_type_id"] == args.device ): - print("GPU:{}\nNAME:{}".format(info["logical_node_type_id"], info["name"])) - print_agent_counter(agent_counters[agent], info) + print( + "{:30}:\t{}\n{:30}:\t{}".format( + "GPU", info["logical_node_type_id"], "Name", info["name"] + ) + ) + print_agent_counter(agent_counters[agent]) + print("\n") break elif info["type"] == 2 and args.device is None: - print("GPU:{}\nNAME:{}".format(info["logical_node_type_id"], info["name"])) - print_agent_counter(agent_counters[agent], info) + print( + "{:30}:\t{}\n{:30}:\t{}".format( + "GPU", info["logical_node_type_id"], "Name", info["name"] + ) + ) + print_agent_counter(agent_counters[agent]) + print("\n") def info_pmc(args): @@ -285,7 +317,7 @@ def print_pmc_info(args, pmc_counters): else: for pmc in args.pmc: for counter in pmc_counters: - if pmc == counter.get_as_dict()["counter_name"]: + if pmc == counter.get_as_dict()["Counter_Name"]: print(counter) print("\n") @@ -295,11 +327,19 @@ def print_pmc_info(args, pmc_counters): and args.device is not None and info["logical_node_type_id"] == args.device ): - print("GPU:{}\nNAME:{}".format(info["logical_node_type_id"], info["name"])) + print( + "{}:{}\n{}:{}".format( + "GPU", info["logical_node_type_id"], "Name", info["name"] + ) + ) print_pmc_info(args, agent_counters[agent]) break elif info["type"] == 2 and args.device is None: - print("GPU:{}\nNAME:{}".format(info["logical_node_type_id"], info["name"])) + print( + "{}:{}\n{}:{}".format( + "GPU", info["logical_node_type_id"], "Name", info["name"] + ) + ) print_pmc_info(args, agent_counters[agent]) @@ -314,10 +354,12 @@ def process_info(args): def process_list(args): - if not args.agent and args.pc_sampling is None: + if args.agent is None and args.pc_sampling is None and args.pmc is None: listing(args) if args.agent: list_basic_agent(args, False) + if args.pmc: + listing(args) if args.pc_sampling: os.environ["ROCPROFILER_PC_SAMPLING_BETA_ENABLED"] = "on" list_pc_sampling(args) @@ -341,7 +383,7 @@ def get_counter_handle(counter_name): agent_counters = avail.get_counters() for agent, counters in agent_counters.items(): for counter in counters: - if counter.get_as_dict()["counter_name"] == counter_name: + if counter.get_as_dict()["Counter_Name"] == counter_name: return counter.counter_handle avail.fatal_error("Invalid counter name") @@ -418,8 +460,9 @@ def main(argv=None): ROCPROFV3_AVAIL_DIR = os.path.dirname(os.path.realpath(__file__)) ROCM_DIR = os.path.dirname(ROCPROFV3_AVAIL_DIR) ROCPROF_LIST_AVAIL_TOOL_LIBRARY = ( - f"{ROCM_DIR}/libexec/rocprofiler-sdk/librocprofv3-list-avail.so" + f"{ROCM_DIR}/lib/rocprofiler-sdk/librocprofv3-list-avail.so" ) + os.environ["ROCPROFILER_METRICS_PATH"] = f"{ROCM_DIR}/share/rocprofiler-sdk" avail.loadLibrary.libname = os.environ.get( "ROCPROF_LIST_AVAIL_TOOL_LIBRARY", ROCPROF_LIST_AVAIL_TOOL_LIBRARY ) diff --git a/source/bin/rocprofv3.py b/source/bin/rocprofv3.py index 97b0c6580b3..6cc43190db0 100755 --- a/source/bin/rocprofv3.py +++ b/source/bin/rocprofv3.py @@ -1056,7 +1056,7 @@ def _write_env_value(): f"{ROCM_DIR}/lib/rocprofiler-sdk/librocprofiler-sdk-tool-kokkosp.so" ) ROCPROF_LIST_AVAIL_TOOL_LIBRARY = ( - f"{ROCM_DIR}/libexec/rocprofiler-sdk/librocprofv3-list-avail.so" + f"{ROCM_DIR}/lib/rocprofiler-sdk/librocprofv3-list-avail.so" ) ROCPROF_TOOL_LIBRARY = resolve_library_path(ROCPROF_TOOL_LIBRARY, args) diff --git a/source/bin/rocprofv3_avail_module/avail.py b/source/bin/rocprofv3_avail_module/avail.py index 9e8dbecdbf5..21e3d7972ba 100644 --- a/source/bin/rocprofv3_avail_module/avail.py +++ b/source/bin/rocprofv3_avail_module/avail.py @@ -36,18 +36,16 @@ def fatal_error(msg, exit_code=1): def build_counter_string(obj): counter_str = "\n".join( - ["{:20}: {}".format(key, itr) for key, itr in obj.get_as_dict().items()] + ["{:20}:\t{}".format(key, itr) for key, itr in obj.get_as_dict().items()] ) - counter_str = counter_str + "\n" - for dim in obj.dimensions: - counter_str = counter_str + dim.__str__() - counter_str = counter_str + "\n" + + counter_str += "\n" + "{:20}:\t".format("Dimensions") + counter_str += " ".join(dim.__str__() for dim in obj.dimensions) return counter_str class dimension: - - columns = ["dimension_id", "dimension_name", "dimension_instances"] + columns = ["Dimension_Id", "Dimension_Name", "Dimension_Instances"] def __init__(self, dimension_id, dimension_name, dimension_instances): self.id = dimension_id @@ -58,18 +56,16 @@ def get_as_dict(self): return dict(zip((self.columns), [self.id, self.name, self.instances])) def __str__(self): - dimension = "{:20}: {}\n".format( - "dimension_name", self.get_as_dict()["dimension_name"] - ) - dimension += "{:20}: [0:{}]".format( - "dimension_instances", self.get_as_dict()["dimension_instances"] + dimension = "{}[0:{}]".format( + self.get_as_dict()["Dimension_Name"], + self.get_as_dict()["Dimension_Instances"] - 1, ) return dimension class counter: - columns = ["counter_name", "description"] + columns = ["Counter_Name", "Description"] def __init__( self, @@ -90,13 +86,13 @@ def get_as_dict(self): def __str__(self): return "\n".join( - ["{:20}: {}".format(key, itr) for key, itr in self.get_as_dict().items()] + ["{:20}:\t{}".format(key, itr) for key, itr in self.get_as_dict().items()] ) class derived_counter(counter): - columns = ["counter_name", "description", "expression"] + columns = ["Counter_Name", "Description", "Expression"] def __init__( self, @@ -125,7 +121,7 @@ def __str__(self): class basic_counter(counter): - columns = ["counter_name", "description", "block"] + columns = ["Counter_Name", "Description", "Block"] def __init__( self, @@ -154,7 +150,7 @@ def __str__(self): class pc_config: - columns = ["method", "unit", "min_interval", "max_interval", "flags"] + columns = ["Method", "Unit", "Min_Interval", "Max_Interval", "Flags"] def __init__(self, config_method, config_unit, min_interval, max_interval, flags): @@ -168,9 +164,9 @@ def __str__(self): return "\n".join( [ - " {:20}:{}".format( + " {:20}:\t{}".format( key, - itr if key == "method" or key == "unit" else self.get_value(key, itr), + itr if key == "Method" or key == "Unit" else self.get_value(key, itr), ) for key, itr in self.get_as_dict().items() ] @@ -178,9 +174,9 @@ def __str__(self): @staticmethod def get_value(key, itr): - if key == "min_interval" or key == "max_interval": + if key == "Min_Interval" or key == "Max_Interval": return itr.value - elif key == "flags": + elif key == "Flags": if itr.value == 1: return "interval pow2" else: diff --git a/source/docs/how-to/using-pc-sampling.rst b/source/docs/how-to/using-pc-sampling.rst index 10e82dfa534..203ad72dfb2 100644 --- a/source/docs/how-to/using-pc-sampling.rst +++ b/source/docs/how-to/using-pc-sampling.rst @@ -41,11 +41,14 @@ The output lists if ``rocprofv3`` supports PC sampling on the GPU and the suppor .. code-block:: bash - List available PC Sample Configurations for node_id 11 - Method: ROCPROFILER_PC_SAMPLING_METHOD_HOST_TRAP - Unit: ROCPROFILER_PC_SAMPLING_UNIT_TIME - Minimum_Interval: 1 - Maximum_Interval: 18446744073709551615 + GPU:0 + NAME:gfx90a + configs: + Method :host_trap + Unit :time + Min_Interval :1 + Max_Interval :18446744073709551615 + Flags :none The preceding output shows that the GPU supports PC sampling with the ``ROCPROFILER_PC_SAMPLING_METHOD_HOST_TRAP`` method and the ``ROCPROFILER_PC_SAMPLING_UNIT_TIME`` unit. The minimum and maximum intervals are also displayed. @@ -220,10 +223,14 @@ Output similar to the following indicates that the ``ROCPROFILER_PC_SAMPLING_MET .. code-block:: bash - Method: ROCPROFILER_PC_SAMPLING_METHOD_STOCHASTIC - Unit: ROCPROFILER_PC_SAMPLING_UNIT_CYCLES - Minimum_Interval: 256 - Maximum_Interval: 2147483648 + GPU:1 + NAME:gfx942 + configs: + Method :stochastic + Unit :cycle + Min_Interval :256 + Max_Interval :2147483648 + Flags :interval pow2 Please note that on gfx942, `ROCPROFILER_PC_SAMPLING_METHOD_STOCHASTIC` requires intervals to be specified in cycles, whose values are powers of 2 diff --git a/source/docs/how-to/using-rocprofv3-avail.rst b/source/docs/how-to/using-rocprofv3-avail.rst index d7371d24f04..2c0361e8209 100644 --- a/source/docs/how-to/using-rocprofv3-avail.rst +++ b/source/docs/how-to/using-rocprofv3-avail.rst @@ -42,60 +42,55 @@ The following table lists ``rocprofv3-avail`` command-line options categorized a | ``list`` | ``pmc-check`` - | Info options for detailed information of counters, agents, and pc-sampling configurations. - | List options for hw counters, agents and pc-sampling support". - | Checking counters collection support on agents. + | List options for hardware counters, agents and pc-sampling support. + | Checking if a set of counters can be collected together on agent. - -Available Hardware Counters -++++++++++++++++++++++++++++ -.. code-block:: bash - - rocprofv3-avail -d 0 - -The preceding command selects a device with logical node type id as 0 in the node. -The option is applied to further sub commands and options - .. code-block:: bash rocprofv3-avail list -The preceding command generates an output listing agents and hardware counters +The preceding command generates an output listing agents and hardware counters. .. code-block:: bash rocprofv3-avail list --agent -The preceding command generates an output listing basic info for all agents, if used with -d only basic info for device -d is listed. +The preceding command generates an output listing basic info for all agents, if used with ``-d``, only basic info for device ``-d`` is listed. +Following is the sample output .. code-block:: bash rocprofv3-avail list --pmc -The preceding command generates an output listing counters for all agents, if used with -d only counters on the the -d device is listed +The preceding command generates an output listing counters for all agents, if used with ``-d``, only counters on the ``-d`` device is listed. +Output contains following information: logical node id, name and list of PMC counters supported on the agent. .. code-block:: bash rocprofv3-avail list --pc-sampling -The preceding command generates an output listing agents that supports any kind of PC Sampling. -d option is not applicable here. +The preceding command generates an output listing agents that supports any kind of PC Sampling. ``-d`` option is not applicable here. + .. code-block:: bash rocprofv3-avail info -The preceding command generates an output with agent information and listing all counters -supported on each +The preceding command generates an output with agent information and listing all counters supported on each agent. .. code-block:: bash rocprofv3-avail info --pmc -The preceding command generates an output with the pmc info, if used with -d information of pmc for device -d is generated. +The preceding command generates an output with the pmc info, if used with ``-d`` information of pmc for device ``-d`` is generated. +Output includes the following information: logical node id, name, counter_name, description of the counter, dimensions, block/expression for every counter. .. code-block:: bash rocprofv3-avail info --pc-sampling -The preceding command generates list of supported PC sampling configurations for each agent that supports PC sampling. -d option is not applicable here. +The preceding command generates list of supported PC sampling configurations for each agent that supports PC sampling. ``-d`` option is not applicable here. +Output has following information: logical node id, method supported, unit, minimum sampling interval, maximum sampling interval +flags. .. code-block:: bash @@ -107,11 +102,10 @@ The preceding command checks if the pmc can be collected together rocprofv3-avail pmc-check -d 0 :device=1 - The preceding command checks if the pmc1 and pmc2 can be collected together on agent 0 - and pmc3 on agent 1 - +The preceding command checks if the pmc1 and pmc2 can be collected together on agent 0 and pmc3 on agent 1 + .. note:: - The above command writes the ouptut to the standard output. - + All commands writes to the standard output. + diff --git a/source/lib/rocprofiler-sdk/CMakeLists.txt b/source/lib/rocprofiler-sdk/CMakeLists.txt index 1fc1ddfe658..a3e84960c4a 100644 --- a/source/lib/rocprofiler-sdk/CMakeLists.txt +++ b/source/lib/rocprofiler-sdk/CMakeLists.txt @@ -158,3 +158,5 @@ set_target_properties( if(ROCPROFILER_BUILD_TESTS) add_subdirectory(tests) endif() + +add_subdirectory(rocprofiler-avail) diff --git a/source/libexec/rocprofiler-sdk/rocprofiler-avail/CMakeLists.txt b/source/lib/rocprofiler-sdk/rocprofiler-avail/CMakeLists.txt similarity index 94% rename from source/libexec/rocprofiler-sdk/rocprofiler-avail/CMakeLists.txt rename to source/lib/rocprofiler-sdk/rocprofiler-avail/CMakeLists.txt index 6d8a5ee603f..0061a71068a 100644 --- a/source/libexec/rocprofiler-sdk/rocprofiler-avail/CMakeLists.txt +++ b/source/lib/rocprofiler-sdk/rocprofiler-avail/CMakeLists.txt @@ -44,7 +44,7 @@ target_link_libraries( set_target_properties( rocprofv3-list-avail PROPERTIES LIBRARY_OUTPUT_DIRECTORY - ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBEXECDIR}/rocprofiler-sdk + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/rocprofiler-sdk SOVERSION ${PROJECT_VERSION_MAJOR} VERSION ${PROJECT_VERSION} BUILD_RPATH "\$ORIGIN:\$ORIGIN/.." @@ -52,6 +52,6 @@ set_target_properties( install( TARGETS rocprofv3-list-avail - DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/rocprofiler-sdk + DESTINATION ${CMAKE_INSTALL_LIBDIR}/rocprofiler-sdk COMPONENT tools EXPORT rocprofiler-sdk-tool-targets) diff --git a/source/libexec/rocprofiler-sdk/rocprofiler-avail/rocprofv3_avail.cpp b/source/lib/rocprofiler-sdk/rocprofiler-avail/rocprofv3_avail.cpp similarity index 100% rename from source/libexec/rocprofiler-sdk/rocprofiler-avail/rocprofv3_avail.cpp rename to source/lib/rocprofiler-sdk/rocprofiler-avail/rocprofv3_avail.cpp diff --git a/source/libexec/rocprofiler-sdk/rocprofiler-avail/rocprofv3_avail.hpp b/source/lib/rocprofiler-sdk/rocprofiler-avail/rocprofv3_avail.hpp similarity index 100% rename from source/libexec/rocprofiler-sdk/rocprofiler-avail/rocprofv3_avail.hpp rename to source/lib/rocprofiler-sdk/rocprofiler-avail/rocprofv3_avail.hpp diff --git a/source/libexec/rocprofiler-sdk/CMakeLists.txt b/source/libexec/rocprofiler-sdk/CMakeLists.txt index c380641a2bd..5b6a1606498 100644 --- a/source/libexec/rocprofiler-sdk/CMakeLists.txt +++ b/source/libexec/rocprofiler-sdk/CMakeLists.txt @@ -22,5 +22,4 @@ # -add_subdirectory(rocprofiler-avail) add_subdirectory(rocprofiler-sdk-launch-compiler) diff --git a/tests/rocprofv3-avail/CMakeLists.txt b/tests/rocprofv3-avail/CMakeLists.txt index 96cb7866a27..2c40cff554f 100644 --- a/tests/rocprofv3-avail/CMakeLists.txt +++ b/tests/rocprofv3-avail/CMakeLists.txt @@ -50,7 +50,7 @@ set_tests_properties( ENVIRONMENT "${test-rocprofv3-avail-env}" PASS_REGULAR_EXPRESSION - "GPU:[0-9]*\\n*;Name:\\t[a-zA-Z_]*\\n;counter_name:\\t[a-zA-Z_]*\\n;description:\\t(.*)\\n*;expression:\\t(.)*\\n*;block:\\t[a-zA-Z]*\\n*;dimension_name:\\t([A-Z_]*)\\n*; dimension_instances:\\t([[0-9]*:[0-9]*\\])*\\n*" + "GPU:[0-9]*\\n*;Name:\\t[a-zA-Z_]*\\n;Counter_Name:\\t[a-zA-Z_]*\\n;Description:\\t(.*)\\n*;Expression:\\t(.)*\\n*;Block:\\t[a-zA-Z]*\\n*;Dimensions:\\t([A-Z_]*)\\t([[0-9]*:[0-9]*\\])*\\n*" DISABLED "${IS_DISABLED}") @@ -64,7 +64,7 @@ set_tests_properties( ENVIRONMENT "${test-rocprofv3-avail-env};${enable_pc_sampling}" PASS_REGULAR_EXPRESSION - "GPU:[0-9]*\\n*;Name:\\t[a-zA-Z_]*\\n;method:(.*)\\n*;unit:(.*)\\n*;min_interval:[0-9]*\\n*;max_interval:[0-9]*\\n*;flags:(.*)\\n*" + "GPU[:0-9 ]+\\n*;Name[:a-zA-Z_ ]+\\n;configs[: ]+;Method:(.*)\\n*;Unit:(.*)\\n*;Min_Interval:[0-9]*\\n*;Max_Interval:[0-9]*\\n*;Flags:(.*)\\n*" DISABLED "${IS_DISABLED}") diff --git a/tests/rocprofv3-avail/validate.py b/tests/rocprofv3-avail/validate.py index 95e0eada671..3d85dc07749 100644 --- a/tests/rocprofv3-avail/validate.py +++ b/tests/rocprofv3-avail/validate.py @@ -110,8 +110,9 @@ def get_agent_name(agent_id): def set_library(rocm_path): ROCPROF_LIST_AVAIL_TOOL_LIBRARY = ( - f"{rocm_path}/libexec/rocprofiler-sdk/librocprofv3-list-avail.so" + f"{rocm_path}/lib/rocprofiler-sdk/librocprofv3-list-avail.so" ) + os.environ["ROCPROFILER_METRICS_PATH"] = f"{rocm_path}/share/rocprofiler-sdk" avail.loadLibrary.libname = os.environ.get( "ROCPROF_LIST_AVAIL_TOOL_LIBRARY", ROCPROF_LIST_AVAIL_TOOL_LIBRARY ) From bbc2a2597ba66eead10d1abc9e6711cc33e10de0 Mon Sep 17 00:00:00 2001 From: "Nagaraj, Sriraksha" Date: Tue, 22 Jul 2025 10:39:59 -0500 Subject: [PATCH 2/2] [rocprofv3-avail] - Add sample data (#514) * Add sample data for avail and remove color code for non terminal output * review comments * review comments * add documentation * test fix --- source/bin/rocprofv3-avail.py | 11 ++++---- source/bin/rocprofv3.py | 7 ++++- source/docs/data/list-avail.txt | 26 +++++++++++++++++++ source/docs/how-to/using-rocprofv3.rst | 6 +++++ source/lib/rocprofiler-sdk-tool/tool.cpp | 2 +- .../rocprofiler-avail/rocprofv3_avail.cpp | 2 +- 6 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 source/docs/data/list-avail.txt diff --git a/source/bin/rocprofv3-avail.py b/source/bin/rocprofv3-avail.py index 66d6ddb98ee..f0932a9fa72 100755 --- a/source/bin/rocprofv3-avail.py +++ b/source/bin/rocprofv3-avail.py @@ -217,7 +217,7 @@ def print_basic_info(info): agent_info_map = avail.get_agent_info_map() agent_counters = avail.get_counters() - for agent, info in agent_info_map.items(): + for agent, info in dict(sorted(agent_info_map.items())).items(): if ( info["type"] == 2 and args.device is not None @@ -238,7 +238,7 @@ def list_pc_sampling(args): sampling_agents = avail.get_pc_sample_configs() agent_info_map = avail.get_agent_info_map() print("Agents supporting PC Sampling\n") - for agent in sampling_agents.keys(): + for agent in dict(sorted(sampling_agents.items())).keys(): info = agent_info_map[agent] print( "{:8}:\t{}\n{:8}:\t{}".format( @@ -251,8 +251,9 @@ def list_pc_sampling(args): def info_pc_sampling(args): sampling_agents = avail.get_pc_sample_configs() agent_info_map = avail.get_agent_info_map() - for agent, configs in sampling_agents.items(): + for agent, configs in dict(sorted(sampling_agents.items())).items(): info = agent_info_map[agent] + print( "{:8}:\t{}\n{:8}:\t{}".format( "GPU", info["logical_node_type_id"], "Name", info["name"] @@ -280,7 +281,7 @@ def print_agent_counter(counters): agent_counters = avail.get_counters() agent_info_map = avail.get_agent_info_map() - for agent, info in agent_info_map.items(): + for agent, info in dict(sorted(agent_info_map.items())).items(): if ( info["type"] == 2 and args.device is not None @@ -321,7 +322,7 @@ def print_pmc_info(args, pmc_counters): print(counter) print("\n") - for agent, info in agent_info_map.items(): + for agent, info in dict(sorted(agent_info_map.items())).items(): if ( info["type"] == 2 and args.device is not None diff --git a/source/bin/rocprofv3.py b/source/bin/rocprofv3.py index 6cc43190db0..571be911ba8 100755 --- a/source/bin/rocprofv3.py +++ b/source/bin/rocprofv3.py @@ -1198,7 +1198,7 @@ def _write_env_value(): if args.marker_trace and not args.suppress_marker_preload: update_env("LD_PRELOAD", ROCPROF_ROCTX_LIBRARY, append=True) - if trace_count == 0: + if trace_count == 0 and len(app_args) != 0: warning("No tracing options were enabled.") # if no tracing was enabled but the options below were enabled, raise an error @@ -1403,6 +1403,11 @@ def log_config(_env): ) else: app_args = [sys.executable, path, "info", "--pmc"] + for itr in ("ROCPROF", "ROCPROFILER", "ROCTX"): + update_env( + f"{itr}_LOG_LEVEL", + "error", + ) exit_code = subprocess.check_call( [sys.executable, path, "info", "--pc-sampling"], env=app_env, diff --git a/source/docs/data/list-avail.txt b/source/docs/data/list-avail.txt new file mode 100644 index 00000000000..9fe41deac5a --- /dev/null +++ b/source/docs/data/list-avail.txt @@ -0,0 +1,26 @@ +GPU : 0 +Name : gfx90a +configs : + Method : host_trap + Unit : time + Min_Interval : 1 + Max_Interval : 18446744073709551615 + Flags : none + +GPU:0 +Name:gfx90a +Counter_Name : processor_id_low +Description : Constant value processor_id_low from agent properties + + +Counter_Name : ALUStalledByLDS +Description : The percentage of GPUTime ALU units are stalled by the LDS input queue being full or the output queue being not ready. If there are LDS bank conflicts, reduce them. Otherwise, try reducing the number of LDS accesses if possible. Value range: 0% (optimal) to 100% (bad). +Expression : 400*reduce(SQ_WAIT_INST_LDS,sum)/reduce(SQ_WAVES,sum)/reduce(GRBM_GUI_ACTIVE,max) +Dimensions : DIMENSION_INSTANCE[0:0] + +Counter_Name : SQ_WAVES +Description : Count number of waves sent to distributed sequencers (SQs). This value represents the number of waves that are sent to each SQ. This only counts new waves sent since the start of collection (for dispatch profiling this is the timeframe of kernel execution, for agent profiling it is the timeframe between start_context and read counter data). A sum of all SQ_WAVES values will give the total number of waves started by the application during the collection timeframe. Returns one value per-SE (aggregates of SIMD values). +Block : SQ +Dimensions : DIMENSION_INSTANCE[0:0] DIMENSION_SHADER_ENGINE[0:7] + +... diff --git a/source/docs/how-to/using-rocprofv3.rst b/source/docs/how-to/using-rocprofv3.rst index a223fe0f01d..ed8beb13ee5 100644 --- a/source/docs/how-to/using-rocprofv3.rst +++ b/source/docs/how-to/using-rocprofv3.rst @@ -780,6 +780,12 @@ To see the counters available on the GPU, use: rocprofv3 --list-avail +Sample output for the list-avail command: + +.. file:: /data/list-avail.txt + :width: 100% + :align: center + You can also customize the counters according to the requirement. Such counters are named :ref:`extra-counters`. For a comprehensive list of counters available on MI200, see `MI200 performance counters and metrics `_. diff --git a/source/lib/rocprofiler-sdk-tool/tool.cpp b/source/lib/rocprofiler-sdk-tool/tool.cpp index 00c80ec8e4f..8ca149d8d93 100644 --- a/source/lib/rocprofiler-sdk-tool/tool.cpp +++ b/source/lib/rocprofiler-sdk-tool/tool.cpp @@ -1477,7 +1477,7 @@ initialize_logging() { auto logging_cfg = rocprofiler::common::logging_config{.install_failure_handler = true}; common::init_logging("ROCPROF", logging_cfg); - FLAGS_colorlogtostderr = true; + FLAGS_colorlogtostderr = isatty(fileno(stderr)) == 1 ? true : false; } } diff --git a/source/lib/rocprofiler-sdk/rocprofiler-avail/rocprofv3_avail.cpp b/source/lib/rocprofiler-sdk/rocprofiler-avail/rocprofv3_avail.cpp index 065f4814691..cc2bf270d10 100644 --- a/source/lib/rocprofiler-sdk/rocprofiler-avail/rocprofv3_avail.cpp +++ b/source/lib/rocprofiler-sdk/rocprofiler-avail/rocprofv3_avail.cpp @@ -78,7 +78,7 @@ initialize_logging() { auto logging_cfg = rocprofiler::common::logging_config{.install_failure_handler = true}; common::init_logging("ROCPROF", logging_cfg); - FLAGS_colorlogtostderr = true; + FLAGS_colorlogtostderr = isatty(fileno(stderr)) == 1 ? true : false; } tool::metadata&