Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 83 additions & 39 deletions source/bin/rocprofv3-avail.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,91 +185,124 @@ 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")

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
and info["logical_node_type_id"] == args.device
):
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):
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("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):
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("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")
print("\n")


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()

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
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):
Expand All @@ -285,21 +318,29 @@ 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")

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
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])


Expand All @@ -314,10 +355,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)
Expand All @@ -341,7 +384,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")

Expand Down Expand Up @@ -418,8 +461,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
)
Expand Down
9 changes: 7 additions & 2 deletions source/bin/rocprofv3.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
38 changes: 17 additions & 21 deletions source/bin/rocprofv3_avail_module/avail.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -125,7 +121,7 @@ def __str__(self):

class basic_counter(counter):

columns = ["counter_name", "description", "block"]
columns = ["Counter_Name", "Description", "Block"]

def __init__(
self,
Expand Down Expand Up @@ -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):

Expand All @@ -168,19 +164,19 @@ 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()
]
)

@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:
Expand Down
26 changes: 26 additions & 0 deletions source/docs/data/list-avail.txt
Original file line number Diff line number Diff line change
@@ -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]

...
Loading