From a86486ab7fb3e718f88ee419509b395d2c01692d Mon Sep 17 00:00:00 2001 From: shahasad <43590019+shahasad@users.noreply.github.com> Date: Tue, 30 Jul 2019 08:59:43 -0700 Subject: [PATCH] Post binary sizes to dashboard database (#1517) Python script and necessary changes in the azure-pipelines yaml file to post the binary size data from NuGet package build. Currently only posted from CPU pipeline. GPU and other pipelines may be added as necessary. --- .../azure-pipelines/nuget/templates/cpu.yml | 23 ++++ ...upload-binary-sizes-from-nuget-package.yml | 48 ++++++++ .../set-version-number-variables-step.yml | 7 ++ .../azure-pipelines/templates/win-ci.yml | 2 + .../windows/post_binary_sizes_to_dashboard.py | 110 ++++++++++++++++++ 5 files changed, 190 insertions(+) create mode 100644 tools/ci_build/github/azure-pipelines/nuget/templates/upload-binary-sizes-from-nuget-package.yml create mode 100644 tools/ci_build/github/windows/post_binary_sizes_to_dashboard.py diff --git a/tools/ci_build/github/azure-pipelines/nuget/templates/cpu.yml b/tools/ci_build/github/azure-pipelines/nuget/templates/cpu.yml index 93c94f35b6..dca49ee42d 100644 --- a/tools/ci_build/github/azure-pipelines/nuget/templates/cpu.yml +++ b/tools/ci_build/github/azure-pipelines/nuget/templates/cpu.yml @@ -100,6 +100,7 @@ jobs: - MacOS_CI_Dev condition: succeeded() steps: + - task: DownloadPipelineArtifact@0 displayName: 'Download Pipeline Artifact - NuGet' inputs: @@ -107,6 +108,7 @@ jobs: targetPath: '$(Build.BinariesDirectory)/nuget-artifact' continueOnError: true + - task: DownloadPipelineArtifact@0 displayName: 'Download Pipeline Artifact - Win-x86' inputs: @@ -150,4 +152,25 @@ jobs: artifactName: 'drop-signed-nuget' targetPath: '$(Build.ArtifactStagingDirectory)' + - template: test_all_os.yml + +- job: Publish_NuGet_Package_And_Report + variables: + - group: Dashboard_MySQL_Secret + condition: ${{ parameters.DoEsrp }} + pool: + name: Hosted Windows 2019 with VS2019 + demands: azureps + dependsOn: + - NuGet_Test_Win + - NuGet_Test_Linux + - NuGet_Test_MacOS + steps: + + - template: ../../templates/set-version-number-variables-step.yml + - template: upload-binary-sizes-from-nuget-package.yml + parameters: + gitCommitHash: $(OnnxRuntimeGitCommitHashShort) + + diff --git a/tools/ci_build/github/azure-pipelines/nuget/templates/upload-binary-sizes-from-nuget-package.yml b/tools/ci_build/github/azure-pipelines/nuget/templates/upload-binary-sizes-from-nuget-package.yml new file mode 100644 index 0000000000..55e1813951 --- /dev/null +++ b/tools/ci_build/github/azure-pipelines/nuget/templates/upload-binary-sizes-from-nuget-package.yml @@ -0,0 +1,48 @@ +parameters: + gitCommitHash: '' + +steps: +- task: DownloadPipelineArtifact@0 + displayName: 'Download Pipeline Artifact - Signed NuGet Package' + inputs: + artifactName: 'drop-signed-nuget' + targetPath: '$(Build.BinariesDirectory)/nuget-artifact/final-package' + +- task: UsePythonVersion@0 + inputs: + versionSpec: '3.7' + addToPath: true + architecture: 'x64' + +- task: CmdLine@1 + displayName: 'Install conda modules mysql-connector-python' + inputs: + filename: '%CONDA%\condabin\conda.bat' + arguments: 'install -q --insecure -y mysql-connector-python' + timeoutInMinutes: 10 + +- task: CmdLine@2 + displayName: 'Post binary sizes to the dashboard database using command line' + inputs: + script: | + echo changing directory to artifact download path + pushd $(Build.BinariesDirectory)\nuget-artifact\final-package + echo processing nupkg + FOR /R %%i IN (*.nupkg) do ( + echo processing %%~ni.nupkg + copy %%~ni.nupkg %%~ni.zip + echo copied to zip + echo listing lib files in the zip + REM use a single .csv file to put the data + echo os,arch,build_config,size > binary_size_data.txt + 7z.exe l -slt %%~ni.zip runtimes\linux-x64\native\libonnxruntime.so | findstr /R /C:"^Size = [0-9]*" | for /F "tokens=3" %%a in ('more') do if not "%%a" == "" echo linux,x64,openmp,%%a >> binary_size_data.txt + 7z.exe l -slt %%~ni.zip runtimes\linux-x86\native\libonnxruntime.so | findstr /R /C:"^Size = [0-9]*" | for /F "tokens=3" %%a in ('more') do if not "%%a" == "" echo linux,x86,openmp,%%a >> binary_size_data.txt + 7z.exe l -slt %%~ni.zip runtimes\osx-x64\native\libonnxruntime.dylib | findstr /R /C:"^Size = [0-9]*" | for /F "tokens=3" %%a in ('more') do if not "%%a" == "" echo osx,x64,openmp,%%a >> binary_size_data.txt + 7z.exe l -slt %%~ni.zip runtimes\win-x64\native\onnxruntime.dll | findstr /R /C:"^Size = [0-9]*" | for /F "tokens=3" %%a in ('more') do if not "%%a" == "" echo win,x64,openmp,%%a >> binary_size_data.txt + 7z.exe l -slt %%~ni.zip runtimes\win-x86\native\onnxruntime.dll | findstr /R /C:"^Size = [0-9]*" | for /F "tokens=3" %%a in ('more') do if not "%%a" == "" echo win,x86,openmp,%%a >> binary_size_data.txt + echo calling python script to post to database + %CONDA%\python.exe $(Build.SourcesDirectory)\tools\ci_build\github\windows\post_binary_sizes_to_dashboard.py --commit_hash=${{ parameters.gitCommitHash }} --size_data_file=binary_size_data.txt --build_project=Lotus --build_id=$(Build.BuildId) + ) + + env: + DASHBOARD_MYSQL_ORT_PASSWORD: $(dashboard-mysql-ort-password) diff --git a/tools/ci_build/github/azure-pipelines/templates/set-version-number-variables-step.yml b/tools/ci_build/github/azure-pipelines/templates/set-version-number-variables-step.yml index 007d40b7ae..dcbdcffb73 100644 --- a/tools/ci_build/github/azure-pipelines/templates/set-version-number-variables-step.yml +++ b/tools/ci_build/github/azure-pipelines/templates/set-version-number-variables-step.yml @@ -12,6 +12,10 @@ steps: FOR /F "tokens=* USEBACKQ" %%F IN (`git rev-parse HEAD`) DO ( @echo ##vso[task.setvariable variable=OnnxRuntimeGitCommitHash;]%%F ) + + FOR /F "tokens=* USEBACKQ" %%F IN (`git rev-parse --short HEAD`) DO ( + @echo ##vso[task.setvariable variable=OnnxRuntimeGitCommitHashShort;]%%F + ) workingDirectory: '$(Build.SourcesDirectory)' condition: eq(variables['Agent.OS'], 'Windows_NT') @@ -26,5 +30,8 @@ steps: _OnnxRuntimeGitCommitHash=$(git rev-parse HEAD) echo "##vso[task.setvariable variable=OnnxRuntimeGitCommitHash;]$_OnnxRuntimeGitCommitHash" + _OnnxRuntimeGitCommitHash=$(git rev-parse --short=8 HEAD) + echo "##vso[task.setvariable variable=OnnxRuntimeGitCommitHashShort;]$_OnnxRuntimeGitCommitHash" + workingDirectory: '$(Build.SourcesDirectory)' condition: not(eq(variables['Agent.OS'], 'Windows_NT')) \ No newline at end of file diff --git a/tools/ci_build/github/azure-pipelines/templates/win-ci.yml b/tools/ci_build/github/azure-pipelines/templates/win-ci.yml index 8ce6984dc5..bcd1cb8da9 100644 --- a/tools/ci_build/github/azure-pipelines/templates/win-ci.yml +++ b/tools/ci_build/github/azure-pipelines/templates/win-ci.yml @@ -13,10 +13,12 @@ parameters: MsbuildArguments: '/m' EnvSetupScript: 'setup_env.bat' CudaVersion: '' + AgentPool: 'Win-CPU' jobs: - job: ${{ parameters.JobName }} timeoutInMinutes: 120 + pool: ${{ parameters.AgentPool }} variables: buildDirectory: '$(Build.BinariesDirectory)' BuildCommand: ${{ parameters.BuildCommand }} diff --git a/tools/ci_build/github/windows/post_binary_sizes_to_dashboard.py b/tools/ci_build/github/windows/post_binary_sizes_to_dashboard.py new file mode 100644 index 0000000000..7161b6f897 --- /dev/null +++ b/tools/ci_build/github/windows/post_binary_sizes_to_dashboard.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + + +import argparse +import mysql.connector +import xml.etree.ElementTree as ET +import sys +import os + +def parse_arguments(): + parser = argparse.ArgumentParser(description="ONNXRuntime binary size uploader for dashboard") + parser.add_argument("--commit_hash", help="Full Git commit hash") + parser.add_argument("--build_project", default='Lotus', choices=['Lotus','onnxruntime'], help="Lotus or onnxruntime build project, to construct the build URL") + parser.add_argument("--build_id", help="Build Id") + parser.add_argument("--size_data_file", help="Path to file that contains the binary size data") + + return parser.parse_args() + +# Assumes size_data_file is a csv file with a header line, containing binary sizes and other attributes +# CSV fields are: +# os,arch,build_config,size +# No empty line or space between fields expected +def get_binary_sizes(size_data_file): + binary_size = [] + with open(size_data_file, 'r') as f: + line = f.readline() + headers = line.strip().split(',') + while line: + line = f.readline() + if not line: + break; + linedata = line.strip().split(',') + tablerow = {} + for i in range(0,len(headers)): + if headers[i] == 'size': + tablerow[headers[i]] = int(linedata[i]) + else: + tablerow[headers[i]] = linedata[i] + binary_size.append(tablerow) + return binary_size + + +def write_to_db(binary_size_data, args): + # connect to database + + cnx = mysql.connector.connect( + user='ort@onnxruntimedashboard', + password=os.environ.get('DASHBOARD_MYSQL_ORT_PASSWORD'), + host='onnxruntimedashboard.mysql.database.azure.com', + database='onnxruntime') + + try: + cursor = cnx.cursor() + + #delete old records + delete_query = ('DELETE FROM onnxruntime.binary_size ' + 'WHERE build_time < DATE_SUB(Now(), INTERVAL 30 DAY);' + ) + + cursor.execute(delete_query) + + #insert current records + for row in binary_size_data: + insert_query = ('INSERT INTO onnxruntime.binary_size ' + '(build_time, build_project, build_id, commit_id, os, arch, build_config, size) ' + 'VALUES (Now(), "%s", "%s", "%s", "%s", "%s", "%s", %d) ' + 'ON DUPLICATE KEY UPDATE ' + 'build_time=Now(), build_project="%s", build_id="%s", size=%d;' + ) % ( + args.build_project, + args.build_id, + args.commit_hash, + row['os'], + row['arch'], + row['build_config'], + row['size'], + + args.build_project, + args.build_id, + row['size'] + ) + cursor.execute(insert_query) + + cnx.commit() + + # # Use below for debugging: + # cursor.execute('select * from onnxruntime.binary_size') + # for r in cursor: + # print(r) + + cursor.close() + cnx.close() + except BaseException as e: + cnx.close() + raise e + + +if __name__ == "__main__": + try: + args = parse_arguments() + binary_size_data = get_binary_sizes(args.size_data_file) + write_to_db(binary_size_data, args) + except BaseException as e: + print(str(e)) + sys.exit(1) + + +