6868 "iphone" : "ip" ,
6969 "xnnpackq8" : "xnnq8" ,
7070}
71+
72+
7173def abbreviate (s ):
7274 for full , abbr in ABBREVIATIONS .items ():
7375 s = s .replace (full , abbr )
@@ -125,14 +127,14 @@ def argparser():
125127 )
126128 parser .add_argument (
127129 "--outputType" ,
128- choices = ["json" , "excel" , "df" ],
130+ choices = ["json" , "excel" , "df" , "csv" ],
129131 default = "print" ,
130132 help = "Choose output type for your run" ,
131133 )
132134 parser .add_argument (
133135 "--outputDir" ,
134136 default = "." ,
135- help = "Only used when output-type is excel, default to current directory" ,
137+ help = "Only used when output-type is excel and csv , default to current directory" ,
136138 )
137139
138140 return parser .parse_args ()
@@ -252,7 +254,7 @@ def to_excel(self, output_dir: str = ".") -> None:
252254 - res_private.xlsx: Results for private devices
253255 - res_public.xlsx: Results for public devices
254256
255- Each file contains multiple sheets, one per benchmark configuration.
257+ Each file contains multiple sheets, one per benchmark configuration for private and public .
256258
257259 Args:
258260 output_dir: Directory to save Excel files
@@ -299,6 +301,66 @@ def _write_multi_sheet_excel(
299301 df = pd .DataFrame (rows )
300302 df .to_excel (writer , sheet_name = sheet_name or "Sheet" , index = False )
301303
304+ def to_csv (self , output_dir : str = "." ) -> None :
305+ """
306+ Export benchmark results to CSV files.
307+
308+ Creates two CSV files:
309+ - res_private.csv: Results for private devices
310+ - res_public.csv: Results for public devices
311+
312+ Each file contains multiple CSV files, one per benchmark configuration for private and public.
313+
314+ Args:
315+ output_dir: Directory to save CSV files
316+ """
317+ if not os .path .exists (output_dir ):
318+ os .makedirs (output_dir )
319+ logging .info (f"Created output directory: { output_dir } " )
320+ else :
321+ logging .info (f"Using existing output directory: { output_dir } " )
322+ private_path = os .path .join (output_dir , "private/" )
323+ public_path = os .path .join (output_dir , "public" )
324+ self ._write_multiple_csv_files (
325+ self .results_private , private_path , file_prefix = "private_"
326+ )
327+ self ._write_multiple_csv_files (
328+ self .results_public , public_path , file_prefix = "public_"
329+ )
330+
331+ def _write_multiple_csv_files (
332+ self , data_list : List [Dict [str , Any ]], output_dir : str , file_prefix = ""
333+ ) -> None :
334+ """
335+ Write multiple benchmark results to separate CSV files.
336+
337+ Each entry in `data_list` becomes its own CSV file.
338+
339+ Args:
340+ data_list: List of benchmark result dictionaries
341+ output_dir: Directory to save the CSV files
342+ """
343+ os .makedirs (output_dir , exist_ok = True )
344+ logging .info (
345+ f"\n ========= Generating multiple CSV files in { output_dir } ========= \n "
346+ )
347+ for idx , entry in enumerate (data_list ):
348+ file_name = entry .get ("short_name" , f"file{ idx + 1 } " )
349+
350+ if file_prefix :
351+ file_name = file_prefix + file_name
352+ if len (file_name ) > 100 :
353+ logging .warning (
354+ f"File name '{ file_name } ' is too long, truncating to 100 characters"
355+ )
356+ file_name = file_name [:100 ]
357+ file_path = os .path .join (output_dir , f"{ file_name } .csv" )
358+
359+ rows = entry .get ("rows" , [])
360+ logging .info (f"Writing CSV: { file_path } with { len (rows )} rows" )
361+ df = pd .DataFrame (rows )
362+ df .to_csv (file_path , index = False )
363+
302364 def _fetch_data (
303365 self , start_time : str , end_time : str
304366 ) -> Optional [List [Dict [str , Any ]]]:
@@ -367,8 +429,10 @@ def print_all_names(self) -> None:
367429 for name in private_ones :
368430 logging .info (name )
369431
370- def _generate_table_name (self , group_info :dict , fields : list [str ]) -> str :
371- name = "|" .join (group_info [k ] for k in fields if k in group_info and group_info [k ])
432+ def _generate_table_name (self , group_info : dict , fields : list [str ]) -> str :
433+ name = "|" .join (
434+ group_info [k ] for k in fields if k in group_info and group_info [k ]
435+ )
372436 return self .normalize_string (name )
373437
374438 def _process (self , data : List [Dict [str , Any ]]) -> List [Dict [str , Any ]]:
@@ -405,7 +469,7 @@ def _process(self, data: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
405469 item ["groupInfo" ]["aws_type" ] = "private"
406470 else :
407471 item ["groupInfo" ]["aws_type" ] = "public"
408-
472+
409473 data .sort (key = lambda x : x ["table_name" ])
410474 logging .info (f"fetched { len (data )} table views" )
411475 return data
@@ -429,16 +493,18 @@ def _fetch_execu_torch_data(self, start_time, end_time):
429493 logging .info (response .text )
430494 return None
431495
432- def generate_short_name (self , words , size ):
496+ def generate_short_name (self , words , size , enable_abbreviation = True ):
433497 shortKeys = [k .replace ("_" , "" ) for k in words ]
434498 s = "_" .join (shortKeys )
435499 if size > 0 :
436500 logging .warning (
437501 f"we found more than one table matches the keywords, adding size to distinguish: { s } "
438502 )
439503 s += s + "_" + str (size )
440- for full , abbr in ABBREVIATIONS .items ():
441- s = s .replace (full , abbr )
504+
505+ if enable_abbreviation :
506+ for full , abbr in ABBREVIATIONS .items ():
507+ s = s .replace (full , abbr )
442508 return s
443509
444510 def find_target_tables (self , keywords , is_private ) -> List [Any ]:
@@ -459,7 +525,7 @@ def find_target_tables(self, keywords, is_private) -> List[Any]:
459525 item .get ("groupInfo" , {}).get ("aws_type" , "" ) == "private"
460526 )
461527 if is_private is not is_item_private :
462- continue # skip if not matching private/public device
528+ continue # skip if not matching private/public device
463529
464530 # generate short name for each table data
465531 item ["short_name" ] = self .generate_short_name (
@@ -508,9 +574,14 @@ def normalize_string(self, s, replace="_"):
508574 logging .info ("\n " )
509575 elif args .outputType == "excel" :
510576 logging .info (
511- f"Writing benchmark results to excel file: { args .outputDir } /res_private.xlsx "
577+ f"Writing benchmark results to excel file as sheets: res_private.xlsx & res_public.xlsx under { args .outputDir } "
512578 )
513579 fetcher .to_excel (args .outputDir )
580+ elif args .outputType == "csv" :
581+ logging .info (
582+ f"Writing benchmark results to csv files under folders private/ & public/ under { args .outputDir } "
583+ )
584+ fetcher .to_csv (args .outputDir )
514585 else :
515586 logging .info (
516587 f"======================Printing private device benchmark results in json format======================"
0 commit comments