@@ -616,7 +616,7 @@ def access(self, i, out = None):
616
616
if automation == '' :
617
617
return {'return' :4 , 'error' :'automation was not specified' }
618
618
else :
619
- return {'return' :4 , 'error' :'automation {} not found' .format (automation )}
619
+ return {'return' :4 , 'error' :'automation "{}" not found' .format (automation )}
620
620
621
621
# If no automation was found or we force common automation
622
622
if use_common_automation or len (automation_lst )== 0 :
@@ -842,19 +842,30 @@ def x(self, i, out = None):
842
842
'h' , 'help' , 'version' , 'out' , 'j' , 'json' ,
843
843
'save_to_json_file' , 'save_to_yaml_file' , 'common' ,
844
844
'ignore_inheritance' , 'log' , 'logfile' , 'raise' , 'repro' ,
845
- 'f' ]]
845
+ 'f' , 'time' , 'profile' ]]
846
846
847
+ delayed_error = ''
848
+
847
849
if len (unknown_control_flags )> 0 :
848
850
unknown_control_flags_str = ',' .join (unknown_control_flags )
849
851
850
- print ( f'Unknown control flag(s): { unknown_control_flags_str } ' )
851
- print ( '' )
852
+ delayed_error = f'Unknown control flag(s): { unknown_control_flags_str } '
853
+
852
854
# Force print help
853
855
control ['h' ] = True
854
856
855
857
if control .pop ('f' , '' ):
856
858
i ['f' ] = True
857
859
860
+ output_json = (control .get ('j' , False ) or control .get ('json' , False ))
861
+
862
+ self_time = control .get ('time' , False )
863
+ if not x_was_called and self_time :
864
+ import time
865
+ self_time1 = time .time ()
866
+
867
+ self_profile = control .get ('profile' , False )
868
+
858
869
# Check repro
859
870
use_log = str (control_flags .pop ('log' , '' )).strip ().lower ()
860
871
log_file = control_flags .pop ('logfile' , '' )
@@ -928,18 +939,48 @@ def x(self, i, out = None):
928
939
self .log (f"x input: { spaces } ({ i } )" , "debug" )
929
940
930
941
# Call access helper
942
+ if not x_was_called and self_profile :
943
+ # https://docs.python.org/3/library/profile.html#module-cProfile
944
+ import cProfile , pstats , io
945
+ from pstats import SortKey
946
+ profile = cProfile .Profile ()
947
+ profile .enable ()
948
+
931
949
r = self ._x (i , control )
932
-
950
+
951
+ if delayed_error != '' and r ['return' ] == 0 :
952
+ r ['return' ] = 1
953
+ r ['error' ] = delayed_error
954
+
933
955
if not self .logger == None :
934
956
self .log (f"x output: { r } " , "debug" )
935
957
936
958
self .state ['recursion' ] = recursion
937
959
938
960
if not x_was_called :
961
+ if self_profile :
962
+ profile .disable ()
963
+ s = io .StringIO ()
964
+ sortby = SortKey .CUMULATIVE
965
+ ps = pstats .Stats (profile , stream = s ).sort_stats (sortby )
966
+ ps .print_stats (32 )
967
+ print ('' )
968
+ print ('CMX profile:' )
969
+ print ('' )
970
+ print (s .getvalue ())
971
+
939
972
# Very first call (not recursive)
940
973
# Check if output to json and save file
941
974
942
- if self .output == 'json' :
975
+ if self_time :
976
+ self_time = time .time () - self_time1
977
+ r ['self_time' ] = self_time
978
+
979
+ if self .output == 'con' :
980
+ print ('' )
981
+ print ('CMX elapsed time: {:.3f} sec.' .format (self_time ))
982
+
983
+ if output_json :
943
984
utils .dump_safe_json (r )
944
985
945
986
# Restore directory of call
@@ -975,9 +1016,10 @@ def _x(self, i, control):
975
1016
if output == True :
976
1017
output = 'con'
977
1018
978
- # Check and force json console output
979
- if control .get ('j' , False ) or control .get ('json' , False ):
980
- output = 'json'
1019
+ # Changed in v3.2.5
1020
+ # # Check and force json console output
1021
+ # if control.get('j', False) or control.get('json', False):
1022
+ # output = 'json'
981
1023
982
1024
# Set self.output to the output of the very first access
983
1025
# to print error in the end if needed
@@ -1011,6 +1053,17 @@ def _x(self, i, control):
1011
1053
elif action == 'init' and automation == '' :
1012
1054
automation = 'core'
1013
1055
1056
+ # Can add popular shortcuts
1057
+ elif action == 'ff' :
1058
+ task = ''
1059
+ if automation != '' and (' ' in automation or ',' in automation ):
1060
+ task = automation
1061
+ if ' ' in automation : task = automation .replace (' ' ,',' )
1062
+ i ['task' ] = task
1063
+ automation = 'flex.flow'
1064
+ action = 'run'
1065
+ i ['automation' ] = automation
1066
+ i ['action' ] = action
1014
1067
1015
1068
# Print basic help if action == ''
1016
1069
extra_help = True if action == 'help' and automation == '' else False
@@ -1038,6 +1091,8 @@ def _x(self, i, control):
1038
1091
print (' -log={info (default) | debug | warning | error} - log level' )
1039
1092
print (' -logfile={path to log file} - record log to file instead of console' )
1040
1093
print (' -raise - raise Python error when automation action fails' )
1094
+ print (' -time - print elapsed time for a given automation' )
1095
+ print (' -profile - profile a given automation' )
1041
1096
print (' -repro - record various info to the cmx-repro directory to replay CMX command' )
1042
1097
print ('' )
1043
1098
print ('Check https://github.com/mlcommons/ck/tree/master/cm/docs/cmx for more details.' )
@@ -1211,7 +1266,7 @@ def _x(self, i, control):
1211
1266
return {'return' :4 , 'error' :'automation meta not found in {}' .format (automation_path )}
1212
1267
1213
1268
# Load artifact class
1214
- r = utils .load_yaml_and_json (automation_path_meta )
1269
+ r = utils .load_yaml_and_json (automation_path_meta )
1215
1270
if r ['return' ]> 0 : return r
1216
1271
1217
1272
automation_meta = r ['meta' ]
@@ -1250,7 +1305,7 @@ def _x(self, i, control):
1250
1305
if automation == '' :
1251
1306
return {'return' :4 , 'error' :'automation was not specified' }
1252
1307
else :
1253
- return {'return' :4 , 'error' :f'automation { automation } not found' }
1308
+ return {'return' :4 , 'error' :f'automation " { automation } " not found' }
1254
1309
1255
1310
# If no automation was found or we force common automation
1256
1311
loaded_common_automation = False
0 commit comments