Files
rocm-systems/source/bin/rocprofv3_avail.py
T
Nagaraj, Sriraksha c42bdc3128 rocprofv3: rocprofv3-avail tool (#15)
* support avail tool

Updating avail library and script

Listing on Std output incase the output folder is not given

Extending list metrics test

misc fix

misc fix

fixing memory leak

changing list-metrics to list-avail

fixing formatting issue

Fixing CMakeLists

Add test for list avil with trace

Fix test fail

clang tidy errors fixed

Removing build commands for rocprofv3-trigger-list

Addressing review changes

addressing review comment

moving avail to libexec

merge fix

Fix test failures

updating doc

Fix doc error

* updating legacy doc

* fix formatting issue

* Addressing review comments
2024-12-04 18:34:10 -06:00

420 строки
16 KiB
Python

#!/usr/bin/env python3
import ctypes
import pathlib
import os
import io
import csv
import socket
class derived_counter:
def __init__(
self, counter_name, counter_description, counter_expression, counter_dimensions
):
self.name = counter_name
self.description = counter_description
self.expression = counter_expression
self.dimensions = counter_dimensions
class basic_counter:
def __init__(
self, counter_name, counter_description, counter_block, counter_dimensions
):
self.name = counter_name
self.description = counter_description
self.block = counter_block
self.dimensions = counter_dimensions
class pc_config:
def __init__(self, config_method, config_unit, min_interval, max_interval):
self.method = config_method
self.unit = config_unit
self.min_interval = min_interval
self.max_interval = max_interval
MAX_STR = 256
libname = os.environ.get("ROCPROF_LIST_AVAIL_TOOL_LIBRARY")
c_lib = ctypes.CDLL(libname)
c_lib.get_number_of_counters.restype = ctypes.c_ulong
c_lib.get_number_of_pc_sample_configs.restype = ctypes.c_ulong
c_lib.get_number_of_dimensions.restype = ctypes.c_ulong
c_lib.get_number_of_counters.argtypes = [ctypes.c_int]
c_lib.get_number_of_pc_sample_configs.argtypes = [ctypes.c_int]
c_lib.get_number_of_dimensions.argtypes = [ctypes.c_int]
c_lib.get_pc_sample_config.argtypes = [
ctypes.c_ulong,
ctypes.c_ulong,
ctypes.POINTER(ctypes.POINTER(ctypes.c_char * MAX_STR)),
ctypes.POINTER(ctypes.POINTER(ctypes.c_char * MAX_STR)),
ctypes.POINTER(ctypes.c_ulong),
ctypes.POINTER(ctypes.c_ulong),
]
c_lib.get_counters_info.argtypes = [
ctypes.c_ulong,
ctypes.c_int,
ctypes.POINTER(ctypes.c_ulong),
ctypes.POINTER(ctypes.POINTER(ctypes.c_char * MAX_STR)),
ctypes.POINTER(ctypes.POINTER(ctypes.c_char * MAX_STR)),
ctypes.POINTER(ctypes.c_int),
]
c_lib.get_counter_expression.argtypes = [
ctypes.c_ulong,
ctypes.c_int,
ctypes.POINTER(ctypes.POINTER(ctypes.c_char * MAX_STR)),
]
c_lib.get_counter_dimension.argtypes = [
ctypes.c_ulong,
ctypes.c_ulong,
ctypes.POINTER(ctypes.c_ulong),
ctypes.POINTER(ctypes.POINTER(ctypes.c_char * MAX_STR)),
ctypes.POINTER(ctypes.c_ulong),
]
c_lib.get_counter_block.argtypes = [
ctypes.c_ulong,
ctypes.c_ulong,
ctypes.POINTER(ctypes.POINTER(ctypes.c_char * MAX_STR)),
]
c_lib.get_number_of_agents.restype = ctypes.c_size_t
c_lib.get_agent_node_id.restype = ctypes.c_ulong
c_lib.get_agent_node_id.argtypes = [ctypes.c_int]
agent_derived_counter_map = dict()
agent_basic_counter_map = dict()
agent_pc_sample_config_map = dict()
def get_counters(node_id):
no_of_counters = c_lib.get_number_of_counters(node_id)
basic_counters = []
derived_counters = []
for counter_idx in range(0, no_of_counters):
name_args = ctypes.POINTER(ctypes.c_char * MAX_STR)()
description_args = ctypes.POINTER(ctypes.c_char * MAX_STR)()
block_args = ctypes.POINTER(ctypes.c_char * MAX_STR)()
is_derived_args = ctypes.c_int()
counter_id_args = ctypes.c_ulong()
c_lib.get_counters_info(
node_id,
counter_idx,
ctypes.byref(counter_id_args),
name_args,
description_args,
ctypes.byref(is_derived_args),
)
is_derived = is_derived_args.value
counter_id = counter_id_args.value
no_of_dimensions = c_lib.get_number_of_dimensions(counter_id)
name = ctypes.cast(name_args, ctypes.c_char_p).value.decode("utf-8")
description = ctypes.cast(description_args, ctypes.c_char_p).value.decode("utf-8")
dimensions_stream = io.StringIO()
for dim in range(0, no_of_dimensions):
dim_name_args = ctypes.POINTER(ctypes.c_char * MAX_STR)()
dim_instance_args = ctypes.c_ulong()
dimension_id_args = ctypes.c_ulong()
c_lib.get_counter_dimension(
counter_id,
dim,
ctypes.byref(dimension_id_args),
dim_name_args,
ctypes.byref(dim_instance_args),
)
dim_name = ctypes.cast(dim_name_args, ctypes.c_char_p).value.decode("utf-8")
dim_instance = dim_instance_args.value
dimensions_stream.write(dim_name)
dimensions_stream.write("[0:")
dimensions_stream.write(str(dim_instance - 1))
dimensions_stream.write("]")
if dim != no_of_dimensions - 1:
dimensions_stream.write("\t")
if is_derived:
expression_args = ctypes.POINTER(ctypes.c_char * MAX_STR)()
c_lib.get_counter_expression(node_id, counter_idx, expression_args)
counter_expression = ctypes.cast(
expression_args, ctypes.c_char_p
).value.decode("utf-8")
derived_counters.append(
derived_counter(
name, description, counter_expression, dimensions_stream.getvalue()
)
)
else:
block_args = ctypes.POINTER(ctypes.c_char * MAX_STR)()
c_lib.get_counter_block(node_id, counter_idx, block_args)
block = ctypes.cast(block_args, ctypes.c_char_p).value.decode("utf-8")
basic_counters.append(
basic_counter(name, description, block, dimensions_stream.getvalue())
)
dimensions_stream.close()
agent_derived_counter_map[node_id] = derived_counters
agent_basic_counter_map[node_id] = basic_counters
def get_pc_sample_configs(node_id):
no_of_pc_sample_configs = c_lib.get_number_of_pc_sample_configs(node_id)
pc_sample_configs = []
if no_of_pc_sample_configs:
for config_idx in range(0, no_of_pc_sample_configs):
method_args = ctypes.POINTER(ctypes.c_char * MAX_STR)()
unit_args = ctypes.POINTER(ctypes.c_char * MAX_STR)()
min_interval = ctypes.c_ulong()
max_interval = ctypes.c_ulong()
c_lib.get_pc_sample_config(
node_id,
config_idx,
method_args,
unit_args,
ctypes.byref(min_interval),
ctypes.byref(max_interval),
)
method = ctypes.cast(method_args, ctypes.c_char_p).value.decode("utf-8")
unit = ctypes.cast(unit_args, ctypes.c_char_p).value.decode("utf-8")
pc_sample_configs.append(
pc_config(method, unit, min_interval.value, max_interval.value)
)
agent_pc_sample_config_map[node_id] = pc_sample_configs
def process_filename(file_path, file_type):
filename = os.environ.get(
"ROCPROF_OUTPUT_FILE_NAME", socket.gethostname() + "/" + str(os.getpid())
)
if os.path.exists(file_path) and os.path.isfile(file_path):
fatal_error("ROCPROFILER_OUTPUT_PATH already exists and is not a directory")
elif not os.path.exists(file_path):
os.makedirs(file_path)
output_filename = ""
if file_type == "derived":
output_filename = filename + "_" + "derived_metrics" + ".csv"
elif file_type == "basic":
output_filename = filename + "_" + "basic_metrics" + ".csv"
elif file_type == "pc_sample_config":
output_filename = filename + "_" + "pc_sample_config" + ".csv"
output_path = os.path.join(file_path, output_filename)
output_path_parent = os.path.dirname(output_path)
if not os.path.exists(output_path_parent):
os.makedirs(output_path_parent)
elif os.path.exists(output_path_parent) and os.path.isfile(output_path_parent):
fatal_error("ROCPROFILER_OUTPUT_PATH already exists and is not a directory")
return output_path
def generate_output(agent_ids):
list_avail_file = os.environ.get("ROCPROF_OUTPUT_LIST_AVAIL_FILE")
if list_avail_file:
file_path = os.environ.get("ROCPROF_OUTPUT_PATH")
derived_output_file = process_filename(file_path, "derived")
basic_output_file = process_filename(file_path, "basic")
pc_sample_config_file = process_filename(file_path, "pc_sample_config")
with open(derived_output_file, "w") as csvfile:
print(f"Opened result file: {derived_output_file}")
fieldnames = ["Agent_Id", "Name", "Description", "Expression", "Dimensions"]
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for node_id, counters in agent_derived_counter_map.items():
for counter in counters:
writer.writerow(
{
"Agent_Id": node_id,
"Name": counter.name,
"Description": counter.description,
"Expression": counter.expression,
"Dimensions": counter.dimensions,
}
)
with open(basic_output_file, "w") as csvfile:
print(f"Opened result file: {basic_output_file}")
fieldnames = ["Agent_Id", "Name", "Description", "Block", "Dimensions"]
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for node_id, counters in agent_basic_counter_map.items():
for counter in counters:
if counter.block:
writer.writerow(
{
"Agent_Id": node_id,
"Name": counter.name,
"Description": counter.description,
"Block": counter.block,
"Dimensions": counter.dimensions,
}
)
with open(pc_sample_config_file, "w") as csvfile:
print(f"Opened result file: {pc_sample_config_file}")
fieldnames = [
"Agent_Id",
"Method",
"Unit",
"Minimum_Interval",
"Maximum_Interval",
]
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for node_id, configs in agent_pc_sample_config_map.items():
for config in configs:
writer.writerow(
{
"Agent_Id": node_id,
"Method": config.method,
"Unit": config.unit,
"Minimum_Interval": config.min_interval,
"Maximum_Interval": config.max_interval,
}
)
else:
for node_id in agent_ids:
print(f"gpu-agent:{node_id}\n")
if node_id in agent_basic_counter_map.keys():
basic_counters_stream = io.StringIO()
counters = agent_basic_counter_map[node_id]
for counter in counters:
if counter.block:
basic_counters_stream.write("Name:")
basic_counters_stream.write("\t")
basic_counters_stream.write(str(counter.name))
basic_counters_stream.write("\n")
basic_counters_stream.write("Description:")
basic_counters_stream.write("\t")
basic_counters_stream.write(str(counter.description))
basic_counters_stream.write("\n")
basic_counters_stream.write("Block:")
basic_counters_stream.write("\t")
basic_counters_stream.write(str(counter.block))
basic_counters_stream.write("\n")
basic_counters_stream.write("Dimensions:")
basic_counters_stream.write("\t")
basic_counters_stream.write(str(counter.dimensions))
basic_counters_stream.write("\n")
basic_counters = basic_counters_stream.getvalue()
print("List Metrics Basic\n")
print(basic_counters)
print("\n")
basic_counters_stream.close()
if node_id in agent_derived_counter_map.keys():
derived_counters_stream = io.StringIO()
counters = agent_derived_counter_map[node_id]
for counter in counters:
derived_counters_stream.write("Name:")
derived_counters_stream.write("\t")
derived_counters_stream.write(str(counter.name))
derived_counters_stream.write("\n")
derived_counters_stream.write("Description:")
derived_counters_stream.write("\t")
derived_counters_stream.write(str(counter.description))
derived_counters_stream.write("\n")
derived_counters_stream.write("Expression:")
derived_counters_stream.write("\t")
derived_counters_stream.write(str(counter.expression))
derived_counters_stream.write("\n")
derived_counters_stream.write("Dimensions:")
derived_counters_stream.write("\t")
derived_counters_stream.write(str(counter.dimensions))
derived_counters_stream.write("\n")
derived_counters = derived_counters_stream.getvalue()
print("List Metrics Derived\n")
print(derived_counters)
print("\n")
derived_counters_stream.close()
if node_id in agent_pc_sample_config_map.keys():
pc_sample_config_stream = io.StringIO()
configs = agent_pc_sample_config_map[node_id]
for config in configs:
pc_sample_config_stream.write("Method:")
pc_sample_config_stream.write("\t")
pc_sample_config_stream.write(str(config.method))
pc_sample_config_stream.write("\n")
pc_sample_config_stream.write("Unit:")
pc_sample_config_stream.write("\t")
pc_sample_config_stream.write(str(config.unit))
pc_sample_config_stream.write("\n")
pc_sample_config_stream.write("Minimum_Interval:")
pc_sample_config_stream.write("\t")
pc_sample_config_stream.write(str(config.min_interval))
pc_sample_config_stream.write("\n")
pc_sample_config_stream.write("Maximum_Interval:")
pc_sample_config_stream.write("\t")
pc_sample_config_stream.write(str(config.max_interval))
pc_sample_config_stream.write("\n")
pc_sample = pc_sample_config_stream.getvalue()
print(
"List available PC Sample Configurations for node_id\t"
+ str(node_id)
+ "\n"
)
print(pc_sample)
print("\n")
pc_sample_config_stream.close()
else:
print("PC Sampling not supported on node_id\t" + str(node_id) + "\n")
if __name__ == "__main__":
# Load the shared library into ctypes
c_lib.avail_tool_init()
no_of_agents = c_lib.get_number_of_agents()
agent_ids = []
for idx in range(0, no_of_agents):
node_id = c_lib.get_agent_node_id(idx)
agent_ids.append(node_id)
get_counters(node_id)
get_pc_sample_configs(node_id)
generate_output(agent_ids)