@@ -107,16 +107,21 @@ def search_path(path_list):
107107
108108def 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
180161class 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
657654def 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 :
0 commit comments