1*da0073e9SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*da0073e9SAndroid Build Coastguard Worker 3*da0073e9SAndroid Build Coastguard Worker""" 4*da0073e9SAndroid Build Coastguard WorkerA wrapper over the benchmark infrastructure to generate commonly used commands, 5*da0073e9SAndroid Build Coastguard Workerparse results and generate csv/graphs. 6*da0073e9SAndroid Build Coastguard Worker 7*da0073e9SAndroid Build Coastguard WorkerThe script works on manually written TABLE (see below). We can add more commands 8*da0073e9SAndroid Build Coastguard Workerin the future. 9*da0073e9SAndroid Build Coastguard Worker 10*da0073e9SAndroid Build Coastguard WorkerOne example usage is 11*da0073e9SAndroid Build Coastguard Worker-> python benchmarks/runner.py --suites=torchbench --inference 12*da0073e9SAndroid Build Coastguard WorkerThis command will generate the commands for the default compilers (see DEFAULTS 13*da0073e9SAndroid Build Coastguard Workerbelow) for inference, run them and visualize the logs. 14*da0073e9SAndroid Build Coastguard Worker 15*da0073e9SAndroid Build Coastguard WorkerIf you want to just print the commands, you could use the following command 16*da0073e9SAndroid Build Coastguard Worker-> python benchmarks/runner.py --print-run-commands --suites=torchbench --inference 17*da0073e9SAndroid Build Coastguard Worker 18*da0073e9SAndroid Build Coastguard WorkerSimilarly, if you want to just visualize the already finished logs 19*da0073e9SAndroid Build Coastguard Worker-> python benchmarks/runner.py --visualize-logs --suites=torchbench --inference 20*da0073e9SAndroid Build Coastguard Worker 21*da0073e9SAndroid Build Coastguard WorkerIf you want to test float16 22*da0073e9SAndroid Build Coastguard Worker-> python benchmarks/runner.py --suites=torchbench --inference --dtypes=float16 23*da0073e9SAndroid Build Coastguard Worker 24*da0073e9SAndroid Build Coastguard Worker""" 25*da0073e9SAndroid Build Coastguard Worker 26*da0073e9SAndroid Build Coastguard Workerimport argparse 27*da0073e9SAndroid Build Coastguard Workerimport dataclasses 28*da0073e9SAndroid Build Coastguard Workerimport functools 29*da0073e9SAndroid Build Coastguard Workerimport glob 30*da0073e9SAndroid Build Coastguard Workerimport importlib 31*da0073e9SAndroid Build Coastguard Workerimport io 32*da0073e9SAndroid Build Coastguard Workerimport itertools 33*da0073e9SAndroid Build Coastguard Workerimport logging 34*da0073e9SAndroid Build Coastguard Workerimport os 35*da0073e9SAndroid Build Coastguard Workerimport re 36*da0073e9SAndroid Build Coastguard Workerimport shutil 37*da0073e9SAndroid Build Coastguard Workerimport subprocess 38*da0073e9SAndroid Build Coastguard Workerimport sys 39*da0073e9SAndroid Build Coastguard Workerimport tempfile 40*da0073e9SAndroid Build Coastguard Workerfrom collections import defaultdict 41*da0073e9SAndroid Build Coastguard Workerfrom datetime import datetime, timedelta, timezone 42*da0073e9SAndroid Build Coastguard Workerfrom os.path import abspath, exists 43*da0073e9SAndroid Build Coastguard Workerfrom random import randint 44*da0073e9SAndroid Build Coastguard Worker 45*da0073e9SAndroid Build Coastguard Workerimport matplotlib.pyplot as plt 46*da0073e9SAndroid Build Coastguard Workerimport numpy as np 47*da0073e9SAndroid Build Coastguard Workerimport pandas as pd 48*da0073e9SAndroid Build Coastguard Workerfrom matplotlib import rcParams 49*da0073e9SAndroid Build Coastguard Workerfrom scipy.stats import gmean 50*da0073e9SAndroid Build Coastguard Workerfrom tabulate import tabulate 51*da0073e9SAndroid Build Coastguard Worker 52*da0073e9SAndroid Build Coastguard Workerimport torch 53*da0073e9SAndroid Build Coastguard Workerimport torch._dynamo 54*da0073e9SAndroid Build Coastguard Worker 55*da0073e9SAndroid Build Coastguard Worker 56*da0073e9SAndroid Build Coastguard WorkerrcParams.update({"figure.autolayout": True}) 57*da0073e9SAndroid Build Coastguard Workerplt.rc("axes", axisbelow=True) 58*da0073e9SAndroid Build Coastguard Worker 59*da0073e9SAndroid Build Coastguard WorkerDEFAULT_OUTPUT_DIR = "benchmark_logs" 60*da0073e9SAndroid Build Coastguard Worker 61*da0073e9SAndroid Build Coastguard Worker 62*da0073e9SAndroid Build Coastguard Workerlog = logging.getLogger(__name__) 63*da0073e9SAndroid Build Coastguard Worker 64*da0073e9SAndroid Build Coastguard WorkerTABLE = { 65*da0073e9SAndroid Build Coastguard Worker "training": { 66*da0073e9SAndroid Build Coastguard Worker "ts_nnc": "--training --speedup-ts ", 67*da0073e9SAndroid Build Coastguard Worker "ts_nvfuser": "--training --nvfuser --speedup-dynamo-ts ", 68*da0073e9SAndroid Build Coastguard Worker "eager": "--training --backend=eager ", 69*da0073e9SAndroid Build Coastguard Worker "aot_eager": "--training --backend=aot_eager ", 70*da0073e9SAndroid Build Coastguard Worker "cudagraphs": "--training --backend=cudagraphs ", 71*da0073e9SAndroid Build Coastguard Worker "aot_nvfuser": "--training --nvfuser --backend=aot_ts_nvfuser ", 72*da0073e9SAndroid Build Coastguard Worker "nvprims_nvfuser": "--training --backend=nvprims_nvfuser ", 73*da0073e9SAndroid Build Coastguard Worker "inductor": "--training --inductor ", 74*da0073e9SAndroid Build Coastguard Worker "inductor_no_cudagraphs": "--training --inductor --disable-cudagraphs ", 75*da0073e9SAndroid Build Coastguard Worker "inductor_max_autotune": "--training --inductor --inductor-compile-mode max-autotune ", 76*da0073e9SAndroid Build Coastguard Worker "inductor_max_autotune_no_cudagraphs": ( 77*da0073e9SAndroid Build Coastguard Worker "--training --inductor --inductor-compile-mode max-autotune-no-cudagraphs --disable-cudagraphs " 78*da0073e9SAndroid Build Coastguard Worker ), 79*da0073e9SAndroid Build Coastguard Worker }, 80*da0073e9SAndroid Build Coastguard Worker "inference": { 81*da0073e9SAndroid Build Coastguard Worker "aot_eager": "--inference --backend=aot_eager ", 82*da0073e9SAndroid Build Coastguard Worker "eager": "--inference --backend=eager ", 83*da0073e9SAndroid Build Coastguard Worker "ts_nnc": "--inference --speedup-ts ", 84*da0073e9SAndroid Build Coastguard Worker "ts_nvfuser": "--inference -n100 --speedup-ts --nvfuser ", 85*da0073e9SAndroid Build Coastguard Worker "trt": "--inference -n100 --speedup-trt ", 86*da0073e9SAndroid Build Coastguard Worker "ts_nvfuser_cudagraphs": "--inference --backend=cudagraphs_ts ", 87*da0073e9SAndroid Build Coastguard Worker "inductor": "--inference -n50 --inductor ", 88*da0073e9SAndroid Build Coastguard Worker "inductor_no_cudagraphs": "--inference -n50 --inductor --disable-cudagraphs ", 89*da0073e9SAndroid Build Coastguard Worker "inductor_max_autotune": "--inference -n50 --inductor --inductor-compile-mode max-autotune ", 90*da0073e9SAndroid Build Coastguard Worker "inductor_max_autotune_no_cudagraphs": ( 91*da0073e9SAndroid Build Coastguard Worker "--inference -n50 --inductor --inductor-compile-mode max-autotune-no-cudagraphs --disable-cudagraphs " 92*da0073e9SAndroid Build Coastguard Worker ), 93*da0073e9SAndroid Build Coastguard Worker "torchscript-onnx": "--inference -n5 --torchscript-onnx", 94*da0073e9SAndroid Build Coastguard Worker "dynamo-onnx": "--inference -n5 --dynamo-onnx", 95*da0073e9SAndroid Build Coastguard Worker }, 96*da0073e9SAndroid Build Coastguard Worker} 97*da0073e9SAndroid Build Coastguard Worker 98*da0073e9SAndroid Build Coastguard WorkerINFERENCE_COMPILERS = tuple(TABLE["inference"].keys()) 99*da0073e9SAndroid Build Coastguard WorkerTRAINING_COMPILERS = tuple(TABLE["training"].keys()) 100*da0073e9SAndroid Build Coastguard Worker 101*da0073e9SAndroid Build Coastguard WorkerDEFAULTS = { 102*da0073e9SAndroid Build Coastguard Worker "training": [ 103*da0073e9SAndroid Build Coastguard Worker "eager", 104*da0073e9SAndroid Build Coastguard Worker "aot_eager", 105*da0073e9SAndroid Build Coastguard Worker "inductor", 106*da0073e9SAndroid Build Coastguard Worker "inductor_no_cudagraphs", 107*da0073e9SAndroid Build Coastguard Worker ], 108*da0073e9SAndroid Build Coastguard Worker "inference": [ 109*da0073e9SAndroid Build Coastguard Worker "eager", 110*da0073e9SAndroid Build Coastguard Worker "aot_eager", 111*da0073e9SAndroid Build Coastguard Worker "inductor", 112*da0073e9SAndroid Build Coastguard Worker "inductor_no_cudagraphs", 113*da0073e9SAndroid Build Coastguard Worker ], 114*da0073e9SAndroid Build Coastguard Worker "flag_compilers": { 115*da0073e9SAndroid Build Coastguard Worker "training": ["inductor", "inductor_no_cudagraphs"], 116*da0073e9SAndroid Build Coastguard Worker "inference": ["inductor", "inductor_no_cudagraphs"], 117*da0073e9SAndroid Build Coastguard Worker }, 118*da0073e9SAndroid Build Coastguard Worker "dtypes": [ 119*da0073e9SAndroid Build Coastguard Worker "float32", 120*da0073e9SAndroid Build Coastguard Worker ], 121*da0073e9SAndroid Build Coastguard Worker "suites": ["torchbench", "huggingface", "timm_models"], 122*da0073e9SAndroid Build Coastguard Worker "devices": [ 123*da0073e9SAndroid Build Coastguard Worker "cuda", 124*da0073e9SAndroid Build Coastguard Worker ], 125*da0073e9SAndroid Build Coastguard Worker "quick": { 126*da0073e9SAndroid Build Coastguard Worker "torchbench": '-k "resnet..$"', 127*da0073e9SAndroid Build Coastguard Worker "huggingface": "-k Albert", 128*da0073e9SAndroid Build Coastguard Worker "timm_models": ' -k "^resnet" -k "^inception"', 129*da0073e9SAndroid Build Coastguard Worker }, 130*da0073e9SAndroid Build Coastguard Worker} 131*da0073e9SAndroid Build Coastguard Worker 132*da0073e9SAndroid Build Coastguard Worker 133*da0073e9SAndroid Build Coastguard WorkerDASHBOARD_DEFAULTS = { 134*da0073e9SAndroid Build Coastguard Worker "dashboard_image_uploader": "/fsx/users/anijain/bin/imgur.sh", 135*da0073e9SAndroid Build Coastguard Worker "dashboard_archive_path": "/data/home/anijain/cluster/cron_logs", 136*da0073e9SAndroid Build Coastguard Worker "dashboard_gh_cli_path": "/data/home/anijain/miniconda/bin/gh", 137*da0073e9SAndroid Build Coastguard Worker} 138*da0073e9SAndroid Build Coastguard Worker 139*da0073e9SAndroid Build Coastguard Worker 140*da0073e9SAndroid Build Coastguard Workerdef flag_speedup(x): 141*da0073e9SAndroid Build Coastguard Worker return x < 0.95 142*da0073e9SAndroid Build Coastguard Worker 143*da0073e9SAndroid Build Coastguard Worker 144*da0073e9SAndroid Build Coastguard Workerdef flag_compilation_latency(x): 145*da0073e9SAndroid Build Coastguard Worker return x > 120 146*da0073e9SAndroid Build Coastguard Worker 147*da0073e9SAndroid Build Coastguard Worker 148*da0073e9SAndroid Build Coastguard Workerdef flag_compression_ratio(x): 149*da0073e9SAndroid Build Coastguard Worker return x < 0.9 150*da0073e9SAndroid Build Coastguard Worker 151*da0073e9SAndroid Build Coastguard Worker 152*da0073e9SAndroid Build Coastguard Workerdef flag_accuracy(x): 153*da0073e9SAndroid Build Coastguard Worker return "pass" not in x 154*da0073e9SAndroid Build Coastguard Worker 155*da0073e9SAndroid Build Coastguard Worker 156*da0073e9SAndroid Build Coastguard WorkerFLAG_FNS = { 157*da0073e9SAndroid Build Coastguard Worker "speedup": flag_speedup, 158*da0073e9SAndroid Build Coastguard Worker "compilation_latency": flag_compilation_latency, 159*da0073e9SAndroid Build Coastguard Worker "compression_ratio": flag_compression_ratio, 160*da0073e9SAndroid Build Coastguard Worker "accuracy": flag_accuracy, 161*da0073e9SAndroid Build Coastguard Worker} 162*da0073e9SAndroid Build Coastguard Worker 163*da0073e9SAndroid Build Coastguard Worker 164*da0073e9SAndroid Build Coastguard Workerdef percentage(part, whole, decimals=2): 165*da0073e9SAndroid Build Coastguard Worker if whole == 0: 166*da0073e9SAndroid Build Coastguard Worker return 0 167*da0073e9SAndroid Build Coastguard Worker return round(100 * float(part) / float(whole), decimals) 168*da0073e9SAndroid Build Coastguard Worker 169*da0073e9SAndroid Build Coastguard Worker 170*da0073e9SAndroid Build Coastguard Workerdef parse_args(): 171*da0073e9SAndroid Build Coastguard Worker parser = argparse.ArgumentParser() 172*da0073e9SAndroid Build Coastguard Worker parser.add_argument("--devices", action="append", help="cpu or cuda") 173*da0073e9SAndroid Build Coastguard Worker parser.add_argument("--dtypes", action="append", help="float16/float32/amp") 174*da0073e9SAndroid Build Coastguard Worker parser.add_argument("--suites", action="append", help="huggingface/torchbench/timm") 175*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 176*da0073e9SAndroid Build Coastguard Worker "--compilers", 177*da0073e9SAndroid Build Coastguard Worker action="append", 178*da0073e9SAndroid Build Coastguard Worker help=f"For --inference, options are {INFERENCE_COMPILERS}. For --training, options are {TRAINING_COMPILERS}", 179*da0073e9SAndroid Build Coastguard Worker ) 180*da0073e9SAndroid Build Coastguard Worker 181*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 182*da0073e9SAndroid Build Coastguard Worker "--flag-compilers", 183*da0073e9SAndroid Build Coastguard Worker action="append", 184*da0073e9SAndroid Build Coastguard Worker help="List of compilers to flag issues. Same format as --compilers.", 185*da0073e9SAndroid Build Coastguard Worker ) 186*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 187*da0073e9SAndroid Build Coastguard Worker "--quick", action="store_true", help="Just runs one model. Helps in debugging" 188*da0073e9SAndroid Build Coastguard Worker ) 189*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 190*da0073e9SAndroid Build Coastguard Worker "--output-dir", 191*da0073e9SAndroid Build Coastguard Worker help="Choose the output directory to save the logs", 192*da0073e9SAndroid Build Coastguard Worker default=DEFAULT_OUTPUT_DIR, 193*da0073e9SAndroid Build Coastguard Worker ) 194*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 195*da0073e9SAndroid Build Coastguard Worker "--keep-output-dir", 196*da0073e9SAndroid Build Coastguard Worker action="store_true", 197*da0073e9SAndroid Build Coastguard Worker help="Do not cleanup the output directory before running", 198*da0073e9SAndroid Build Coastguard Worker ) 199*da0073e9SAndroid Build Coastguard Worker 200*da0073e9SAndroid Build Coastguard Worker # Choose either generation of commands, pretty parsing or e2e runs 201*da0073e9SAndroid Build Coastguard Worker group = parser.add_mutually_exclusive_group(required=False) 202*da0073e9SAndroid Build Coastguard Worker group.add_argument( 203*da0073e9SAndroid Build Coastguard Worker "--print-run-commands", 204*da0073e9SAndroid Build Coastguard Worker "--print_run_commands", 205*da0073e9SAndroid Build Coastguard Worker action="store_true", 206*da0073e9SAndroid Build Coastguard Worker help="Generate commands and saves them to run.sh", 207*da0073e9SAndroid Build Coastguard Worker ) 208*da0073e9SAndroid Build Coastguard Worker group.add_argument( 209*da0073e9SAndroid Build Coastguard Worker "--visualize-logs", 210*da0073e9SAndroid Build Coastguard Worker "--visualize_logs", 211*da0073e9SAndroid Build Coastguard Worker action="store_true", 212*da0073e9SAndroid Build Coastguard Worker help="Pretty print the log files and draw graphs", 213*da0073e9SAndroid Build Coastguard Worker ) 214*da0073e9SAndroid Build Coastguard Worker group.add_argument( 215*da0073e9SAndroid Build Coastguard Worker "--run", 216*da0073e9SAndroid Build Coastguard Worker action="store_true", 217*da0073e9SAndroid Build Coastguard Worker default=True, 218*da0073e9SAndroid Build Coastguard Worker help="Generate commands, run and parses the files", 219*da0073e9SAndroid Build Coastguard Worker ) 220*da0073e9SAndroid Build Coastguard Worker 221*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 222*da0073e9SAndroid Build Coastguard Worker "--log-operator-inputs", 223*da0073e9SAndroid Build Coastguard Worker action="store_true", 224*da0073e9SAndroid Build Coastguard Worker default=False, 225*da0073e9SAndroid Build Coastguard Worker help="Log operator inputs", 226*da0073e9SAndroid Build Coastguard Worker ) 227*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 228*da0073e9SAndroid Build Coastguard Worker "--include-slowdowns", 229*da0073e9SAndroid Build Coastguard Worker "--include_slowdowns", 230*da0073e9SAndroid Build Coastguard Worker action="store_true", 231*da0073e9SAndroid Build Coastguard Worker default=False, 232*da0073e9SAndroid Build Coastguard Worker help="Include slowdowns in geomean performance speedup report. By default, slowdowns are ignored. " 233*da0073e9SAndroid Build Coastguard Worker "This is because one can always use eager if compile is not speeding things up", 234*da0073e9SAndroid Build Coastguard Worker ) 235*da0073e9SAndroid Build Coastguard Worker 236*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 237*da0073e9SAndroid Build Coastguard Worker "--extra-args", default="", help="Append commandline with these args" 238*da0073e9SAndroid Build Coastguard Worker ) 239*da0073e9SAndroid Build Coastguard Worker 240*da0073e9SAndroid Build Coastguard Worker # Choose either inference or training 241*da0073e9SAndroid Build Coastguard Worker group_mode = parser.add_mutually_exclusive_group(required=True) 242*da0073e9SAndroid Build Coastguard Worker group_mode.add_argument( 243*da0073e9SAndroid Build Coastguard Worker "--inference", action="store_true", help="Only run inference related tasks" 244*da0073e9SAndroid Build Coastguard Worker ) 245*da0073e9SAndroid Build Coastguard Worker group_mode.add_argument( 246*da0073e9SAndroid Build Coastguard Worker "--training", action="store_true", help="Only run training related tasks" 247*da0073e9SAndroid Build Coastguard Worker ) 248*da0073e9SAndroid Build Coastguard Worker 249*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 250*da0073e9SAndroid Build Coastguard Worker "--base-sha", 251*da0073e9SAndroid Build Coastguard Worker help="commit id for the tested pytorch", 252*da0073e9SAndroid Build Coastguard Worker ) 253*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 254*da0073e9SAndroid Build Coastguard Worker "--total-partitions", 255*da0073e9SAndroid Build Coastguard Worker type=int, 256*da0073e9SAndroid Build Coastguard Worker help="Total number of partitions, to be passed to the actual benchmark script", 257*da0073e9SAndroid Build Coastguard Worker ) 258*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 259*da0073e9SAndroid Build Coastguard Worker "--partition-id", 260*da0073e9SAndroid Build Coastguard Worker type=int, 261*da0073e9SAndroid Build Coastguard Worker help="ID of partition, to be passed to the actual benchmark script", 262*da0073e9SAndroid Build Coastguard Worker ) 263*da0073e9SAndroid Build Coastguard Worker 264*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 265*da0073e9SAndroid Build Coastguard Worker "--update-dashboard", 266*da0073e9SAndroid Build Coastguard Worker action="store_true", 267*da0073e9SAndroid Build Coastguard Worker default=False, 268*da0073e9SAndroid Build Coastguard Worker help="Updates to dashboard", 269*da0073e9SAndroid Build Coastguard Worker ) 270*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 271*da0073e9SAndroid Build Coastguard Worker "--no-graphs", 272*da0073e9SAndroid Build Coastguard Worker action="store_true", 273*da0073e9SAndroid Build Coastguard Worker default=False, 274*da0073e9SAndroid Build Coastguard Worker help="Do not genenerate and upload metric graphs", 275*da0073e9SAndroid Build Coastguard Worker ) 276*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 277*da0073e9SAndroid Build Coastguard Worker "--no-update-archive", 278*da0073e9SAndroid Build Coastguard Worker action="store_true", 279*da0073e9SAndroid Build Coastguard Worker default=False, 280*da0073e9SAndroid Build Coastguard Worker help="Do not update lookup.csv or the log archive", 281*da0073e9SAndroid Build Coastguard Worker ) 282*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 283*da0073e9SAndroid Build Coastguard Worker "--no-gh-comment", 284*da0073e9SAndroid Build Coastguard Worker action="store_true", 285*da0073e9SAndroid Build Coastguard Worker default=False, 286*da0073e9SAndroid Build Coastguard Worker help="Do not write a comment to github", 287*da0073e9SAndroid Build Coastguard Worker ) 288*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 289*da0073e9SAndroid Build Coastguard Worker "--no-detect-regressions", 290*da0073e9SAndroid Build Coastguard Worker action="store_true", 291*da0073e9SAndroid Build Coastguard Worker default=False, 292*da0073e9SAndroid Build Coastguard Worker help="Do not compare to previous runs for regressions or metric graphs.", 293*da0073e9SAndroid Build Coastguard Worker ) 294*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 295*da0073e9SAndroid Build Coastguard Worker "--update-dashboard-test", 296*da0073e9SAndroid Build Coastguard Worker action="store_true", 297*da0073e9SAndroid Build Coastguard Worker default=False, 298*da0073e9SAndroid Build Coastguard Worker help="does all of --no-graphs, --no-update-archive, and --no-gh-comment", 299*da0073e9SAndroid Build Coastguard Worker ) 300*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 301*da0073e9SAndroid Build Coastguard Worker "--dashboard-image-uploader", 302*da0073e9SAndroid Build Coastguard Worker default=DASHBOARD_DEFAULTS["dashboard_image_uploader"], 303*da0073e9SAndroid Build Coastguard Worker help="Image uploader command", 304*da0073e9SAndroid Build Coastguard Worker ) 305*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 306*da0073e9SAndroid Build Coastguard Worker "--dashboard-archive-path", 307*da0073e9SAndroid Build Coastguard Worker default=DASHBOARD_DEFAULTS["dashboard_archive_path"], 308*da0073e9SAndroid Build Coastguard Worker help="Archived directory path", 309*da0073e9SAndroid Build Coastguard Worker ) 310*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 311*da0073e9SAndroid Build Coastguard Worker "--archive-name", 312*da0073e9SAndroid Build Coastguard Worker help="Directory name under dashboard-archive-path to copy output-dir to. " 313*da0073e9SAndroid Build Coastguard Worker "If not provided, a generated name is used.", 314*da0073e9SAndroid Build Coastguard Worker ) 315*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 316*da0073e9SAndroid Build Coastguard Worker "--dashboard-gh-cli-path", 317*da0073e9SAndroid Build Coastguard Worker default=DASHBOARD_DEFAULTS["dashboard_gh_cli_path"], 318*da0073e9SAndroid Build Coastguard Worker help="Github CLI path", 319*da0073e9SAndroid Build Coastguard Worker ) 320*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 321*da0073e9SAndroid Build Coastguard Worker "--batch-size", 322*da0073e9SAndroid Build Coastguard Worker "--batch_size", 323*da0073e9SAndroid Build Coastguard Worker type=int, 324*da0073e9SAndroid Build Coastguard Worker default=None, 325*da0073e9SAndroid Build Coastguard Worker help="batch size for benchmarking", 326*da0073e9SAndroid Build Coastguard Worker ) 327*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 328*da0073e9SAndroid Build Coastguard Worker "--threads", 329*da0073e9SAndroid Build Coastguard Worker "-t", 330*da0073e9SAndroid Build Coastguard Worker type=int, 331*da0073e9SAndroid Build Coastguard Worker default=None, 332*da0073e9SAndroid Build Coastguard Worker help="number of threads to use for eager and inductor.", 333*da0073e9SAndroid Build Coastguard Worker ) 334*da0073e9SAndroid Build Coastguard Worker launcher_group = parser.add_argument_group("CPU Launcher Parameters") 335*da0073e9SAndroid Build Coastguard Worker launcher_group.add_argument( 336*da0073e9SAndroid Build Coastguard Worker "--enable-cpu-launcher", 337*da0073e9SAndroid Build Coastguard Worker "--enable_cpu_launcher", 338*da0073e9SAndroid Build Coastguard Worker action="store_true", 339*da0073e9SAndroid Build Coastguard Worker default=False, 340*da0073e9SAndroid Build Coastguard Worker help="Use torch.backends.xeon.run_cpu to get the peak performance on Intel(R) Xeon(R) Scalable Processors.", 341*da0073e9SAndroid Build Coastguard Worker ) 342*da0073e9SAndroid Build Coastguard Worker launcher_group.add_argument( 343*da0073e9SAndroid Build Coastguard Worker "--cpu-launcher-args", 344*da0073e9SAndroid Build Coastguard Worker "--cpu_launcher_args", 345*da0073e9SAndroid Build Coastguard Worker type=str, 346*da0073e9SAndroid Build Coastguard Worker default="", 347*da0073e9SAndroid Build Coastguard Worker help="Provide the args of torch.backends.xeon.run_cpu. " 348*da0073e9SAndroid Build Coastguard Worker "To look up what optional arguments this launcher offers: python -m torch.backends.xeon.run_cpu --help", 349*da0073e9SAndroid Build Coastguard Worker ) 350*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 351*da0073e9SAndroid Build Coastguard Worker "--no-cold-start-latency", 352*da0073e9SAndroid Build Coastguard Worker action="store_true", 353*da0073e9SAndroid Build Coastguard Worker default=False, 354*da0073e9SAndroid Build Coastguard Worker help="Do not include --cold-start-latency on inductor benchmarks", 355*da0073e9SAndroid Build Coastguard Worker ) 356*da0073e9SAndroid Build Coastguard Worker parser.add_argument( 357*da0073e9SAndroid Build Coastguard Worker "--inductor-compile-mode", 358*da0073e9SAndroid Build Coastguard Worker default=None, 359*da0073e9SAndroid Build Coastguard Worker help="torch.compile mode argument for inductor runs.", 360*da0073e9SAndroid Build Coastguard Worker ) 361*da0073e9SAndroid Build Coastguard Worker args = parser.parse_args() 362*da0073e9SAndroid Build Coastguard Worker return args 363*da0073e9SAndroid Build Coastguard Worker 364*da0073e9SAndroid Build Coastguard Worker 365*da0073e9SAndroid Build Coastguard Workerdef get_mode(args): 366*da0073e9SAndroid Build Coastguard Worker if args.inference: 367*da0073e9SAndroid Build Coastguard Worker return "inference" 368*da0073e9SAndroid Build Coastguard Worker return "training" 369*da0073e9SAndroid Build Coastguard Worker 370*da0073e9SAndroid Build Coastguard Worker 371*da0073e9SAndroid Build Coastguard Workerdef get_skip_tests(suite, device, is_training: bool): 372*da0073e9SAndroid Build Coastguard Worker """ 373*da0073e9SAndroid Build Coastguard Worker Generate -x seperated string to skip the unusual setup training tests 374*da0073e9SAndroid Build Coastguard Worker """ 375*da0073e9SAndroid Build Coastguard Worker skip_tests = set() 376*da0073e9SAndroid Build Coastguard Worker original_dir = abspath(os.getcwd()) 377*da0073e9SAndroid Build Coastguard Worker module = importlib.import_module(suite) 378*da0073e9SAndroid Build Coastguard Worker os.chdir(original_dir) 379*da0073e9SAndroid Build Coastguard Worker 380*da0073e9SAndroid Build Coastguard Worker if suite == "torchbench": 381*da0073e9SAndroid Build Coastguard Worker skip_tests.update(module.TorchBenchmarkRunner().skip_models) 382*da0073e9SAndroid Build Coastguard Worker if is_training: 383*da0073e9SAndroid Build Coastguard Worker skip_tests.update( 384*da0073e9SAndroid Build Coastguard Worker module.TorchBenchmarkRunner().skip_not_suitable_for_training_models 385*da0073e9SAndroid Build Coastguard Worker ) 386*da0073e9SAndroid Build Coastguard Worker if device == "cpu": 387*da0073e9SAndroid Build Coastguard Worker skip_tests.update(module.TorchBenchmarkRunner().skip_models_for_cpu) 388*da0073e9SAndroid Build Coastguard Worker elif device == "cuda": 389*da0073e9SAndroid Build Coastguard Worker skip_tests.update(module.TorchBenchmarkRunner().skip_models_for_cuda) 390*da0073e9SAndroid Build Coastguard Worker 391*da0073e9SAndroid Build Coastguard Worker skip_tests = (f"-x {name}" for name in skip_tests) 392*da0073e9SAndroid Build Coastguard Worker skip_str = " ".join(skip_tests) 393*da0073e9SAndroid Build Coastguard Worker return skip_str 394*da0073e9SAndroid Build Coastguard Worker 395*da0073e9SAndroid Build Coastguard Worker 396*da0073e9SAndroid Build Coastguard Workerdef generate_csv_name(args, dtype, suite, device, compiler, testing): 397*da0073e9SAndroid Build Coastguard Worker mode = get_mode(args) 398*da0073e9SAndroid Build Coastguard Worker return f"{compiler}_{suite}_{dtype}_{mode}_{device}_{testing}.csv" 399*da0073e9SAndroid Build Coastguard Worker 400*da0073e9SAndroid Build Coastguard Worker 401*da0073e9SAndroid Build Coastguard Workerdef generate_commands(args, dtypes, suites, devices, compilers, output_dir): 402*da0073e9SAndroid Build Coastguard Worker mode = get_mode(args) 403*da0073e9SAndroid Build Coastguard Worker suites_str = "_".join(suites) 404*da0073e9SAndroid Build Coastguard Worker devices_str = "_".join(devices) 405*da0073e9SAndroid Build Coastguard Worker dtypes_str = "_".join(dtypes) 406*da0073e9SAndroid Build Coastguard Worker compilers_str = "_".join(compilers) 407*da0073e9SAndroid Build Coastguard Worker generated_file = ( 408*da0073e9SAndroid Build Coastguard Worker f"run_{mode}_{devices_str}_{dtypes_str}_{suites_str}_{compilers_str}.sh" 409*da0073e9SAndroid Build Coastguard Worker ) 410*da0073e9SAndroid Build Coastguard Worker with open(generated_file, "w") as runfile: 411*da0073e9SAndroid Build Coastguard Worker lines = [] 412*da0073e9SAndroid Build Coastguard Worker 413*da0073e9SAndroid Build Coastguard Worker lines.append("#!/bin/bash") 414*da0073e9SAndroid Build Coastguard Worker lines.append("set -x") 415*da0073e9SAndroid Build Coastguard Worker lines.append("# Setup the output directory") 416*da0073e9SAndroid Build Coastguard Worker if not args.keep_output_dir: 417*da0073e9SAndroid Build Coastguard Worker lines.append(f"rm -rf {output_dir}") 418*da0073e9SAndroid Build Coastguard Worker # It's ok if the output directory already exists 419*da0073e9SAndroid Build Coastguard Worker lines.append(f"mkdir -p {output_dir}") 420*da0073e9SAndroid Build Coastguard Worker lines.append("") 421*da0073e9SAndroid Build Coastguard Worker 422*da0073e9SAndroid Build Coastguard Worker for testing in ["performance", "accuracy"]: 423*da0073e9SAndroid Build Coastguard Worker for iter in itertools.product(suites, devices, dtypes): 424*da0073e9SAndroid Build Coastguard Worker suite, device, dtype = iter 425*da0073e9SAndroid Build Coastguard Worker lines.append( 426*da0073e9SAndroid Build Coastguard Worker f"# Commands for {suite} for device={device}, dtype={dtype} for {mode} and for {testing} testing" 427*da0073e9SAndroid Build Coastguard Worker ) 428*da0073e9SAndroid Build Coastguard Worker info = TABLE[mode] 429*da0073e9SAndroid Build Coastguard Worker for compiler in compilers: 430*da0073e9SAndroid Build Coastguard Worker base_cmd = info[compiler] 431*da0073e9SAndroid Build Coastguard Worker output_filename = f"{output_dir}/{generate_csv_name(args, dtype, suite, device, compiler, testing)}" 432*da0073e9SAndroid Build Coastguard Worker launcher_cmd = "python" 433*da0073e9SAndroid Build Coastguard Worker if args.enable_cpu_launcher: 434*da0073e9SAndroid Build Coastguard Worker launcher_cmd = f"python -m torch.backends.xeon.run_cpu {args.cpu_launcher_args}" 435*da0073e9SAndroid Build Coastguard Worker cmd = f"{launcher_cmd} benchmarks/dynamo/{suite}.py --{testing} --{dtype} -d{device} --output={output_filename}" 436*da0073e9SAndroid Build Coastguard Worker cmd = f"{cmd} {base_cmd} {args.extra_args} --dashboard" 437*da0073e9SAndroid Build Coastguard Worker skip_tests_str = get_skip_tests(suite, device, args.training) 438*da0073e9SAndroid Build Coastguard Worker cmd = f"{cmd} {skip_tests_str}" 439*da0073e9SAndroid Build Coastguard Worker 440*da0073e9SAndroid Build Coastguard Worker if args.log_operator_inputs: 441*da0073e9SAndroid Build Coastguard Worker cmd = f"{cmd} --log-operator-inputs" 442*da0073e9SAndroid Build Coastguard Worker 443*da0073e9SAndroid Build Coastguard Worker if args.quick: 444*da0073e9SAndroid Build Coastguard Worker filters = DEFAULTS["quick"][suite] 445*da0073e9SAndroid Build Coastguard Worker cmd = f"{cmd} {filters}" 446*da0073e9SAndroid Build Coastguard Worker 447*da0073e9SAndroid Build Coastguard Worker if ( 448*da0073e9SAndroid Build Coastguard Worker compiler 449*da0073e9SAndroid Build Coastguard Worker in ( 450*da0073e9SAndroid Build Coastguard Worker "inductor", 451*da0073e9SAndroid Build Coastguard Worker "inductor_no_cudagraphs", 452*da0073e9SAndroid Build Coastguard Worker ) 453*da0073e9SAndroid Build Coastguard Worker and not args.no_cold_start_latency 454*da0073e9SAndroid Build Coastguard Worker ): 455*da0073e9SAndroid Build Coastguard Worker cmd = f"{cmd} --cold-start-latency" 456*da0073e9SAndroid Build Coastguard Worker 457*da0073e9SAndroid Build Coastguard Worker if args.batch_size is not None: 458*da0073e9SAndroid Build Coastguard Worker cmd = f"{cmd} --batch-size {args.batch_size}" 459*da0073e9SAndroid Build Coastguard Worker 460*da0073e9SAndroid Build Coastguard Worker if args.threads is not None: 461*da0073e9SAndroid Build Coastguard Worker cmd = f"{cmd} --threads {args.threads}" 462*da0073e9SAndroid Build Coastguard Worker 463*da0073e9SAndroid Build Coastguard Worker if args.total_partitions is not None: 464*da0073e9SAndroid Build Coastguard Worker cmd = f"{cmd} --total-partitions {args.total_partitions}" 465*da0073e9SAndroid Build Coastguard Worker 466*da0073e9SAndroid Build Coastguard Worker if args.partition_id is not None: 467*da0073e9SAndroid Build Coastguard Worker cmd = f"{cmd} --partition-id {args.partition_id}" 468*da0073e9SAndroid Build Coastguard Worker 469*da0073e9SAndroid Build Coastguard Worker if args.inductor_compile_mode is not None: 470*da0073e9SAndroid Build Coastguard Worker cmd = f"{cmd} --inductor-compile-mode {args.inductor_compile_mode}" 471*da0073e9SAndroid Build Coastguard Worker lines.append(cmd) 472*da0073e9SAndroid Build Coastguard Worker lines.append("") 473*da0073e9SAndroid Build Coastguard Worker runfile.writelines([line + "\n" for line in lines]) 474*da0073e9SAndroid Build Coastguard Worker return generated_file 475*da0073e9SAndroid Build Coastguard Worker 476*da0073e9SAndroid Build Coastguard Worker 477*da0073e9SAndroid Build Coastguard Workerdef generate_dropdown_comment(title, body): 478*da0073e9SAndroid Build Coastguard Worker str_io = io.StringIO() 479*da0073e9SAndroid Build Coastguard Worker str_io.write(f"{title}\n") 480*da0073e9SAndroid Build Coastguard Worker str_io.write("<details>\n") 481*da0073e9SAndroid Build Coastguard Worker str_io.write("<summary>see more</summary>\n") 482*da0073e9SAndroid Build Coastguard Worker str_io.write(f"{body}") 483*da0073e9SAndroid Build Coastguard Worker str_io.write("\n") 484*da0073e9SAndroid Build Coastguard Worker str_io.write("</details>\n\n") 485*da0073e9SAndroid Build Coastguard Worker return str_io.getvalue() 486*da0073e9SAndroid Build Coastguard Worker 487*da0073e9SAndroid Build Coastguard Worker 488*da0073e9SAndroid Build Coastguard Workerdef build_summary(args): 489*da0073e9SAndroid Build Coastguard Worker out_io = io.StringIO() 490*da0073e9SAndroid Build Coastguard Worker 491*da0073e9SAndroid Build Coastguard Worker def print_commit_hash(path, name): 492*da0073e9SAndroid Build Coastguard Worker if args.base_sha is not None: 493*da0073e9SAndroid Build Coastguard Worker if name == "pytorch": 494*da0073e9SAndroid Build Coastguard Worker out_io.write(f"{name} commit: {args.base_sha}\n") 495*da0073e9SAndroid Build Coastguard Worker elif exists(path): 496*da0073e9SAndroid Build Coastguard Worker import git 497*da0073e9SAndroid Build Coastguard Worker 498*da0073e9SAndroid Build Coastguard Worker repo = git.Repo(path, search_parent_directories=True) 499*da0073e9SAndroid Build Coastguard Worker sha = repo.head.object.hexsha 500*da0073e9SAndroid Build Coastguard Worker date = repo.head.object.committed_datetime 501*da0073e9SAndroid Build Coastguard Worker out_io.write(f"{name} commit: {sha}\n") 502*da0073e9SAndroid Build Coastguard Worker out_io.write(f"{name} commit date: {date}\n") 503*da0073e9SAndroid Build Coastguard Worker else: 504*da0073e9SAndroid Build Coastguard Worker out_io.write(f"{name} Absent\n") 505*da0073e9SAndroid Build Coastguard Worker 506*da0073e9SAndroid Build Coastguard Worker def env_var(name): 507*da0073e9SAndroid Build Coastguard Worker if name in os.environ: 508*da0073e9SAndroid Build Coastguard Worker out_io.write(f"{name} = {os.environ[name]}\n") 509*da0073e9SAndroid Build Coastguard Worker else: 510*da0073e9SAndroid Build Coastguard Worker out_io.write(f"{name} = {None}\n") 511*da0073e9SAndroid Build Coastguard Worker 512*da0073e9SAndroid Build Coastguard Worker out_io.write("\n") 513*da0073e9SAndroid Build Coastguard Worker out_io.write("### Run name ###\n") 514*da0073e9SAndroid Build Coastguard Worker out_io.write(get_archive_name(args, args.dtypes[0])) 515*da0073e9SAndroid Build Coastguard Worker out_io.write("\n") 516*da0073e9SAndroid Build Coastguard Worker 517*da0073e9SAndroid Build Coastguard Worker out_io.write("\n") 518*da0073e9SAndroid Build Coastguard Worker out_io.write("### Commit hashes ###\n") 519*da0073e9SAndroid Build Coastguard Worker print_commit_hash("../pytorch", "pytorch") 520*da0073e9SAndroid Build Coastguard Worker print_commit_hash("../torchbenchmark", "torchbench") 521*da0073e9SAndroid Build Coastguard Worker 522*da0073e9SAndroid Build Coastguard Worker out_io.write("\n") 523*da0073e9SAndroid Build Coastguard Worker out_io.write("### TorchDynamo config flags ###\n") 524*da0073e9SAndroid Build Coastguard Worker for key in dir(torch._dynamo.config): 525*da0073e9SAndroid Build Coastguard Worker val = getattr(torch._dynamo.config, key) 526*da0073e9SAndroid Build Coastguard Worker if not key.startswith("__") and isinstance(val, bool): 527*da0073e9SAndroid Build Coastguard Worker out_io.write(f"torch._dynamo.config.{key} = {val}\n") 528*da0073e9SAndroid Build Coastguard Worker 529*da0073e9SAndroid Build Coastguard Worker out_io.write("\n") 530*da0073e9SAndroid Build Coastguard Worker out_io.write("### Torch version ###\n") 531*da0073e9SAndroid Build Coastguard Worker out_io.write(f"torch: {torch.__version__}\n") 532*da0073e9SAndroid Build Coastguard Worker 533*da0073e9SAndroid Build Coastguard Worker out_io.write("\n") 534*da0073e9SAndroid Build Coastguard Worker out_io.write("### Environment variables ###\n") 535*da0073e9SAndroid Build Coastguard Worker env_var("TORCH_CUDA_ARCH_LIST") 536*da0073e9SAndroid Build Coastguard Worker env_var("CUDA_HOME") 537*da0073e9SAndroid Build Coastguard Worker env_var("USE_LLVM") 538*da0073e9SAndroid Build Coastguard Worker 539*da0073e9SAndroid Build Coastguard Worker if "cuda" in args.devices: 540*da0073e9SAndroid Build Coastguard Worker out_io.write("\n") 541*da0073e9SAndroid Build Coastguard Worker out_io.write("### GPU details ###\n") 542*da0073e9SAndroid Build Coastguard Worker out_io.write(f"CUDNN VERSION: {torch.backends.cudnn.version()}\n") 543*da0073e9SAndroid Build Coastguard Worker out_io.write(f"Number CUDA Devices: {torch.cuda.device_count()}\n") 544*da0073e9SAndroid Build Coastguard Worker out_io.write(f"Device Name: {torch.cuda.get_device_name(0)}\n") 545*da0073e9SAndroid Build Coastguard Worker out_io.write( 546*da0073e9SAndroid Build Coastguard Worker f"Device Memory [GB]: {torch.cuda.get_device_properties(0).total_memory/1e9}\n" 547*da0073e9SAndroid Build Coastguard Worker ) 548*da0073e9SAndroid Build Coastguard Worker 549*da0073e9SAndroid Build Coastguard Worker title = "## Build Summary" 550*da0073e9SAndroid Build Coastguard Worker comment = generate_dropdown_comment(title, out_io.getvalue()) 551*da0073e9SAndroid Build Coastguard Worker with open(f"{output_dir}/gh_build_summary.txt", "w") as gh_fh: 552*da0073e9SAndroid Build Coastguard Worker gh_fh.write(comment) 553*da0073e9SAndroid Build Coastguard Worker 554*da0073e9SAndroid Build Coastguard Worker 555*da0073e9SAndroid Build Coastguard Worker@functools.lru_cache(None) 556*da0073e9SAndroid Build Coastguard Workerdef archive_data(archive_name): 557*da0073e9SAndroid Build Coastguard Worker if archive_name is not None: 558*da0073e9SAndroid Build Coastguard Worker prefix_match = re.search(r"\w+(?=_performance)", archive_name) 559*da0073e9SAndroid Build Coastguard Worker if prefix_match is not None: 560*da0073e9SAndroid Build Coastguard Worker prefix = prefix_match.group(0) 561*da0073e9SAndroid Build Coastguard Worker else: 562*da0073e9SAndroid Build Coastguard Worker prefix = "" 563*da0073e9SAndroid Build Coastguard Worker day_match = re.search(r"day_(\d+)_", archive_name) 564*da0073e9SAndroid Build Coastguard Worker if day_match is not None: 565*da0073e9SAndroid Build Coastguard Worker day = day_match.group(1) 566*da0073e9SAndroid Build Coastguard Worker else: 567*da0073e9SAndroid Build Coastguard Worker day = "000" 568*da0073e9SAndroid Build Coastguard Worker else: 569*da0073e9SAndroid Build Coastguard Worker now = datetime.now(tz=timezone(timedelta(hours=-8))) 570*da0073e9SAndroid Build Coastguard Worker day = now.strftime("%j") 571*da0073e9SAndroid Build Coastguard Worker prefix = now.strftime(f"day_{day}_%d_%m_%y") 572*da0073e9SAndroid Build Coastguard Worker return day, prefix 573*da0073e9SAndroid Build Coastguard Worker 574*da0073e9SAndroid Build Coastguard Worker 575*da0073e9SAndroid Build Coastguard Worker@functools.lru_cache(None) 576*da0073e9SAndroid Build Coastguard Workerdef default_archive_name(dtype): 577*da0073e9SAndroid Build Coastguard Worker _, prefix = archive_data(None) 578*da0073e9SAndroid Build Coastguard Worker return f"{prefix}_performance_{dtype}_{randint(100, 999)}" 579*da0073e9SAndroid Build Coastguard Worker 580*da0073e9SAndroid Build Coastguard Worker 581*da0073e9SAndroid Build Coastguard Workerdef get_archive_name(args, dtype): 582*da0073e9SAndroid Build Coastguard Worker return ( 583*da0073e9SAndroid Build Coastguard Worker default_archive_name(dtype) if args.archive_name is None else args.archive_name 584*da0073e9SAndroid Build Coastguard Worker ) 585*da0073e9SAndroid Build Coastguard Worker 586*da0073e9SAndroid Build Coastguard Worker 587*da0073e9SAndroid Build Coastguard Workerdef archive(src_dir, dest_dir_prefix, archive_name, dtype): 588*da0073e9SAndroid Build Coastguard Worker if archive_name is None: 589*da0073e9SAndroid Build Coastguard Worker archive_name = default_archive_name(dtype) 590*da0073e9SAndroid Build Coastguard Worker # Copy the folder to archived location 591*da0073e9SAndroid Build Coastguard Worker dest = os.path.join(dest_dir_prefix, archive_name) 592*da0073e9SAndroid Build Coastguard Worker shutil.copytree(src_dir, dest, dirs_exist_ok=True) 593*da0073e9SAndroid Build Coastguard Worker print(f"copied contents of {src_dir} to {dest}") 594*da0073e9SAndroid Build Coastguard Worker 595*da0073e9SAndroid Build Coastguard Worker 596*da0073e9SAndroid Build Coastguard Workerdef get_metric_title(metric): 597*da0073e9SAndroid Build Coastguard Worker if metric == "speedup": 598*da0073e9SAndroid Build Coastguard Worker return "Performance speedup" 599*da0073e9SAndroid Build Coastguard Worker elif metric == "accuracy": 600*da0073e9SAndroid Build Coastguard Worker return "Accuracy" 601*da0073e9SAndroid Build Coastguard Worker elif metric == "compilation_latency": 602*da0073e9SAndroid Build Coastguard Worker return "Compilation latency (sec)" 603*da0073e9SAndroid Build Coastguard Worker elif metric == "compression_ratio": 604*da0073e9SAndroid Build Coastguard Worker return "Peak Memory Compression Ratio" 605*da0073e9SAndroid Build Coastguard Worker elif metric == "abs_latency": 606*da0073e9SAndroid Build Coastguard Worker return "Absolute latency (ms)" 607*da0073e9SAndroid Build Coastguard Worker raise RuntimeError("unknown metric") 608*da0073e9SAndroid Build Coastguard Worker 609*da0073e9SAndroid Build Coastguard Worker 610*da0073e9SAndroid Build Coastguard Workerclass Parser: 611*da0073e9SAndroid Build Coastguard Worker def __init__( 612*da0073e9SAndroid Build Coastguard Worker self, suites, devices, dtypes, compilers, flag_compilers, mode, output_dir 613*da0073e9SAndroid Build Coastguard Worker ): 614*da0073e9SAndroid Build Coastguard Worker self.suites = suites 615*da0073e9SAndroid Build Coastguard Worker self.devices = devices 616*da0073e9SAndroid Build Coastguard Worker self.dtypes = dtypes 617*da0073e9SAndroid Build Coastguard Worker self.compilers = compilers 618*da0073e9SAndroid Build Coastguard Worker self.flag_compilers = flag_compilers 619*da0073e9SAndroid Build Coastguard Worker self.output_dir = output_dir 620*da0073e9SAndroid Build Coastguard Worker self.mode = mode 621*da0073e9SAndroid Build Coastguard Worker 622*da0073e9SAndroid Build Coastguard Worker def has_header(self, output_filename): 623*da0073e9SAndroid Build Coastguard Worker header_present = False 624*da0073e9SAndroid Build Coastguard Worker with open(output_filename) as f: 625*da0073e9SAndroid Build Coastguard Worker line = f.readline() 626*da0073e9SAndroid Build Coastguard Worker if "dev" in line: 627*da0073e9SAndroid Build Coastguard Worker header_present = True 628*da0073e9SAndroid Build Coastguard Worker return header_present 629*da0073e9SAndroid Build Coastguard Worker 630*da0073e9SAndroid Build Coastguard Worker 631*da0073e9SAndroid Build Coastguard Workerclass ParsePerformanceLogs(Parser): 632*da0073e9SAndroid Build Coastguard Worker def __init__( 633*da0073e9SAndroid Build Coastguard Worker self, 634*da0073e9SAndroid Build Coastguard Worker suites, 635*da0073e9SAndroid Build Coastguard Worker devices, 636*da0073e9SAndroid Build Coastguard Worker dtypes, 637*da0073e9SAndroid Build Coastguard Worker compilers, 638*da0073e9SAndroid Build Coastguard Worker flag_compilers, 639*da0073e9SAndroid Build Coastguard Worker mode, 640*da0073e9SAndroid Build Coastguard Worker output_dir, 641*da0073e9SAndroid Build Coastguard Worker include_slowdowns=False, 642*da0073e9SAndroid Build Coastguard Worker ): 643*da0073e9SAndroid Build Coastguard Worker super().__init__( 644*da0073e9SAndroid Build Coastguard Worker suites, 645*da0073e9SAndroid Build Coastguard Worker devices, 646*da0073e9SAndroid Build Coastguard Worker dtypes, 647*da0073e9SAndroid Build Coastguard Worker compilers, 648*da0073e9SAndroid Build Coastguard Worker flag_compilers, 649*da0073e9SAndroid Build Coastguard Worker mode, 650*da0073e9SAndroid Build Coastguard Worker output_dir, 651*da0073e9SAndroid Build Coastguard Worker ) 652*da0073e9SAndroid Build Coastguard Worker self.parsed_frames = defaultdict(lambda: defaultdict(None)) 653*da0073e9SAndroid Build Coastguard Worker self.untouched_parsed_frames = defaultdict(lambda: defaultdict(None)) 654*da0073e9SAndroid Build Coastguard Worker self.metrics = [ 655*da0073e9SAndroid Build Coastguard Worker "speedup", 656*da0073e9SAndroid Build Coastguard Worker "abs_latency", 657*da0073e9SAndroid Build Coastguard Worker "compilation_latency", 658*da0073e9SAndroid Build Coastguard Worker "compression_ratio", 659*da0073e9SAndroid Build Coastguard Worker ] 660*da0073e9SAndroid Build Coastguard Worker self.bottom_k = 50 661*da0073e9SAndroid Build Coastguard Worker self.parse() 662*da0073e9SAndroid Build Coastguard Worker self.include_slowdowns = include_slowdowns 663*da0073e9SAndroid Build Coastguard Worker 664*da0073e9SAndroid Build Coastguard Worker def plot_graph(self, df, title): 665*da0073e9SAndroid Build Coastguard Worker labels = df.columns.values.tolist() 666*da0073e9SAndroid Build Coastguard Worker labels = labels[3:] 667*da0073e9SAndroid Build Coastguard Worker df.plot( 668*da0073e9SAndroid Build Coastguard Worker x="name", 669*da0073e9SAndroid Build Coastguard Worker y=labels, 670*da0073e9SAndroid Build Coastguard Worker kind="bar", 671*da0073e9SAndroid Build Coastguard Worker width=0.65, 672*da0073e9SAndroid Build Coastguard Worker title=title, 673*da0073e9SAndroid Build Coastguard Worker ylabel="Speedup over eager", 674*da0073e9SAndroid Build Coastguard Worker xlabel="", 675*da0073e9SAndroid Build Coastguard Worker grid=True, 676*da0073e9SAndroid Build Coastguard Worker figsize=(max(len(df.index) / 4, 5), 10), 677*da0073e9SAndroid Build Coastguard Worker edgecolor="black", 678*da0073e9SAndroid Build Coastguard Worker ) 679*da0073e9SAndroid Build Coastguard Worker plt.tight_layout() 680*da0073e9SAndroid Build Coastguard Worker plt.savefig(f"{self.output_dir}/{title}.png") 681*da0073e9SAndroid Build Coastguard Worker 682*da0073e9SAndroid Build Coastguard Worker def read_csv(self, output_filename): 683*da0073e9SAndroid Build Coastguard Worker if self.has_header(output_filename): 684*da0073e9SAndroid Build Coastguard Worker return pd.read_csv(output_filename) 685*da0073e9SAndroid Build Coastguard Worker else: 686*da0073e9SAndroid Build Coastguard Worker return pd.read_csv( 687*da0073e9SAndroid Build Coastguard Worker output_filename, 688*da0073e9SAndroid Build Coastguard Worker names=[ 689*da0073e9SAndroid Build Coastguard Worker "dev", 690*da0073e9SAndroid Build Coastguard Worker "name", 691*da0073e9SAndroid Build Coastguard Worker "batch_size", 692*da0073e9SAndroid Build Coastguard Worker "speedup", 693*da0073e9SAndroid Build Coastguard Worker "abs_latency", 694*da0073e9SAndroid Build Coastguard Worker "compilation_latency", 695*da0073e9SAndroid Build Coastguard Worker "compression_ratio", 696*da0073e9SAndroid Build Coastguard Worker ], 697*da0073e9SAndroid Build Coastguard Worker header=None, 698*da0073e9SAndroid Build Coastguard Worker engine="python", 699*da0073e9SAndroid Build Coastguard Worker ) 700*da0073e9SAndroid Build Coastguard Worker 701*da0073e9SAndroid Build Coastguard Worker def parse(self): 702*da0073e9SAndroid Build Coastguard Worker self.extract_df("accuracy", "accuracy") 703*da0073e9SAndroid Build Coastguard Worker for metric in self.metrics: 704*da0073e9SAndroid Build Coastguard Worker self.extract_df(metric, "performance") 705*da0073e9SAndroid Build Coastguard Worker 706*da0073e9SAndroid Build Coastguard Worker def clean_batch_sizes(self, frames): 707*da0073e9SAndroid Build Coastguard Worker # Clean up batch sizes when its 0 708*da0073e9SAndroid Build Coastguard Worker if len(frames) == 1: 709*da0073e9SAndroid Build Coastguard Worker return frames 710*da0073e9SAndroid Build Coastguard Worker batch_sizes = frames[0]["batch_size"].to_list() 711*da0073e9SAndroid Build Coastguard Worker for frame in frames[1:]: 712*da0073e9SAndroid Build Coastguard Worker frame_batch_sizes = frame["batch_size"].to_list() 713*da0073e9SAndroid Build Coastguard Worker for idx, (batch_a, batch_b) in enumerate( 714*da0073e9SAndroid Build Coastguard Worker zip(batch_sizes, frame_batch_sizes) 715*da0073e9SAndroid Build Coastguard Worker ): 716*da0073e9SAndroid Build Coastguard Worker assert batch_a == batch_b or batch_a == 0 or batch_b == 0, print( 717*da0073e9SAndroid Build Coastguard Worker f"a={batch_a}, b={batch_b}" 718*da0073e9SAndroid Build Coastguard Worker ) 719*da0073e9SAndroid Build Coastguard Worker batch_sizes[idx] = max(batch_a, batch_b) 720*da0073e9SAndroid Build Coastguard Worker for frame in frames: 721*da0073e9SAndroid Build Coastguard Worker frame["batch_size"] = batch_sizes 722*da0073e9SAndroid Build Coastguard Worker return frames 723*da0073e9SAndroid Build Coastguard Worker 724*da0073e9SAndroid Build Coastguard Worker def extract_df(self, metric, testing): 725*da0073e9SAndroid Build Coastguard Worker for iter in itertools.product(self.suites, self.devices, self.dtypes): 726*da0073e9SAndroid Build Coastguard Worker suite, device, dtype = iter 727*da0073e9SAndroid Build Coastguard Worker frames = [] 728*da0073e9SAndroid Build Coastguard Worker for compiler in self.compilers: 729*da0073e9SAndroid Build Coastguard Worker output_filename = f"{self.output_dir}/{compiler}_{suite}_{dtype}_{self.mode}_{device}_{testing}.csv" 730*da0073e9SAndroid Build Coastguard Worker df = self.read_csv(output_filename) 731*da0073e9SAndroid Build Coastguard Worker if metric not in df: 732*da0073e9SAndroid Build Coastguard Worker df.insert(len(df.columns), metric, np.nan) 733*da0073e9SAndroid Build Coastguard Worker df = df[["dev", "name", "batch_size", metric]] 734*da0073e9SAndroid Build Coastguard Worker df.rename(columns={metric: compiler}, inplace=True) 735*da0073e9SAndroid Build Coastguard Worker df["batch_size"] = df["batch_size"].astype(int) 736*da0073e9SAndroid Build Coastguard Worker frames.append(df) 737*da0073e9SAndroid Build Coastguard Worker 738*da0073e9SAndroid Build Coastguard Worker # Merge the results 739*da0073e9SAndroid Build Coastguard Worker frames = self.clean_batch_sizes(frames) 740*da0073e9SAndroid Build Coastguard Worker if len(self.compilers) == 1: 741*da0073e9SAndroid Build Coastguard Worker df = frames[0] 742*da0073e9SAndroid Build Coastguard Worker else: 743*da0073e9SAndroid Build Coastguard Worker # Merge data frames 744*da0073e9SAndroid Build Coastguard Worker df = pd.merge(frames[0], frames[1], on=["dev", "name", "batch_size"]) 745*da0073e9SAndroid Build Coastguard Worker for idx in range(2, len(frames)): 746*da0073e9SAndroid Build Coastguard Worker df = pd.merge(df, frames[idx], on=["dev", "name", "batch_size"]) 747*da0073e9SAndroid Build Coastguard Worker 748*da0073e9SAndroid Build Coastguard Worker if testing == "performance": 749*da0073e9SAndroid Build Coastguard Worker for compiler in self.compilers: 750*da0073e9SAndroid Build Coastguard Worker df[compiler] = pd.to_numeric(df[compiler], errors="coerce").fillna( 751*da0073e9SAndroid Build Coastguard Worker 0 752*da0073e9SAndroid Build Coastguard Worker ) 753*da0073e9SAndroid Build Coastguard Worker 754*da0073e9SAndroid Build Coastguard Worker df_copy = df.copy() 755*da0073e9SAndroid Build Coastguard Worker df_copy = df_copy.sort_values( 756*da0073e9SAndroid Build Coastguard Worker by=list(reversed(self.compilers)), ascending=False 757*da0073e9SAndroid Build Coastguard Worker ) 758*da0073e9SAndroid Build Coastguard Worker if "inductor" in self.compilers: 759*da0073e9SAndroid Build Coastguard Worker df_copy = df_copy.sort_values(by="inductor", ascending=False) 760*da0073e9SAndroid Build Coastguard Worker self.untouched_parsed_frames[suite][metric] = df_copy 761*da0073e9SAndroid Build Coastguard Worker 762*da0073e9SAndroid Build Coastguard Worker if testing == "performance": 763*da0073e9SAndroid Build Coastguard Worker df_accuracy = self.parsed_frames[suite]["accuracy"] 764*da0073e9SAndroid Build Coastguard Worker perf_rows = [] 765*da0073e9SAndroid Build Coastguard Worker for model_name in df["name"]: 766*da0073e9SAndroid Build Coastguard Worker perf_row = df[df["name"] == model_name].copy() 767*da0073e9SAndroid Build Coastguard Worker acc_row = df_accuracy[df_accuracy["name"] == model_name] 768*da0073e9SAndroid Build Coastguard Worker for compiler in self.compilers: 769*da0073e9SAndroid Build Coastguard Worker if not perf_row.empty: 770*da0073e9SAndroid Build Coastguard Worker if acc_row.empty: 771*da0073e9SAndroid Build Coastguard Worker perf_row[compiler] = 0.0 772*da0073e9SAndroid Build Coastguard Worker elif acc_row[compiler].iloc[0] in ( 773*da0073e9SAndroid Build Coastguard Worker "model_fail_to_load", 774*da0073e9SAndroid Build Coastguard Worker "eager_fail_to_run", 775*da0073e9SAndroid Build Coastguard Worker ): 776*da0073e9SAndroid Build Coastguard Worker perf_row = pd.DataFrame() 777*da0073e9SAndroid Build Coastguard Worker elif acc_row[compiler].iloc[0] not in ( 778*da0073e9SAndroid Build Coastguard Worker "pass", 779*da0073e9SAndroid Build Coastguard Worker "pass_due_to_skip", 780*da0073e9SAndroid Build Coastguard Worker ): 781*da0073e9SAndroid Build Coastguard Worker perf_row[compiler] = 0.0 782*da0073e9SAndroid Build Coastguard Worker if not perf_row.empty: 783*da0073e9SAndroid Build Coastguard Worker perf_rows.append(perf_row) 784*da0073e9SAndroid Build Coastguard Worker df = pd.concat(perf_rows) 785*da0073e9SAndroid Build Coastguard Worker df = df.sort_values(by=list(reversed(self.compilers)), ascending=False) 786*da0073e9SAndroid Build Coastguard Worker 787*da0073e9SAndroid Build Coastguard Worker if "inductor" in self.compilers: 788*da0073e9SAndroid Build Coastguard Worker df = df.sort_values(by="inductor", ascending=False) 789*da0073e9SAndroid Build Coastguard Worker self.parsed_frames[suite][metric] = df 790*da0073e9SAndroid Build Coastguard Worker 791*da0073e9SAndroid Build Coastguard Worker def get_passing_entries(self, compiler, df): 792*da0073e9SAndroid Build Coastguard Worker return df[compiler][df[compiler] > 0] 793*da0073e9SAndroid Build Coastguard Worker 794*da0073e9SAndroid Build Coastguard Worker def comp_time(self, compiler, df): 795*da0073e9SAndroid Build Coastguard Worker df = self.get_passing_entries(compiler, df) 796*da0073e9SAndroid Build Coastguard Worker # df = df.sort_values(by=compiler, ascending=False)[compiler][: self.bottom_k] 797*da0073e9SAndroid Build Coastguard Worker if df.empty: 798*da0073e9SAndroid Build Coastguard Worker return "0.0" 799*da0073e9SAndroid Build Coastguard Worker 800*da0073e9SAndroid Build Coastguard Worker return f"{df.mean():.2f}" 801*da0073e9SAndroid Build Coastguard Worker 802*da0073e9SAndroid Build Coastguard Worker def geomean(self, compiler, df): 803*da0073e9SAndroid Build Coastguard Worker cleaned_df = self.get_passing_entries(compiler, df) 804*da0073e9SAndroid Build Coastguard Worker if not self.include_slowdowns: 805*da0073e9SAndroid Build Coastguard Worker cleaned_df = cleaned_df.clip(1) 806*da0073e9SAndroid Build Coastguard Worker if cleaned_df.empty: 807*da0073e9SAndroid Build Coastguard Worker return "0.0x" 808*da0073e9SAndroid Build Coastguard Worker return f"{gmean(cleaned_df):.2f}x" 809*da0073e9SAndroid Build Coastguard Worker 810*da0073e9SAndroid Build Coastguard Worker def passrate(self, compiler, df): 811*da0073e9SAndroid Build Coastguard Worker total = len(df.index) 812*da0073e9SAndroid Build Coastguard Worker passing = df[df[compiler] > 0.0][compiler].count() 813*da0073e9SAndroid Build Coastguard Worker perc = int(percentage(passing, total, decimals=0)) 814*da0073e9SAndroid Build Coastguard Worker return f"{perc}%, {passing}/{total}" 815*da0073e9SAndroid Build Coastguard Worker 816*da0073e9SAndroid Build Coastguard Worker def memory(self, compiler, df): 817*da0073e9SAndroid Build Coastguard Worker df = self.get_passing_entries(compiler, df) 818*da0073e9SAndroid Build Coastguard Worker df = df.fillna(0) 819*da0073e9SAndroid Build Coastguard Worker df = df[df > 0] 820*da0073e9SAndroid Build Coastguard Worker if df.empty: 821*da0073e9SAndroid Build Coastguard Worker return "0.0x" 822*da0073e9SAndroid Build Coastguard Worker return f"{df.mean():.2f}x" 823*da0073e9SAndroid Build Coastguard Worker 824*da0073e9SAndroid Build Coastguard Worker def exec_summary_df(self, fn, metric): 825*da0073e9SAndroid Build Coastguard Worker """ 826*da0073e9SAndroid Build Coastguard Worker Generate a table with passrate and geomean perf 827*da0073e9SAndroid Build Coastguard Worker """ 828*da0073e9SAndroid Build Coastguard Worker cols = {} 829*da0073e9SAndroid Build Coastguard Worker cols["Compiler"] = self.compilers 830*da0073e9SAndroid Build Coastguard Worker for suite in self.suites: 831*da0073e9SAndroid Build Coastguard Worker df = self.parsed_frames[suite][metric] 832*da0073e9SAndroid Build Coastguard Worker # speedups = [self.geomean(compiler, df) for compiler in self.compilers] 833*da0073e9SAndroid Build Coastguard Worker speedups = [fn(compiler, df) for compiler in self.compilers] 834*da0073e9SAndroid Build Coastguard Worker col = pd.Series(data=speedups, index=self.compilers) 835*da0073e9SAndroid Build Coastguard Worker cols[suite] = col 836*da0073e9SAndroid Build Coastguard Worker df = pd.DataFrame(cols) 837*da0073e9SAndroid Build Coastguard Worker df = df.fillna(0) 838*da0073e9SAndroid Build Coastguard Worker df.to_csv(os.path.join(self.output_dir, f"{fn.__name__}.csv")) 839*da0073e9SAndroid Build Coastguard Worker return df 840*da0073e9SAndroid Build Coastguard Worker 841*da0073e9SAndroid Build Coastguard Worker def exec_summary_text(self, caption, fn, metric): 842*da0073e9SAndroid Build Coastguard Worker df = self.exec_summary_df(fn, metric) 843*da0073e9SAndroid Build Coastguard Worker tabform = tabulate(df, headers="keys", tablefmt="pretty", showindex="never") 844*da0073e9SAndroid Build Coastguard Worker 845*da0073e9SAndroid Build Coastguard Worker str_io = io.StringIO() 846*da0073e9SAndroid Build Coastguard Worker str_io.write(f"{caption}") 847*da0073e9SAndroid Build Coastguard Worker str_io.write("~~~\n") 848*da0073e9SAndroid Build Coastguard Worker str_io.write(f"{tabform}\n") 849*da0073e9SAndroid Build Coastguard Worker str_io.write("~~~\n") 850*da0073e9SAndroid Build Coastguard Worker return str_io.getvalue() 851*da0073e9SAndroid Build Coastguard Worker 852*da0073e9SAndroid Build Coastguard Worker def generate_executive_summary(self): 853*da0073e9SAndroid Build Coastguard Worker machine = "A100 GPUs" 854*da0073e9SAndroid Build Coastguard Worker if "cpu" in self.devices: 855*da0073e9SAndroid Build Coastguard Worker get_machine_cmd = "lscpu| grep 'Model name' | awk -F':' '{print $2}'" 856*da0073e9SAndroid Build Coastguard Worker machine = subprocess.getstatusoutput(get_machine_cmd)[1].strip() 857*da0073e9SAndroid Build Coastguard Worker description = ( 858*da0073e9SAndroid Build Coastguard Worker "We evaluate different backends " 859*da0073e9SAndroid Build Coastguard Worker "across three benchmark suites - torchbench, huggingface and timm. We run " 860*da0073e9SAndroid Build Coastguard Worker "these experiments on " 861*da0073e9SAndroid Build Coastguard Worker + machine 862*da0073e9SAndroid Build Coastguard Worker + ". Each experiment runs one iteration of forward pass " 863*da0073e9SAndroid Build Coastguard Worker "and backward pass for training and forward pass only for inference. " 864*da0073e9SAndroid Build Coastguard Worker "For accuracy, we check the numerical correctness of forward pass outputs and gradients " 865*da0073e9SAndroid Build Coastguard Worker "by comparing with native pytorch. We measure speedup " 866*da0073e9SAndroid Build Coastguard Worker "by normalizing against the performance of native pytorch. We report mean " 867*da0073e9SAndroid Build Coastguard Worker "compilation latency numbers and peak memory footprint reduction ratio. \n\n" 868*da0073e9SAndroid Build Coastguard Worker "Caveats\n" 869*da0073e9SAndroid Build Coastguard Worker "1) Batch size has been reduced to workaround OOM errors. Work is in progress to " 870*da0073e9SAndroid Build Coastguard Worker "reduce peak memory footprint.\n" 871*da0073e9SAndroid Build Coastguard Worker "2) Experiments do not cover dynamic shapes.\n" 872*da0073e9SAndroid Build Coastguard Worker "3) Experimental setup does not have optimizer.\n\n" 873*da0073e9SAndroid Build Coastguard Worker ) 874*da0073e9SAndroid Build Coastguard Worker comment = generate_dropdown_comment("", description) 875*da0073e9SAndroid Build Coastguard Worker str_io = io.StringIO() 876*da0073e9SAndroid Build Coastguard Worker str_io.write("\n") 877*da0073e9SAndroid Build Coastguard Worker str_io.write("## Executive Summary ##\n") 878*da0073e9SAndroid Build Coastguard Worker str_io.write(comment) 879*da0073e9SAndroid Build Coastguard Worker 880*da0073e9SAndroid Build Coastguard Worker speedup_caption = "Geometric mean speedup \n" 881*da0073e9SAndroid Build Coastguard Worker speedup_summary = self.exec_summary_text( 882*da0073e9SAndroid Build Coastguard Worker speedup_caption, self.geomean, "speedup" 883*da0073e9SAndroid Build Coastguard Worker ) 884*da0073e9SAndroid Build Coastguard Worker 885*da0073e9SAndroid Build Coastguard Worker passrate_caption = "Passrate\n" 886*da0073e9SAndroid Build Coastguard Worker passrate_summary = self.exec_summary_text( 887*da0073e9SAndroid Build Coastguard Worker passrate_caption, self.passrate, "speedup" 888*da0073e9SAndroid Build Coastguard Worker ) 889*da0073e9SAndroid Build Coastguard Worker 890*da0073e9SAndroid Build Coastguard Worker comp_time_caption = "Mean compilation time (seconds)\n" 891*da0073e9SAndroid Build Coastguard Worker comp_time_summary = self.exec_summary_text( 892*da0073e9SAndroid Build Coastguard Worker comp_time_caption, self.comp_time, "compilation_latency" 893*da0073e9SAndroid Build Coastguard Worker ) 894*da0073e9SAndroid Build Coastguard Worker 895*da0073e9SAndroid Build Coastguard Worker peak_memory_caption = ( 896*da0073e9SAndroid Build Coastguard Worker "Peak memory footprint compression ratio (higher is better)\n" 897*da0073e9SAndroid Build Coastguard Worker ) 898*da0073e9SAndroid Build Coastguard Worker peak_memory_summary = self.exec_summary_text( 899*da0073e9SAndroid Build Coastguard Worker peak_memory_caption, self.memory, "compression_ratio" 900*da0073e9SAndroid Build Coastguard Worker ) 901*da0073e9SAndroid Build Coastguard Worker 902*da0073e9SAndroid Build Coastguard Worker str_io.write( 903*da0073e9SAndroid Build Coastguard Worker "To measure performance, compilation latency and memory footprint reduction, " 904*da0073e9SAndroid Build Coastguard Worker "we remove the models that fail accuracy checks.\n\n" 905*da0073e9SAndroid Build Coastguard Worker ) 906*da0073e9SAndroid Build Coastguard Worker str_io.write(passrate_summary) 907*da0073e9SAndroid Build Coastguard Worker str_io.write(speedup_summary) 908*da0073e9SAndroid Build Coastguard Worker str_io.write(comp_time_summary) 909*da0073e9SAndroid Build Coastguard Worker str_io.write(peak_memory_summary) 910*da0073e9SAndroid Build Coastguard Worker self.executive_summary = str_io.getvalue() 911*da0073e9SAndroid Build Coastguard Worker 912*da0073e9SAndroid Build Coastguard Worker def flag_bad_entries(self, suite, metric, flag_fn): 913*da0073e9SAndroid Build Coastguard Worker df = self.untouched_parsed_frames[suite][metric] 914*da0073e9SAndroid Build Coastguard Worker df = df.drop("dev", axis=1) 915*da0073e9SAndroid Build Coastguard Worker df = df.rename(columns={"batch_size": "bs"}) 916*da0073e9SAndroid Build Coastguard Worker # apply flag_fn elementwise to flag_compilers columns, 917*da0073e9SAndroid Build Coastguard Worker # if one element fails, the entire row is flagged 918*da0073e9SAndroid Build Coastguard Worker flag = np.logical_or.reduce( 919*da0073e9SAndroid Build Coastguard Worker df[self.flag_compilers].applymap(flag_fn), 920*da0073e9SAndroid Build Coastguard Worker axis=1, 921*da0073e9SAndroid Build Coastguard Worker ) 922*da0073e9SAndroid Build Coastguard Worker df = df[flag] 923*da0073e9SAndroid Build Coastguard Worker df = df.assign(suite=suite) 924*da0073e9SAndroid Build Coastguard Worker return df.reindex(columns=["suite", "name"] + self.flag_compilers) 925*da0073e9SAndroid Build Coastguard Worker 926*da0073e9SAndroid Build Coastguard Worker def generate_warnings(self): 927*da0073e9SAndroid Build Coastguard Worker title = "## Warnings ##" 928*da0073e9SAndroid Build Coastguard Worker body = ( 929*da0073e9SAndroid Build Coastguard Worker "We flag models where:\n\n" 930*da0073e9SAndroid Build Coastguard Worker " - accuracy fails\n" 931*da0073e9SAndroid Build Coastguard Worker " - speedup < 0.95x (NOTE: 0.0 speedup typically signifies a failure in the performance test)\n" 932*da0073e9SAndroid Build Coastguard Worker " - compilation latency > 120 sec.\n" 933*da0073e9SAndroid Build Coastguard Worker " - compression ratio < 0.9\n" 934*da0073e9SAndroid Build Coastguard Worker "\n" 935*da0073e9SAndroid Build Coastguard Worker ) 936*da0073e9SAndroid Build Coastguard Worker for metric in [ 937*da0073e9SAndroid Build Coastguard Worker "accuracy", 938*da0073e9SAndroid Build Coastguard Worker "speedup", 939*da0073e9SAndroid Build Coastguard Worker "compilation_latency", 940*da0073e9SAndroid Build Coastguard Worker "compression_ratio", 941*da0073e9SAndroid Build Coastguard Worker ]: 942*da0073e9SAndroid Build Coastguard Worker dfs = [] 943*da0073e9SAndroid Build Coastguard Worker for suite in self.suites: 944*da0073e9SAndroid Build Coastguard Worker dfs.append(self.flag_bad_entries(suite, metric, FLAG_FNS[metric])) 945*da0073e9SAndroid Build Coastguard Worker df = pd.concat(dfs, axis=0) 946*da0073e9SAndroid Build Coastguard Worker if df.empty: 947*da0073e9SAndroid Build Coastguard Worker continue 948*da0073e9SAndroid Build Coastguard Worker tabform = tabulate(df, headers="keys", tablefmt="pretty", showindex="never") 949*da0073e9SAndroid Build Coastguard Worker str_io = io.StringIO() 950*da0073e9SAndroid Build Coastguard Worker str_io.write("\n") 951*da0073e9SAndroid Build Coastguard Worker str_io.write(get_metric_title(metric) + " warnings\n") 952*da0073e9SAndroid Build Coastguard Worker str_io.write("~~~\n") 953*da0073e9SAndroid Build Coastguard Worker str_io.write(f"{tabform}\n") 954*da0073e9SAndroid Build Coastguard Worker str_io.write("~~~\n") 955*da0073e9SAndroid Build Coastguard Worker body += str_io.getvalue() 956*da0073e9SAndroid Build Coastguard Worker 957*da0073e9SAndroid Build Coastguard Worker comment = generate_dropdown_comment(title, body) 958*da0073e9SAndroid Build Coastguard Worker return comment 959*da0073e9SAndroid Build Coastguard Worker 960*da0073e9SAndroid Build Coastguard Worker def prepare_message(self, suite): 961*da0073e9SAndroid Build Coastguard Worker title = f"## {suite} suite with {self.dtypes[0]} precision ##" 962*da0073e9SAndroid Build Coastguard Worker body = "" 963*da0073e9SAndroid Build Coastguard Worker for metric in [ 964*da0073e9SAndroid Build Coastguard Worker "speedup", 965*da0073e9SAndroid Build Coastguard Worker "accuracy", 966*da0073e9SAndroid Build Coastguard Worker "compilation_latency", 967*da0073e9SAndroid Build Coastguard Worker "compression_ratio", 968*da0073e9SAndroid Build Coastguard Worker "abs_latency", 969*da0073e9SAndroid Build Coastguard Worker ]: 970*da0073e9SAndroid Build Coastguard Worker df = self.untouched_parsed_frames[suite][metric] 971*da0073e9SAndroid Build Coastguard Worker df = df.drop("dev", axis=1) 972*da0073e9SAndroid Build Coastguard Worker df = df.rename(columns={"batch_size": "bs"}) 973*da0073e9SAndroid Build Coastguard Worker tabform = tabulate(df, headers="keys", tablefmt="pretty", showindex="never") 974*da0073e9SAndroid Build Coastguard Worker str_io = io.StringIO() 975*da0073e9SAndroid Build Coastguard Worker str_io.write("\n") 976*da0073e9SAndroid Build Coastguard Worker str_io.write(get_metric_title(metric) + "\n") 977*da0073e9SAndroid Build Coastguard Worker str_io.write("~~~\n") 978*da0073e9SAndroid Build Coastguard Worker str_io.write(f"{tabform}\n") 979*da0073e9SAndroid Build Coastguard Worker str_io.write("~~~\n") 980*da0073e9SAndroid Build Coastguard Worker body += str_io.getvalue() 981*da0073e9SAndroid Build Coastguard Worker 982*da0073e9SAndroid Build Coastguard Worker comment = generate_dropdown_comment(title, body) 983*da0073e9SAndroid Build Coastguard Worker return comment 984*da0073e9SAndroid Build Coastguard Worker 985*da0073e9SAndroid Build Coastguard Worker def gen_summary_files(self): 986*da0073e9SAndroid Build Coastguard Worker self.generate_executive_summary() 987*da0073e9SAndroid Build Coastguard Worker for suite in self.suites: 988*da0073e9SAndroid Build Coastguard Worker self.plot_graph( 989*da0073e9SAndroid Build Coastguard Worker self.untouched_parsed_frames[suite]["speedup"], 990*da0073e9SAndroid Build Coastguard Worker f"{suite}_{self.dtypes[0]}", 991*da0073e9SAndroid Build Coastguard Worker ) 992*da0073e9SAndroid Build Coastguard Worker 993*da0073e9SAndroid Build Coastguard Worker with open(f"{self.output_dir}/gh_title.txt", "w") as gh_fh: 994*da0073e9SAndroid Build Coastguard Worker str_io = io.StringIO() 995*da0073e9SAndroid Build Coastguard Worker str_io.write("\n") 996*da0073e9SAndroid Build Coastguard Worker str_io.write(f"# Performance Dashboard for {self.dtypes[0]} precision ##\n") 997*da0073e9SAndroid Build Coastguard Worker str_io.write("\n") 998*da0073e9SAndroid Build Coastguard Worker gh_fh.write(str_io.getvalue()) 999*da0073e9SAndroid Build Coastguard Worker 1000*da0073e9SAndroid Build Coastguard Worker with open(f"{self.output_dir}/gh_executive_summary.txt", "w") as gh_fh: 1001*da0073e9SAndroid Build Coastguard Worker gh_fh.write(self.executive_summary) 1002*da0073e9SAndroid Build Coastguard Worker 1003*da0073e9SAndroid Build Coastguard Worker with open(f"{self.output_dir}/gh_warnings.txt", "w") as gh_fh: 1004*da0073e9SAndroid Build Coastguard Worker warnings_body = self.generate_warnings() 1005*da0073e9SAndroid Build Coastguard Worker gh_fh.write(warnings_body) 1006*da0073e9SAndroid Build Coastguard Worker 1007*da0073e9SAndroid Build Coastguard Worker str_io = io.StringIO() 1008*da0073e9SAndroid Build Coastguard Worker for suite in self.suites: 1009*da0073e9SAndroid Build Coastguard Worker str_io.write(self.prepare_message(suite)) 1010*da0073e9SAndroid Build Coastguard Worker str_io.write("\n") 1011*da0073e9SAndroid Build Coastguard Worker with open(f"{self.output_dir}/gh_{self.mode}.txt", "w") as gh_fh: 1012*da0073e9SAndroid Build Coastguard Worker gh_fh.write(str_io.getvalue()) 1013*da0073e9SAndroid Build Coastguard Worker 1014*da0073e9SAndroid Build Coastguard Worker 1015*da0073e9SAndroid Build Coastguard Workerdef parse_logs(args, dtypes, suites, devices, compilers, flag_compilers, output_dir): 1016*da0073e9SAndroid Build Coastguard Worker mode = get_mode(args) 1017*da0073e9SAndroid Build Coastguard Worker build_summary(args) 1018*da0073e9SAndroid Build Coastguard Worker include_slowdowns = args.include_slowdowns 1019*da0073e9SAndroid Build Coastguard Worker 1020*da0073e9SAndroid Build Coastguard Worker parser_class = ParsePerformanceLogs 1021*da0073e9SAndroid Build Coastguard Worker parser = parser_class( 1022*da0073e9SAndroid Build Coastguard Worker suites, 1023*da0073e9SAndroid Build Coastguard Worker devices, 1024*da0073e9SAndroid Build Coastguard Worker dtypes, 1025*da0073e9SAndroid Build Coastguard Worker compilers, 1026*da0073e9SAndroid Build Coastguard Worker flag_compilers, 1027*da0073e9SAndroid Build Coastguard Worker mode, 1028*da0073e9SAndroid Build Coastguard Worker output_dir, 1029*da0073e9SAndroid Build Coastguard Worker include_slowdowns, 1030*da0073e9SAndroid Build Coastguard Worker ) 1031*da0073e9SAndroid Build Coastguard Worker parser.gen_summary_files() 1032*da0073e9SAndroid Build Coastguard Worker return 1033*da0073e9SAndroid Build Coastguard Worker 1034*da0073e9SAndroid Build Coastguard Worker 1035*da0073e9SAndroid Build Coastguard Worker@dataclasses.dataclass 1036*da0073e9SAndroid Build Coastguard Workerclass LogInfo: 1037*da0073e9SAndroid Build Coastguard Worker # Day of the year this log was generated 1038*da0073e9SAndroid Build Coastguard Worker day: str 1039*da0073e9SAndroid Build Coastguard Worker 1040*da0073e9SAndroid Build Coastguard Worker # Directory path where all logs are present 1041*da0073e9SAndroid Build Coastguard Worker dir_path: str 1042*da0073e9SAndroid Build Coastguard Worker 1043*da0073e9SAndroid Build Coastguard Worker 1044*da0073e9SAndroid Build Coastguard Workerdef get_date(log_info): 1045*da0073e9SAndroid Build Coastguard Worker return datetime.strptime(f"{log_info.day}", "%j").strftime("%m-%d") 1046*da0073e9SAndroid Build Coastguard Worker 1047*da0073e9SAndroid Build Coastguard Worker 1048*da0073e9SAndroid Build Coastguard Workerdef find_last_2_with_filenames(lookup_file, dashboard_archive_path, dtype, filenames): 1049*da0073e9SAndroid Build Coastguard Worker df = pd.read_csv(lookup_file, names=("day", "mode", "prec", "path")) 1050*da0073e9SAndroid Build Coastguard Worker df = df[df["mode"] == "performance"] 1051*da0073e9SAndroid Build Coastguard Worker df = df[df["prec"] == dtype] 1052*da0073e9SAndroid Build Coastguard Worker df = df[::-1] 1053*da0073e9SAndroid Build Coastguard Worker last2 = [] 1054*da0073e9SAndroid Build Coastguard Worker for path in df["path"]: 1055*da0073e9SAndroid Build Coastguard Worker output_dir = os.path.join(dashboard_archive_path, path) 1056*da0073e9SAndroid Build Coastguard Worker fullpaths = [ 1057*da0073e9SAndroid Build Coastguard Worker os.path.join(dashboard_archive_path, path, name) for name in filenames 1058*da0073e9SAndroid Build Coastguard Worker ] 1059*da0073e9SAndroid Build Coastguard Worker if all(os.path.exists(fullpath) for fullpath in fullpaths): 1060*da0073e9SAndroid Build Coastguard Worker last2.append(output_dir) 1061*da0073e9SAndroid Build Coastguard Worker if len(last2) >= 2: 1062*da0073e9SAndroid Build Coastguard Worker return last2 1063*da0073e9SAndroid Build Coastguard Worker return None 1064*da0073e9SAndroid Build Coastguard Worker 1065*da0073e9SAndroid Build Coastguard Worker 1066*da0073e9SAndroid Build Coastguard Workerclass SummaryStatDiffer: 1067*da0073e9SAndroid Build Coastguard Worker def __init__(self, args): 1068*da0073e9SAndroid Build Coastguard Worker self.args = args 1069*da0073e9SAndroid Build Coastguard Worker self.lookup_file = os.path.join(self.args.dashboard_archive_path, "lookup.csv") 1070*da0073e9SAndroid Build Coastguard Worker assert os.path.exists(self.lookup_file) 1071*da0073e9SAndroid Build Coastguard Worker 1072*da0073e9SAndroid Build Coastguard Worker def generate_diff(self, last2, filename, caption): 1073*da0073e9SAndroid Build Coastguard Worker df_cur, df_prev = (pd.read_csv(os.path.join(path, filename)) for path in last2) 1074*da0073e9SAndroid Build Coastguard Worker df_merge = df_cur.merge(df_prev, on="Compiler", suffixes=("_cur", "_prev")) 1075*da0073e9SAndroid Build Coastguard Worker data = {col: [] for col in ("compiler", "suite", "prev_value", "cur_value")} 1076*da0073e9SAndroid Build Coastguard Worker for _, row in df_merge.iterrows(): 1077*da0073e9SAndroid Build Coastguard Worker if row["Compiler"] in self.args.flag_compilers: 1078*da0073e9SAndroid Build Coastguard Worker for suite in self.args.suites: 1079*da0073e9SAndroid Build Coastguard Worker if suite + "_prev" not in row or suite + "_cur" not in row: 1080*da0073e9SAndroid Build Coastguard Worker continue 1081*da0073e9SAndroid Build Coastguard Worker data["compiler"].append(row["Compiler"]) 1082*da0073e9SAndroid Build Coastguard Worker data["suite"].append(suite) 1083*da0073e9SAndroid Build Coastguard Worker data["prev_value"].append(row[suite + "_prev"]) 1084*da0073e9SAndroid Build Coastguard Worker data["cur_value"].append(row[suite + "_cur"]) 1085*da0073e9SAndroid Build Coastguard Worker 1086*da0073e9SAndroid Build Coastguard Worker df = pd.DataFrame(data) 1087*da0073e9SAndroid Build Coastguard Worker tabform = tabulate(df, headers="keys", tablefmt="pretty", showindex="never") 1088*da0073e9SAndroid Build Coastguard Worker str_io = io.StringIO() 1089*da0073e9SAndroid Build Coastguard Worker str_io.write("\n") 1090*da0073e9SAndroid Build Coastguard Worker str_io.write(f"{caption}\n") 1091*da0073e9SAndroid Build Coastguard Worker str_io.write("~~~\n") 1092*da0073e9SAndroid Build Coastguard Worker str_io.write(f"{tabform}\n") 1093*da0073e9SAndroid Build Coastguard Worker str_io.write("~~~\n") 1094*da0073e9SAndroid Build Coastguard Worker return str_io.getvalue() 1095*da0073e9SAndroid Build Coastguard Worker 1096*da0073e9SAndroid Build Coastguard Worker def generate_comment(self): 1097*da0073e9SAndroid Build Coastguard Worker title = "## Summary Statistics Diff ##\n" 1098*da0073e9SAndroid Build Coastguard Worker body = ( 1099*da0073e9SAndroid Build Coastguard Worker "For each relevant compiler, we compare the summary statistics " 1100*da0073e9SAndroid Build Coastguard Worker "for the most 2 recent reports that actually run the compiler.\n\n" 1101*da0073e9SAndroid Build Coastguard Worker ) 1102*da0073e9SAndroid Build Coastguard Worker dtype = self.args.dtypes[0] 1103*da0073e9SAndroid Build Coastguard Worker last2 = find_last_2_with_filenames( 1104*da0073e9SAndroid Build Coastguard Worker self.lookup_file, 1105*da0073e9SAndroid Build Coastguard Worker self.args.dashboard_archive_path, 1106*da0073e9SAndroid Build Coastguard Worker dtype, 1107*da0073e9SAndroid Build Coastguard Worker ["geomean.csv", "passrate.csv"], 1108*da0073e9SAndroid Build Coastguard Worker ) 1109*da0073e9SAndroid Build Coastguard Worker 1110*da0073e9SAndroid Build Coastguard Worker if last2 is None: 1111*da0073e9SAndroid Build Coastguard Worker body += "Could not find most 2 recent reports.\n\n" 1112*da0073e9SAndroid Build Coastguard Worker else: 1113*da0073e9SAndroid Build Coastguard Worker for state, path in zip(("Current", "Previous"), last2): 1114*da0073e9SAndroid Build Coastguard Worker body += f"{state} report name: {path}\n\n" 1115*da0073e9SAndroid Build Coastguard Worker body += self.generate_diff(last2, "passrate.csv", "Passrate diff") 1116*da0073e9SAndroid Build Coastguard Worker body += self.generate_diff( 1117*da0073e9SAndroid Build Coastguard Worker last2, "geomean.csv", "Geometric mean speedup diff" 1118*da0073e9SAndroid Build Coastguard Worker ) 1119*da0073e9SAndroid Build Coastguard Worker 1120*da0073e9SAndroid Build Coastguard Worker comment = generate_dropdown_comment(title, body) 1121*da0073e9SAndroid Build Coastguard Worker 1122*da0073e9SAndroid Build Coastguard Worker with open(f"{self.args.output_dir}/gh_summary_diff.txt", "w") as gh_fh: 1123*da0073e9SAndroid Build Coastguard Worker gh_fh.write(comment) 1124*da0073e9SAndroid Build Coastguard Worker 1125*da0073e9SAndroid Build Coastguard Worker 1126*da0073e9SAndroid Build Coastguard Workerclass RegressionDetector: 1127*da0073e9SAndroid Build Coastguard Worker """ 1128*da0073e9SAndroid Build Coastguard Worker Compares the most recent 2 benchmarks to find previously unflagged models 1129*da0073e9SAndroid Build Coastguard Worker that are now flagged. 1130*da0073e9SAndroid Build Coastguard Worker """ 1131*da0073e9SAndroid Build Coastguard Worker 1132*da0073e9SAndroid Build Coastguard Worker def __init__(self, args): 1133*da0073e9SAndroid Build Coastguard Worker self.args = args 1134*da0073e9SAndroid Build Coastguard Worker self.lookup_file = os.path.join(self.args.dashboard_archive_path, "lookup.csv") 1135*da0073e9SAndroid Build Coastguard Worker assert os.path.exists(self.lookup_file) 1136*da0073e9SAndroid Build Coastguard Worker 1137*da0073e9SAndroid Build Coastguard Worker def generate_comment(self): 1138*da0073e9SAndroid Build Coastguard Worker title = "## Recent Regressions ##\n" 1139*da0073e9SAndroid Build Coastguard Worker body = ( 1140*da0073e9SAndroid Build Coastguard Worker "For each relevant compiler, we compare the most recent 2 reports " 1141*da0073e9SAndroid Build Coastguard Worker "(that actually run the compiler) to find previously unflagged " 1142*da0073e9SAndroid Build Coastguard Worker "models that are now flagged as problematic (according to the " 1143*da0073e9SAndroid Build Coastguard Worker "'Warnings' section).\n\n" 1144*da0073e9SAndroid Build Coastguard Worker ) 1145*da0073e9SAndroid Build Coastguard Worker dtype = self.args.dtypes[0] 1146*da0073e9SAndroid Build Coastguard Worker device = self.args.devices[0] 1147*da0073e9SAndroid Build Coastguard Worker for suite in self.args.suites: 1148*da0073e9SAndroid Build Coastguard Worker body += f"### Regressions for {suite} ###\n" 1149*da0073e9SAndroid Build Coastguard Worker last2 = {} 1150*da0073e9SAndroid Build Coastguard Worker 1151*da0073e9SAndroid Build Coastguard Worker for compiler in self.args.flag_compilers: 1152*da0073e9SAndroid Build Coastguard Worker filenames = [ 1153*da0073e9SAndroid Build Coastguard Worker generate_csv_name( 1154*da0073e9SAndroid Build Coastguard Worker self.args, dtype, suite, device, compiler, testing 1155*da0073e9SAndroid Build Coastguard Worker ) 1156*da0073e9SAndroid Build Coastguard Worker for testing in ["performance", "accuracy"] 1157*da0073e9SAndroid Build Coastguard Worker ] 1158*da0073e9SAndroid Build Coastguard Worker compiler_last2 = find_last_2_with_filenames( 1159*da0073e9SAndroid Build Coastguard Worker self.lookup_file, self.args.dashboard_archive_path, dtype, filenames 1160*da0073e9SAndroid Build Coastguard Worker ) 1161*da0073e9SAndroid Build Coastguard Worker if compiler_last2 is not None: 1162*da0073e9SAndroid Build Coastguard Worker last2[compiler] = [ 1163*da0073e9SAndroid Build Coastguard Worker ParsePerformanceLogs( 1164*da0073e9SAndroid Build Coastguard Worker [suite], 1165*da0073e9SAndroid Build Coastguard Worker [device], 1166*da0073e9SAndroid Build Coastguard Worker [dtype], 1167*da0073e9SAndroid Build Coastguard Worker [compiler], 1168*da0073e9SAndroid Build Coastguard Worker [compiler], 1169*da0073e9SAndroid Build Coastguard Worker get_mode(self.args), 1170*da0073e9SAndroid Build Coastguard Worker output_dir, 1171*da0073e9SAndroid Build Coastguard Worker ) 1172*da0073e9SAndroid Build Coastguard Worker for output_dir in compiler_last2 1173*da0073e9SAndroid Build Coastguard Worker ] 1174*da0073e9SAndroid Build Coastguard Worker for state, path in zip(("Current", "Previous"), compiler_last2): 1175*da0073e9SAndroid Build Coastguard Worker body += ( 1176*da0073e9SAndroid Build Coastguard Worker f"{state} report name (compiler: {compiler}, " 1177*da0073e9SAndroid Build Coastguard Worker f"suite: {suite}): {path}\n\n" 1178*da0073e9SAndroid Build Coastguard Worker ) 1179*da0073e9SAndroid Build Coastguard Worker 1180*da0073e9SAndroid Build Coastguard Worker regressions_present = False 1181*da0073e9SAndroid Build Coastguard Worker for metric in [ 1182*da0073e9SAndroid Build Coastguard Worker "accuracy", 1183*da0073e9SAndroid Build Coastguard Worker "speedup", 1184*da0073e9SAndroid Build Coastguard Worker "compilation_latency", 1185*da0073e9SAndroid Build Coastguard Worker "compression_ratio", 1186*da0073e9SAndroid Build Coastguard Worker ]: 1187*da0073e9SAndroid Build Coastguard Worker dfs = [] 1188*da0073e9SAndroid Build Coastguard Worker for compiler in self.args.flag_compilers: 1189*da0073e9SAndroid Build Coastguard Worker if last2[compiler] is None: 1190*da0073e9SAndroid Build Coastguard Worker continue 1191*da0073e9SAndroid Build Coastguard Worker 1192*da0073e9SAndroid Build Coastguard Worker df_cur, df_prev = ( 1193*da0073e9SAndroid Build Coastguard Worker last2[compiler][i].untouched_parsed_frames[suite][metric] 1194*da0073e9SAndroid Build Coastguard Worker for i in (0, 1) 1195*da0073e9SAndroid Build Coastguard Worker ) 1196*da0073e9SAndroid Build Coastguard Worker df_merge = df_cur.merge( 1197*da0073e9SAndroid Build Coastguard Worker df_prev, on="name", suffixes=("_cur", "_prev") 1198*da0073e9SAndroid Build Coastguard Worker ) 1199*da0073e9SAndroid Build Coastguard Worker flag_fn = FLAG_FNS[metric] 1200*da0073e9SAndroid Build Coastguard Worker flag = np.logical_and( 1201*da0073e9SAndroid Build Coastguard Worker df_merge[compiler + "_prev"].apply( 1202*da0073e9SAndroid Build Coastguard Worker lambda x: not pd.isna(x) and not flag_fn(x) 1203*da0073e9SAndroid Build Coastguard Worker ), 1204*da0073e9SAndroid Build Coastguard Worker df_merge[compiler + "_cur"].apply( 1205*da0073e9SAndroid Build Coastguard Worker lambda x: not pd.isna(x) and flag_fn(x) 1206*da0073e9SAndroid Build Coastguard Worker ), 1207*da0073e9SAndroid Build Coastguard Worker ) 1208*da0073e9SAndroid Build Coastguard Worker df_bad = df_merge[flag] 1209*da0073e9SAndroid Build Coastguard Worker dfs.append( 1210*da0073e9SAndroid Build Coastguard Worker pd.DataFrame( 1211*da0073e9SAndroid Build Coastguard Worker data={ 1212*da0073e9SAndroid Build Coastguard Worker "compiler": compiler, 1213*da0073e9SAndroid Build Coastguard Worker "name": df_bad["name"], 1214*da0073e9SAndroid Build Coastguard Worker "prev_status": df_bad[compiler + "_prev"], 1215*da0073e9SAndroid Build Coastguard Worker "cur_status": df_bad[compiler + "_cur"], 1216*da0073e9SAndroid Build Coastguard Worker } 1217*da0073e9SAndroid Build Coastguard Worker ) 1218*da0073e9SAndroid Build Coastguard Worker ) 1219*da0073e9SAndroid Build Coastguard Worker 1220*da0073e9SAndroid Build Coastguard Worker if not dfs: 1221*da0073e9SAndroid Build Coastguard Worker continue 1222*da0073e9SAndroid Build Coastguard Worker df = pd.concat(dfs, axis=0) 1223*da0073e9SAndroid Build Coastguard Worker if df.empty: 1224*da0073e9SAndroid Build Coastguard Worker continue 1225*da0073e9SAndroid Build Coastguard Worker regressions_present = True 1226*da0073e9SAndroid Build Coastguard Worker tabform = tabulate( 1227*da0073e9SAndroid Build Coastguard Worker df, headers="keys", tablefmt="pretty", showindex="never" 1228*da0073e9SAndroid Build Coastguard Worker ) 1229*da0073e9SAndroid Build Coastguard Worker str_io = io.StringIO() 1230*da0073e9SAndroid Build Coastguard Worker str_io.write("\n") 1231*da0073e9SAndroid Build Coastguard Worker str_io.write(f"{get_metric_title(metric)} regressions\n") 1232*da0073e9SAndroid Build Coastguard Worker str_io.write("~~~\n") 1233*da0073e9SAndroid Build Coastguard Worker str_io.write(f"{tabform}\n") 1234*da0073e9SAndroid Build Coastguard Worker str_io.write("~~~\n") 1235*da0073e9SAndroid Build Coastguard Worker body += str_io.getvalue() 1236*da0073e9SAndroid Build Coastguard Worker 1237*da0073e9SAndroid Build Coastguard Worker if not regressions_present: 1238*da0073e9SAndroid Build Coastguard Worker body += "No regressions found.\n" 1239*da0073e9SAndroid Build Coastguard Worker 1240*da0073e9SAndroid Build Coastguard Worker comment = generate_dropdown_comment(title, body) 1241*da0073e9SAndroid Build Coastguard Worker 1242*da0073e9SAndroid Build Coastguard Worker with open(f"{self.args.output_dir}/gh_metric_regression.txt", "w") as gh_fh: 1243*da0073e9SAndroid Build Coastguard Worker gh_fh.write(comment) 1244*da0073e9SAndroid Build Coastguard Worker 1245*da0073e9SAndroid Build Coastguard Worker 1246*da0073e9SAndroid Build Coastguard Workerclass RegressionTracker: 1247*da0073e9SAndroid Build Coastguard Worker """ 1248*da0073e9SAndroid Build Coastguard Worker Plots progress of different metrics over time to detect regressions. 1249*da0073e9SAndroid Build Coastguard Worker """ 1250*da0073e9SAndroid Build Coastguard Worker 1251*da0073e9SAndroid Build Coastguard Worker def __init__(self, args): 1252*da0073e9SAndroid Build Coastguard Worker self.args = args 1253*da0073e9SAndroid Build Coastguard Worker self.suites = self.args.suites 1254*da0073e9SAndroid Build Coastguard Worker self.lookup_file = os.path.join(self.args.dashboard_archive_path, "lookup.csv") 1255*da0073e9SAndroid Build Coastguard Worker assert os.path.exists(self.lookup_file) 1256*da0073e9SAndroid Build Coastguard Worker self.k = 10 1257*da0073e9SAndroid Build Coastguard Worker 1258*da0073e9SAndroid Build Coastguard Worker def find_last_k(self): 1259*da0073e9SAndroid Build Coastguard Worker """ 1260*da0073e9SAndroid Build Coastguard Worker Find the last k pairs of (day number, log_path) 1261*da0073e9SAndroid Build Coastguard Worker """ 1262*da0073e9SAndroid Build Coastguard Worker dtype = self.args.dtypes[0] 1263*da0073e9SAndroid Build Coastguard Worker df = pd.read_csv(self.lookup_file, names=("day", "mode", "prec", "path")) 1264*da0073e9SAndroid Build Coastguard Worker df = df[df["mode"] == "performance"] 1265*da0073e9SAndroid Build Coastguard Worker df = df[df["prec"] == dtype] 1266*da0073e9SAndroid Build Coastguard Worker log_infos = [] 1267*da0073e9SAndroid Build Coastguard Worker for day, path in zip(df["day"], df["path"]): 1268*da0073e9SAndroid Build Coastguard Worker log_infos.append(LogInfo(day, path)) 1269*da0073e9SAndroid Build Coastguard Worker 1270*da0073e9SAndroid Build Coastguard Worker assert len(log_infos) >= self.k 1271*da0073e9SAndroid Build Coastguard Worker log_infos = log_infos[len(log_infos) - self.k :] 1272*da0073e9SAndroid Build Coastguard Worker return log_infos 1273*da0073e9SAndroid Build Coastguard Worker 1274*da0073e9SAndroid Build Coastguard Worker def generate_comment(self): 1275*da0073e9SAndroid Build Coastguard Worker title = "## Metrics over time ##\n" 1276*da0073e9SAndroid Build Coastguard Worker str_io = io.StringIO() 1277*da0073e9SAndroid Build Coastguard Worker if not self.args.update_dashboard_test and not self.args.no_graphs: 1278*da0073e9SAndroid Build Coastguard Worker for name in glob.glob(self.args.output_dir + "/*over_time.png"): 1279*da0073e9SAndroid Build Coastguard Worker output = ( 1280*da0073e9SAndroid Build Coastguard Worker subprocess.check_output([self.args.dashboard_image_uploader, name]) 1281*da0073e9SAndroid Build Coastguard Worker .decode("ascii") 1282*da0073e9SAndroid Build Coastguard Worker .rstrip() 1283*da0073e9SAndroid Build Coastguard Worker ) 1284*da0073e9SAndroid Build Coastguard Worker str_io.write(f"\n{name} : \n") 1285*da0073e9SAndroid Build Coastguard Worker comment = generate_dropdown_comment(title, str_io.getvalue()) 1286*da0073e9SAndroid Build Coastguard Worker 1287*da0073e9SAndroid Build Coastguard Worker with open(f"{self.args.output_dir}/gh_regression.txt", "w") as gh_fh: 1288*da0073e9SAndroid Build Coastguard Worker gh_fh.write(comment) 1289*da0073e9SAndroid Build Coastguard Worker 1290*da0073e9SAndroid Build Coastguard Worker def diff(self): 1291*da0073e9SAndroid Build Coastguard Worker log_infos = self.find_last_k() 1292*da0073e9SAndroid Build Coastguard Worker 1293*da0073e9SAndroid Build Coastguard Worker for metric in ["geomean", "passrate", "comp_time", "memory"]: 1294*da0073e9SAndroid Build Coastguard Worker fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(15, 5)) 1295*da0073e9SAndroid Build Coastguard Worker for idx, suite in enumerate(self.suites): 1296*da0073e9SAndroid Build Coastguard Worker dfs = [] 1297*da0073e9SAndroid Build Coastguard Worker for log_info in log_infos: 1298*da0073e9SAndroid Build Coastguard Worker dir_path = os.path.join( 1299*da0073e9SAndroid Build Coastguard Worker self.args.dashboard_archive_path, log_info.dir_path 1300*da0073e9SAndroid Build Coastguard Worker ) 1301*da0073e9SAndroid Build Coastguard Worker assert os.path.exists(dir_path) 1302*da0073e9SAndroid Build Coastguard Worker gmean_filename = os.path.join(dir_path, f"{metric}.csv") 1303*da0073e9SAndroid Build Coastguard Worker if not os.path.exists(gmean_filename): 1304*da0073e9SAndroid Build Coastguard Worker continue 1305*da0073e9SAndroid Build Coastguard Worker df = pd.read_csv(gmean_filename) 1306*da0073e9SAndroid Build Coastguard Worker if suite not in df: 1307*da0073e9SAndroid Build Coastguard Worker continue 1308*da0073e9SAndroid Build Coastguard Worker if metric == "geomean" or metric == "memory": 1309*da0073e9SAndroid Build Coastguard Worker df[suite] = df[suite].str.replace("x", "").astype(float) 1310*da0073e9SAndroid Build Coastguard Worker elif metric == "passrate": 1311*da0073e9SAndroid Build Coastguard Worker df[suite] = df[suite].str.split("%").str[0].astype(float) 1312*da0073e9SAndroid Build Coastguard Worker df.insert(0, "day", get_date(log_info)) 1313*da0073e9SAndroid Build Coastguard Worker df = df.pivot(index="day", columns="Compiler", values=suite) 1314*da0073e9SAndroid Build Coastguard Worker 1315*da0073e9SAndroid Build Coastguard Worker # Interim stage when both inductor_cudagraphs and inductor exist 1316*da0073e9SAndroid Build Coastguard Worker df = df.rename(columns={"inductor_cudagraphs": "inductor"}) 1317*da0073e9SAndroid Build Coastguard Worker for col_name in df.columns: 1318*da0073e9SAndroid Build Coastguard Worker if col_name not in self.args.compilers: 1319*da0073e9SAndroid Build Coastguard Worker df = df.drop(columns=[col_name]) 1320*da0073e9SAndroid Build Coastguard Worker dfs.append(df) 1321*da0073e9SAndroid Build Coastguard Worker 1322*da0073e9SAndroid Build Coastguard Worker df = pd.concat(dfs) 1323*da0073e9SAndroid Build Coastguard Worker df = df.interpolate(method="linear") 1324*da0073e9SAndroid Build Coastguard Worker ax = df.plot( 1325*da0073e9SAndroid Build Coastguard Worker ax=axes[idx], 1326*da0073e9SAndroid Build Coastguard Worker kind="line", 1327*da0073e9SAndroid Build Coastguard Worker ylabel=metric, 1328*da0073e9SAndroid Build Coastguard Worker xlabel="Date", 1329*da0073e9SAndroid Build Coastguard Worker grid=True, 1330*da0073e9SAndroid Build Coastguard Worker ylim=0 if metric == "passrate" else 0.8, 1331*da0073e9SAndroid Build Coastguard Worker title=suite, 1332*da0073e9SAndroid Build Coastguard Worker style=".-", 1333*da0073e9SAndroid Build Coastguard Worker legend=False, 1334*da0073e9SAndroid Build Coastguard Worker ) 1335*da0073e9SAndroid Build Coastguard Worker ax.legend(loc="lower right", ncol=2) 1336*da0073e9SAndroid Build Coastguard Worker 1337*da0073e9SAndroid Build Coastguard Worker plt.tight_layout() 1338*da0073e9SAndroid Build Coastguard Worker plt.savefig(os.path.join(output_dir, f"{metric}_over_time.png")) 1339*da0073e9SAndroid Build Coastguard Worker 1340*da0073e9SAndroid Build Coastguard Worker self.generate_comment() 1341*da0073e9SAndroid Build Coastguard Worker 1342*da0073e9SAndroid Build Coastguard Worker 1343*da0073e9SAndroid Build Coastguard Workerclass DashboardUpdater: 1344*da0073e9SAndroid Build Coastguard Worker """ 1345*da0073e9SAndroid Build Coastguard Worker Aggregates the information and makes a comment to Performance Dashboard. 1346*da0073e9SAndroid Build Coastguard Worker https://github.com/pytorch/torchdynamo/issues/681 1347*da0073e9SAndroid Build Coastguard Worker """ 1348*da0073e9SAndroid Build Coastguard Worker 1349*da0073e9SAndroid Build Coastguard Worker def __init__(self, args): 1350*da0073e9SAndroid Build Coastguard Worker self.args = args 1351*da0073e9SAndroid Build Coastguard Worker self.output_dir = args.output_dir 1352*da0073e9SAndroid Build Coastguard Worker self.lookup_file = os.path.join(self.args.dashboard_archive_path, "lookup.csv") 1353*da0073e9SAndroid Build Coastguard Worker assert os.path.exists(self.lookup_file) 1354*da0073e9SAndroid Build Coastguard Worker try: 1355*da0073e9SAndroid Build Coastguard Worker if not self.args.update_dashboard_test and not self.args.no_update_archive: 1356*da0073e9SAndroid Build Coastguard Worker self.update_lookup_file() 1357*da0073e9SAndroid Build Coastguard Worker except subprocess.CalledProcessError: 1358*da0073e9SAndroid Build Coastguard Worker sys.stderr.write("failed to update lookup file\n") 1359*da0073e9SAndroid Build Coastguard Worker 1360*da0073e9SAndroid Build Coastguard Worker def update_lookup_file(self): 1361*da0073e9SAndroid Build Coastguard Worker dtype = self.args.dtypes[0] 1362*da0073e9SAndroid Build Coastguard Worker day, _ = archive_data(self.args.archive_name) 1363*da0073e9SAndroid Build Coastguard Worker target_dir = get_archive_name(self.args, dtype) 1364*da0073e9SAndroid Build Coastguard Worker # Update lookup csv the folder to arhived logs 1365*da0073e9SAndroid Build Coastguard Worker subprocess.check_call( 1366*da0073e9SAndroid Build Coastguard Worker f'echo "{day},performance,{dtype},{target_dir}" >> {self.lookup_file}', 1367*da0073e9SAndroid Build Coastguard Worker shell=True, 1368*da0073e9SAndroid Build Coastguard Worker ) 1369*da0073e9SAndroid Build Coastguard Worker 1370*da0073e9SAndroid Build Coastguard Worker def archive(self): 1371*da0073e9SAndroid Build Coastguard Worker dtype = self.args.dtypes[0] 1372*da0073e9SAndroid Build Coastguard Worker # Copy the folder to archived location 1373*da0073e9SAndroid Build Coastguard Worker archive( 1374*da0073e9SAndroid Build Coastguard Worker self.output_dir, 1375*da0073e9SAndroid Build Coastguard Worker self.args.dashboard_archive_path, 1376*da0073e9SAndroid Build Coastguard Worker self.args.archive_name, 1377*da0073e9SAndroid Build Coastguard Worker dtype, 1378*da0073e9SAndroid Build Coastguard Worker ) 1379*da0073e9SAndroid Build Coastguard Worker 1380*da0073e9SAndroid Build Coastguard Worker def upload_graphs(self): 1381*da0073e9SAndroid Build Coastguard Worker title = "## Performance graphs ##\n" 1382*da0073e9SAndroid Build Coastguard Worker str_io = io.StringIO() 1383*da0073e9SAndroid Build Coastguard Worker if not self.args.update_dashboard_test and not self.args.no_graphs: 1384*da0073e9SAndroid Build Coastguard Worker for name in glob.glob(self.output_dir + "/*png"): 1385*da0073e9SAndroid Build Coastguard Worker if "over_time" not in name: 1386*da0073e9SAndroid Build Coastguard Worker output = ( 1387*da0073e9SAndroid Build Coastguard Worker subprocess.check_output( 1388*da0073e9SAndroid Build Coastguard Worker [self.args.dashboard_image_uploader, name] 1389*da0073e9SAndroid Build Coastguard Worker ) 1390*da0073e9SAndroid Build Coastguard Worker .decode("ascii") 1391*da0073e9SAndroid Build Coastguard Worker .rstrip() 1392*da0073e9SAndroid Build Coastguard Worker ) 1393*da0073e9SAndroid Build Coastguard Worker str_io.write(f"\n{name} : \n") 1394*da0073e9SAndroid Build Coastguard Worker comment = generate_dropdown_comment(title, str_io.getvalue()) 1395*da0073e9SAndroid Build Coastguard Worker 1396*da0073e9SAndroid Build Coastguard Worker with open(f"{self.output_dir}/gh_graphs.txt", "w") as gh_fh: 1397*da0073e9SAndroid Build Coastguard Worker gh_fh.write(comment) 1398*da0073e9SAndroid Build Coastguard Worker 1399*da0073e9SAndroid Build Coastguard Worker def gen_comment(self): 1400*da0073e9SAndroid Build Coastguard Worker files = [ 1401*da0073e9SAndroid Build Coastguard Worker "gh_title.txt", 1402*da0073e9SAndroid Build Coastguard Worker "gh_executive_summary.txt", 1403*da0073e9SAndroid Build Coastguard Worker "gh_summary_diff.txt", 1404*da0073e9SAndroid Build Coastguard Worker "gh_warnings.txt", 1405*da0073e9SAndroid Build Coastguard Worker "gh_regression.txt", 1406*da0073e9SAndroid Build Coastguard Worker "gh_metric_regression.txt", 1407*da0073e9SAndroid Build Coastguard Worker "gh_training.txt" if self.args.training else "gh_inference.txt", 1408*da0073e9SAndroid Build Coastguard Worker "gh_graphs.txt", 1409*da0073e9SAndroid Build Coastguard Worker "gh_build_summary.txt", 1410*da0073e9SAndroid Build Coastguard Worker ] 1411*da0073e9SAndroid Build Coastguard Worker all_lines = [] 1412*da0073e9SAndroid Build Coastguard Worker for f in files: 1413*da0073e9SAndroid Build Coastguard Worker try: 1414*da0073e9SAndroid Build Coastguard Worker with open(os.path.join(self.output_dir, f)) as fh: 1415*da0073e9SAndroid Build Coastguard Worker all_lines.extend(fh.readlines()) 1416*da0073e9SAndroid Build Coastguard Worker except FileNotFoundError: 1417*da0073e9SAndroid Build Coastguard Worker pass 1418*da0073e9SAndroid Build Coastguard Worker 1419*da0073e9SAndroid Build Coastguard Worker return "\n".join([x.rstrip() for x in all_lines]) 1420*da0073e9SAndroid Build Coastguard Worker 1421*da0073e9SAndroid Build Coastguard Worker def comment_on_gh(self, comment): 1422*da0073e9SAndroid Build Coastguard Worker """ 1423*da0073e9SAndroid Build Coastguard Worker Send a commment to dashboard 1424*da0073e9SAndroid Build Coastguard Worker """ 1425*da0073e9SAndroid Build Coastguard Worker with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: 1426*da0073e9SAndroid Build Coastguard Worker f.write(comment) 1427*da0073e9SAndroid Build Coastguard Worker filename = f.name 1428*da0073e9SAndroid Build Coastguard Worker 1429*da0073e9SAndroid Build Coastguard Worker issue_number = "93794" 1430*da0073e9SAndroid Build Coastguard Worker if self.args.dtypes[0] == "float32": 1431*da0073e9SAndroid Build Coastguard Worker issue_number = "93518" 1432*da0073e9SAndroid Build Coastguard Worker 1433*da0073e9SAndroid Build Coastguard Worker subprocess.check_call( 1434*da0073e9SAndroid Build Coastguard Worker [ 1435*da0073e9SAndroid Build Coastguard Worker self.args.dashboard_gh_cli_path, 1436*da0073e9SAndroid Build Coastguard Worker "issue", 1437*da0073e9SAndroid Build Coastguard Worker "comment", 1438*da0073e9SAndroid Build Coastguard Worker "--repo=https://github.com/pytorch/pytorch.git", 1439*da0073e9SAndroid Build Coastguard Worker issue_number, 1440*da0073e9SAndroid Build Coastguard Worker "-F", 1441*da0073e9SAndroid Build Coastguard Worker filename, 1442*da0073e9SAndroid Build Coastguard Worker ] 1443*da0073e9SAndroid Build Coastguard Worker ) 1444*da0073e9SAndroid Build Coastguard Worker 1445*da0073e9SAndroid Build Coastguard Worker os.remove(filename) 1446*da0073e9SAndroid Build Coastguard Worker 1447*da0073e9SAndroid Build Coastguard Worker def update(self): 1448*da0073e9SAndroid Build Coastguard Worker self.upload_graphs() 1449*da0073e9SAndroid Build Coastguard Worker if not self.args.no_detect_regressions: 1450*da0073e9SAndroid Build Coastguard Worker SummaryStatDiffer(self.args).generate_comment() 1451*da0073e9SAndroid Build Coastguard Worker RegressionDetector(self.args).generate_comment() 1452*da0073e9SAndroid Build Coastguard Worker try: 1453*da0073e9SAndroid Build Coastguard Worker RegressionTracker(self.args).diff() 1454*da0073e9SAndroid Build Coastguard Worker except Exception as e: 1455*da0073e9SAndroid Build Coastguard Worker logging.exception("") 1456*da0073e9SAndroid Build Coastguard Worker with open(f"{self.args.output_dir}/gh_regression.txt", "w") as gh_fh: 1457*da0073e9SAndroid Build Coastguard Worker gh_fh.write("") 1458*da0073e9SAndroid Build Coastguard Worker 1459*da0073e9SAndroid Build Coastguard Worker comment = self.gen_comment() 1460*da0073e9SAndroid Build Coastguard Worker print(comment) 1461*da0073e9SAndroid Build Coastguard Worker 1462*da0073e9SAndroid Build Coastguard Worker if not self.args.update_dashboard_test: 1463*da0073e9SAndroid Build Coastguard Worker if not self.args.no_gh_comment: 1464*da0073e9SAndroid Build Coastguard Worker self.comment_on_gh(comment) 1465*da0073e9SAndroid Build Coastguard Worker if not self.args.no_update_archive: 1466*da0073e9SAndroid Build Coastguard Worker self.archive() 1467*da0073e9SAndroid Build Coastguard Worker 1468*da0073e9SAndroid Build Coastguard Worker 1469*da0073e9SAndroid Build Coastguard Workerif __name__ == "__main__": 1470*da0073e9SAndroid Build Coastguard Worker args = parse_args() 1471*da0073e9SAndroid Build Coastguard Worker 1472*da0073e9SAndroid Build Coastguard Worker def extract(key): 1473*da0073e9SAndroid Build Coastguard Worker return DEFAULTS[key] if getattr(args, key, None) is None else getattr(args, key) 1474*da0073e9SAndroid Build Coastguard Worker 1475*da0073e9SAndroid Build Coastguard Worker dtypes = extract("dtypes") 1476*da0073e9SAndroid Build Coastguard Worker suites = extract("suites") 1477*da0073e9SAndroid Build Coastguard Worker devices = extract("devices") 1478*da0073e9SAndroid Build Coastguard Worker 1479*da0073e9SAndroid Build Coastguard Worker if args.inference: 1480*da0073e9SAndroid Build Coastguard Worker compilers = DEFAULTS["inference"] if args.compilers is None else args.compilers 1481*da0073e9SAndroid Build Coastguard Worker flag_compilers = ( 1482*da0073e9SAndroid Build Coastguard Worker DEFAULTS["flag_compilers"]["inference"] 1483*da0073e9SAndroid Build Coastguard Worker if args.flag_compilers is None 1484*da0073e9SAndroid Build Coastguard Worker else args.flag_compilers 1485*da0073e9SAndroid Build Coastguard Worker ) 1486*da0073e9SAndroid Build Coastguard Worker else: 1487*da0073e9SAndroid Build Coastguard Worker assert args.training 1488*da0073e9SAndroid Build Coastguard Worker compilers = DEFAULTS["training"] if args.compilers is None else args.compilers 1489*da0073e9SAndroid Build Coastguard Worker flag_compilers = ( 1490*da0073e9SAndroid Build Coastguard Worker DEFAULTS["flag_compilers"]["training"] 1491*da0073e9SAndroid Build Coastguard Worker if args.flag_compilers is None 1492*da0073e9SAndroid Build Coastguard Worker else args.flag_compilers 1493*da0073e9SAndroid Build Coastguard Worker ) 1494*da0073e9SAndroid Build Coastguard Worker 1495*da0073e9SAndroid Build Coastguard Worker output_dir = args.output_dir 1496*da0073e9SAndroid Build Coastguard Worker args.compilers = compilers 1497*da0073e9SAndroid Build Coastguard Worker args.devices = devices 1498*da0073e9SAndroid Build Coastguard Worker args.dtypes = dtypes 1499*da0073e9SAndroid Build Coastguard Worker flag_compilers = list(set(flag_compilers) & set(compilers)) 1500*da0073e9SAndroid Build Coastguard Worker args.flag_compilers = flag_compilers 1501*da0073e9SAndroid Build Coastguard Worker args.suites = suites 1502*da0073e9SAndroid Build Coastguard Worker 1503*da0073e9SAndroid Build Coastguard Worker if args.print_run_commands: 1504*da0073e9SAndroid Build Coastguard Worker generated_file = generate_commands( 1505*da0073e9SAndroid Build Coastguard Worker args, dtypes, suites, devices, compilers, output_dir 1506*da0073e9SAndroid Build Coastguard Worker ) 1507*da0073e9SAndroid Build Coastguard Worker print( 1508*da0073e9SAndroid Build Coastguard Worker f"Running commands are generated in file {generated_file}. Please run (bash {generated_file})." 1509*da0073e9SAndroid Build Coastguard Worker ) 1510*da0073e9SAndroid Build Coastguard Worker elif args.visualize_logs: 1511*da0073e9SAndroid Build Coastguard Worker parse_logs(args, dtypes, suites, devices, compilers, flag_compilers, output_dir) 1512*da0073e9SAndroid Build Coastguard Worker elif args.run: 1513*da0073e9SAndroid Build Coastguard Worker generated_file = generate_commands( 1514*da0073e9SAndroid Build Coastguard Worker args, dtypes, suites, devices, compilers, output_dir 1515*da0073e9SAndroid Build Coastguard Worker ) 1516*da0073e9SAndroid Build Coastguard Worker # generate memoized archive name now so that the date is reflective 1517*da0073e9SAndroid Build Coastguard Worker # of when the run started 1518*da0073e9SAndroid Build Coastguard Worker get_archive_name(args, dtypes[0]) 1519*da0073e9SAndroid Build Coastguard Worker # TODO - Do we need to worry about segfaults 1520*da0073e9SAndroid Build Coastguard Worker try: 1521*da0073e9SAndroid Build Coastguard Worker os.system(f"bash {generated_file}") 1522*da0073e9SAndroid Build Coastguard Worker except Exception as e: 1523*da0073e9SAndroid Build Coastguard Worker print( 1524*da0073e9SAndroid Build Coastguard Worker f"Running commands failed. Please run manually (bash {generated_file}) and inspect the errors." 1525*da0073e9SAndroid Build Coastguard Worker ) 1526*da0073e9SAndroid Build Coastguard Worker raise e 1527*da0073e9SAndroid Build Coastguard Worker if not args.log_operator_inputs: 1528*da0073e9SAndroid Build Coastguard Worker if not args.no_update_archive: 1529*da0073e9SAndroid Build Coastguard Worker archive( 1530*da0073e9SAndroid Build Coastguard Worker output_dir, 1531*da0073e9SAndroid Build Coastguard Worker args.dashboard_archive_path, 1532*da0073e9SAndroid Build Coastguard Worker args.archive_name, 1533*da0073e9SAndroid Build Coastguard Worker dtypes[0], 1534*da0073e9SAndroid Build Coastguard Worker ) 1535*da0073e9SAndroid Build Coastguard Worker parse_logs( 1536*da0073e9SAndroid Build Coastguard Worker args, dtypes, suites, devices, compilers, flag_compilers, output_dir 1537*da0073e9SAndroid Build Coastguard Worker ) 1538*da0073e9SAndroid Build Coastguard Worker if not args.no_update_archive: 1539*da0073e9SAndroid Build Coastguard Worker archive( 1540*da0073e9SAndroid Build Coastguard Worker output_dir, 1541*da0073e9SAndroid Build Coastguard Worker args.dashboard_archive_path, 1542*da0073e9SAndroid Build Coastguard Worker args.archive_name, 1543*da0073e9SAndroid Build Coastguard Worker dtypes[0], 1544*da0073e9SAndroid Build Coastguard Worker ) 1545*da0073e9SAndroid Build Coastguard Worker 1546*da0073e9SAndroid Build Coastguard Worker if args.update_dashboard: 1547*da0073e9SAndroid Build Coastguard Worker DashboardUpdater(args).update() 1548