Skip to content

Commit 81250fa

Browse files
authored
rocprofv3: Update rocprofv3 command line for ATT (#201)
* rocprofv3: suppress agent info when no data collected * Update output config serialization - full serialization of output configuration * Update rocprofiler-sdk-att/tests - add version and soversion - change output directory - generate libatt_decoder_summary - disable tests instead of removing them * Update rocprofv3 command-line - make --att-library-path hidden by default - simplify check_att_capability - reorder pc sampling options - add hidden --echo option - remove ROCPROF_LIST_AVAIL_TOOL_LIBRARY from preload * Add new rocprofv3 tests for specify the ATT library path * Tweak to rocprofv3-test-hsa-multiqueue-att tests * Update rocprofv3 tool to enable output with att * Fix standalone test installation * Revert to fetchcontent_makeavailable to fetchcontent_populate * Revert tests/common/CMakeLists.txt --------- Co-authored-by: Jonathan R. Madsen <jonathanrmadsen@gmail.com> [ROCm/rocprofiler-sdk commit: 59b41ab]
1 parent 5cc6244 commit 81250fa

File tree

12 files changed

+403
-193
lines changed

12 files changed

+403
-193
lines changed

projects/rocprofiler-sdk/source/bin/rocprofv3.py

Lines changed: 118 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -107,16 +107,21 @@ def search_path(path_list):
107107

108108
def check_att_capability(args):
109109

110-
path = []
111110
ROCPROFV3_DIR = os.path.dirname(os.path.realpath(__file__))
112111
ROCM_DIR = os.path.dirname(ROCPROFV3_DIR)
113-
support_input = {}
114-
tmp_parser = argparse.ArgumentParser(add_help=False)
112+
ld_library_paths = []
113+
for itr in os.environ.get("LD_LIBRARY_PATH", "").split(":") + [f"{ROCM_DIR}/lib"]:
114+
# don't add duplicates
115+
if itr not in ld_library_paths:
116+
ld_library_paths += [itr]
117+
118+
tmp_parser = argparse.ArgumentParser(add_help=False, allow_abbrev=False)
115119
tmp_parser.add_argument(
116120
"--att-library-path",
117121
default=os.environ.get(
118-
"ATT_LIBRARY_PATH", os.environ.get("LD_LIBRARY_PATH", None)
119-
),
122+
"ROCPROF_ATT_LIBRARY_PATH", ":".join(ld_library_paths)
123+
).split(":"),
124+
nargs="+",
120125
type=str,
121126
required=False,
122127
)
@@ -129,52 +134,28 @@ def check_att_capability(args):
129134
required=False,
130135
)
131136

132-
tmp_data = {}
133-
att_args, unparsed_args = tmp_parser.parse_known_args(args)
134-
tmp_keys = list(att_args.__dict__.keys())
137+
att_args, _ = tmp_parser.parse_known_args(args)
135138

136-
for itr in tmp_keys:
137-
if has_set_attr(att_args, itr):
138-
tmp_data[itr] = getattr(att_args, itr)
139-
140-
data = dotdict(tmp_data)
141-
if data.input:
139+
support = search_path(att_args.att_library_path)
140+
support_input = {}
141+
if att_args.input:
142142
# If index of a pass in input file is a key in the support_input dict, then that pass has att-library-path arg
143-
args_list = parse_input(data.input)
143+
args_list = parse_input(att_args.input)
144144
for index, itr in enumerate(args_list):
145145
if itr.att_library_path:
146-
library_path = []
147-
if ":" in itr.att_library_path:
148-
library_path.extend(itr.att_library_path.split(":"))
149-
else:
150-
library_path.append(itr.att_library_path)
151-
support = search_path(library_path)
152-
# If the att-library-path in the input file for a pass is valid, then the value of index key in the dict, support_input, is updated to that valid path
153-
if support:
154-
support_input[index] = set(support)
155-
else:
156-
# If the att-library-path in the input file for a pass is invalid, then the value of index key in the dict, support_input, is empty
157-
support_input[index] = []
158-
if data.att_library_path:
159-
if ":" in data.att_library_path:
160-
path.extend(data.att_library_path.split(":"))
161-
else:
162-
path.append(data.att_library_path)
163-
else:
164-
path.append(f"{ROCM_DIR}/lib")
165-
path.append(f"{ROCM_DIR}/lib64")
166-
167-
support = search_path(set(path))
168-
if support:
169-
if len(path) == 1:
170-
os.environ["ATT_LIBRARY_PATH"] = path[0]
171-
os.environ["ROCPROF_ATT_LIBRARY_PATH"] = path[0]
172-
else:
173-
os.environ["ATT_LIBRARY_PATH"] = ":".join(path)
174-
os.environ["ROCPROF_ATT_LIBRARY_PATH"] = ":".join(path)
175-
return support, support_input
146+
library_path = (
147+
itr.att_library_path.split(":")
148+
if isinstance(itr.att_library_path, str)
149+
else itr.att_library_path
150+
)
151+
_support = search_path(library_path)
152+
# If the att-library-path in the input file for a pass is valid, then the value of index key in the dict,
153+
# support_input, is updated to that valid path
154+
# If the att-library-path in the input file for a pass is invalid, then the value of index key in the dict,
155+
# support_input, is empty
156+
support_input[index] = set(_support) if support else []
176157

177-
return None, support_input
158+
return (att_args.att_library_path, set(support), support_input)
178159

179160

180161
class booleanArgAction(argparse.Action):
@@ -279,36 +260,6 @@ def add_parser_bool_argument(gparser, *args, **kwargs):
279260
help="Collect tracing data for HIP API, HSA API, Marker (ROCTx) API, RCCL API, ROCDecode API, Memory operations (copies, scratch, and allocations), and Kernel dispatches.",
280261
)
281262

282-
pc_sampling_options = parser.add_argument_group("PC sampling options")
283-
284-
add_parser_bool_argument(
285-
pc_sampling_options,
286-
"--pc-sampling-beta-enabled",
287-
help="enable pc sampling support; beta version",
288-
)
289-
290-
pc_sampling_options.add_argument(
291-
"--pc-sampling-unit",
292-
help="",
293-
default=None,
294-
type=str.lower,
295-
choices=("instructions", "cycles", "time"),
296-
)
297-
298-
pc_sampling_options.add_argument(
299-
"--pc-sampling-method",
300-
help="",
301-
default=None,
302-
type=str.lower,
303-
choices=("stochastic", "host_trap"),
304-
)
305-
306-
pc_sampling_options.add_argument(
307-
"--pc-sampling-interval",
308-
help="",
309-
default=None,
310-
type=int,
311-
)
312263
basic_tracing_options = parser.add_argument_group("Basic tracing options")
313264

314265
# Add the arguments
@@ -408,6 +359,37 @@ def add_parser_bool_argument(gparser, *args, **kwargs):
408359
nargs="*",
409360
)
410361

362+
pc_sampling_options = parser.add_argument_group("PC sampling options")
363+
364+
add_parser_bool_argument(
365+
pc_sampling_options,
366+
"--pc-sampling-beta-enabled",
367+
help="enable pc sampling support; beta version",
368+
)
369+
370+
pc_sampling_options.add_argument(
371+
"--pc-sampling-unit",
372+
help="",
373+
default=None,
374+
type=str.lower,
375+
choices=("instructions", "cycles", "time"),
376+
)
377+
378+
pc_sampling_options.add_argument(
379+
"--pc-sampling-method",
380+
help="",
381+
default=None,
382+
type=str.lower,
383+
choices=("stochastic", "host_trap"),
384+
)
385+
386+
pc_sampling_options.add_argument(
387+
"--pc-sampling-interval",
388+
help="",
389+
default=None,
390+
type=int,
391+
)
392+
411393
post_processing_options = parser.add_argument_group("Post-processing tracing options")
412394

413395
add_parser_bool_argument(
@@ -564,13 +546,6 @@ def add_parser_bool_argument(gparser, *args, **kwargs):
564546
nargs="*",
565547
)
566548

567-
advanced_options.add_argument(
568-
"--att-library-path",
569-
default=os.environ.get(
570-
"ATT_LIBRARY_PATH", os.environ.get("LD_LIBRARY_PATH", None)
571-
),
572-
help="ATT library path to find decoder library",
573-
)
574549
# below is available for CI because LD_PRELOADing a library linked to a sanitizer library
575550
# causes issues in apps where HIP is part of shared library.
576551
add_parser_bool_argument(
@@ -579,6 +554,13 @@ def add_parser_bool_argument(gparser, *args, **kwargs):
579554
help=argparse.SUPPRESS,
580555
)
581556

557+
# just echo the command line
558+
add_parser_bool_argument(
559+
advanced_options,
560+
"--echo",
561+
help=argparse.SUPPRESS,
562+
)
563+
582564
if args is None:
583565
args = sys.argv[1:]
584566

@@ -592,22 +574,35 @@ def add_parser_bool_argument(gparser, *args, **kwargs):
592574
app_args = args[(idx + 1) :]
593575
break
594576

595-
supported_list, is_support_input = check_att_capability(rocp_args)
596-
if supported_list or len(is_support_input) != 0:
577+
default_att_lib_path, att_support_args, att_support_inp = check_att_capability(
578+
rocp_args
579+
)
580+
if att_support_args or len(att_support_inp) != 0:
597581
choice_list = []
598-
for keys, values in is_support_input.items():
582+
for keys, values in att_support_inp.items():
599583
choice_list.extend(values)
600-
if supported_list:
601-
choice_list.extend(list(supported_list))
584+
if att_support_args:
585+
choice_list.extend(list(att_support_args))
586+
587+
# remove duplicates
588+
choice_list = list(set(choice_list))
602589

603-
att_options = parser.add_argument_group("Advanced Thread Trace")
590+
att_options = parser.add_argument_group("Advanced Thread Trace (ATT) options")
604591

605592
add_parser_bool_argument(
606593
att_options,
607594
"--advanced-thread-trace",
595+
"--att",
608596
help="Enable ATT",
609597
)
610598

599+
att_options.add_argument(
600+
"--att-library-path",
601+
help="Search path(s) to decoder library/libraries",
602+
default=default_att_lib_path if not att_support_inp else None,
603+
nargs="+",
604+
)
605+
611606
att_options.add_argument(
612607
"--att-target-cu",
613608
help="ATT target compute unit",
@@ -639,7 +634,9 @@ def add_parser_bool_argument(gparser, *args, **kwargs):
639634
att_options.add_argument(
640635
"--att-parse",
641636
type=str.lower,
642-
default=None,
637+
default=(
638+
choice_list[0] if len(choice_list) == 1 and not att_support_inp else None
639+
),
643640
help="Select ATT Parse method from the choices",
644641
choices=set(choice_list),
645642
)
@@ -651,7 +648,7 @@ def add_parser_bool_argument(gparser, *args, **kwargs):
651648
help="Serialize all kernels",
652649
)
653650

654-
return (parser.parse_args(rocp_args), app_args, supported_list, is_support_input)
651+
return (parser.parse_args(rocp_args), app_args, att_support_args, att_support_inp)
655652

656653

657654
def parse_yaml(yaml_file):
@@ -792,7 +789,9 @@ def get_attr(key):
792789
and has_set_attr(inp_args, itr)
793790
and getattr(cmd_args, itr) != getattr(inp_args, itr)
794791
):
795-
raise RuntimeError(f"conflicting value for {itr}")
792+
raise RuntimeError(
793+
f"conflicting value for {itr} : {getattr(cmd_args, itr)} vs {getattr(inp_args, itr)}"
794+
)
796795
else:
797796
data[itr] = get_attr(itr)
798797

@@ -889,7 +888,6 @@ def _write_env_value():
889888
prepend_preload = [itr for itr in args.preload if itr]
890889
append_preload = [
891890
ROCPROF_TOOL_LIBRARY,
892-
ROCPROF_LIST_AVAIL_TOOL_LIBRARY,
893891
ROCPROF_SDK_LIBRARY,
894892
]
895893

@@ -1054,11 +1052,14 @@ def _write_env_value():
10541052
args.truncate_kernels,
10551053
overwrite_if_true=True,
10561054
)
1057-
update_env(
1058-
"ROCPROF_LIST_AVAIL",
1059-
args.list_avail,
1060-
overwrite_if_true=True,
1061-
)
1055+
1056+
if args.list_avail:
1057+
update_env(
1058+
"ROCPROF_LIST_AVAIL_TOOL_LIBRARY",
1059+
ROCPROF_LIST_AVAIL_TOOL_LIBRARY,
1060+
overwrite_if_true=True,
1061+
)
1062+
10621063
if args.collection_period:
10631064
factors = {
10641065
"hour": 60 * 60 * 1e9,
@@ -1136,11 +1137,11 @@ def log_config(_env):
11361137
update_env("ROCPROFILER_PC_SAMPLING_BETA_ENABLED", "on")
11371138
path = os.path.join(f"{ROCM_DIR}", "bin/rocprofv3_avail")
11381139
if app_args:
1139-
exit_code = subprocess.check_call(["python3", path], env=app_env)
1140+
exit_code = subprocess.check_call([sys.executable, path], env=app_env)
11401141
else:
1141-
app_args = ["python3", path]
1142+
app_args = [sys.executable, path]
11421143

1143-
elif not app_args:
1144+
elif not app_args and not args.echo:
11441145
log_config(app_env)
11451146
fatal_error("No application provided")
11461147

@@ -1169,11 +1170,6 @@ def log_config(_env):
11691170
update_env(
11701171
"ROCPROF_COUNTERS", "pmc: {}".format(" ".join(args.pmc)), overwrite=True
11711172
)
1172-
else:
1173-
update_env("ROCPROF_COUNTER_COLLECTION", False, overwrite=True)
1174-
1175-
if args.log_level in ("info", "trace", "env"):
1176-
log_config(app_env)
11771173

11781174
if args.pc_sampling_unit or args.pc_sampling_method or args.pc_sampling_interval:
11791175

@@ -1256,17 +1252,10 @@ def int_auto(num_str):
12561252
args.att_serialize_all,
12571253
overwrite=True,
12581254
)
1259-
12601255
if args.att_library_path:
1261-
12621256
update_env(
12631257
"ROCPROF_ATT_LIBRARY_PATH",
1264-
args.att_library_path,
1265-
overwrite=True,
1266-
)
1267-
update_env(
1268-
"ATT_LIBRARY_PATH",
1269-
args.att_library_path,
1258+
":".join(args.att_library_path),
12701259
overwrite=True,
12711260
)
12721261
if args.att_percounters:
@@ -1276,10 +1265,23 @@ def int_auto(num_str):
12761265
overwrite=True,
12771266
)
12781267

1268+
if args.log_level in ("info", "trace", "env"):
1269+
log_config(app_env)
1270+
12791271
if use_execv:
1280-
# does not return
1281-
os.execvpe(app_args[0], app_args, env=app_env)
1272+
if args.echo:
1273+
sys.stderr.flush()
1274+
print(f"command: {app_args}")
1275+
sys.stdout.flush()
1276+
else:
1277+
# does not return
1278+
os.execvpe(app_args[0], app_args, env=app_env)
12821279
else:
1280+
if args.echo:
1281+
sys.stderr.flush()
1282+
print(f"command: {app_args}")
1283+
sys.stdout.flush()
1284+
return 0
12831285
try:
12841286
exit_code = subprocess.check_call(app_args, env=app_env)
12851287
if exit_code != 0:

projects/rocprofiler-sdk/source/lib/output/output_config.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,13 @@ output_config::save(ArchiveT& ar) const
121121
CFG_SERIALIZE_NAMED_MEMBER("summary_unit", stats_summary_unit);
122122
CFG_SERIALIZE_NAMED_MEMBER("summary_file", stats_summary_file);
123123

124+
CFG_SERIALIZE_MEMBER(csv_output);
125+
CFG_SERIALIZE_MEMBER(json_output);
126+
CFG_SERIALIZE_MEMBER(pftrace_output);
127+
CFG_SERIALIZE_MEMBER(otf2_output);
128+
CFG_SERIALIZE_MEMBER(summary_output);
129+
CFG_SERIALIZE_MEMBER(kernel_rename);
130+
124131
#undef CFG_SERIALIZE_MEMBER
125132
#undef CFG_SERIALIZE_NAMED_MEMBER
126133
}

0 commit comments

Comments
 (0)