Skip to content
This repository has been archived by the owner on Apr 17, 2019. It is now read-only.

Commit

Permalink
Iroha build time graph per each g++ target
Browse files Browse the repository at this point in the history
Signed-off-by: Alexey Rodionov <[email protected]>
  • Loading branch information
Stayer committed Feb 21, 2019
1 parent aeac2a1 commit cf71e0a
Show file tree
Hide file tree
Showing 19 changed files with 291 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .jenkinsci-new/build.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def cmakeConfigure(String buildDir, String cmakeOptions, String sourceTreeDir=".
}

def cmakeBuild(String buildDir, String cmakeOptions, int parallelism) {
sh "cmake --build ${buildDir} ${cmakeOptions} -- -j${parallelism}"
sh "cmake --build ${buildDir} ${cmakeOptions} -- -j${parallelism} | sponge buildTimeResult.txt"
sh "ccache --show-stats"
}

Expand Down
16 changes: 15 additions & 1 deletion .jenkinsci-new/builders/x64-linux-build-steps.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,23 @@ def buildSteps(int parallelism, List compilerVersions, String build_type, boolea
}
}

def successPostSteps(scmVars, boolean packagePush, String dockerTag, List environment) {
def successPostSteps(scmVars, boolean packagePush, String dockerTag, List environment, boolean buildTimeGraph) {
stage('Linux success PostSteps') {
withEnv(environment) {

// handling build time results
if (buildTimeGraph) {
sh(".jenkinsci-new/helpers/exportBuildTime.py buildTimeResult.txt")
zip archive: true, dir: '', glob: 'buildTimeResult.csv', zipFile: 'buildTimeMeasurement.zip'
archiveArtifacts artifacts: 'buildTimeMeasurement.zip'

copyArtifacts(projectName: 'develop', filter: 'buildTimeMeasurement.zip', target: 'buildTimeMeasurement-develop');
unzip zipFile: 'buildTimeMeasurement-develop/buildTimeMeasurement.zip', dir: 'buildTimeMeasurement-develop'
sh ".jenkinsci-new/helpers/analyzeBuildTime.py buildTimeMeasurement-develop/buildTimeResult.csv buildTimeResult.csv"
zip archive: true, dir: '', glob: 'diff.csv', zipFile: 'diff.zip'
archiveArtifacts artifacts: 'diff.zip'
}

if (packagePush) {
def artifacts = load ".jenkinsci-new/artifacts.groovy"
def utils = load ".jenkinsci-new/utils/utils.groovy"
Expand Down
65 changes: 65 additions & 0 deletions .jenkinsci-new/helpers/analyzeBuildTime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env python
#
# Copyright Soramitsu Co., Ltd. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
#

#
# Analyzes build time per each iroha build target (g++ target) and stores all results to csv-file:
# target, work_type, sys_time, user_time, total, sys_time_diff, user_time_diff, total_diff, sys_time_perc, user_time_perc, total_perc
#

import csv
from sys import argv
from os import path

F1, F2 = argv[1], argv[2] # base, compare

# time difference in seconds (multiply by -1 show difference - faster or lower)
def diff_secs(a, b):
return round( (float(a) - float(b)) * -1 , 2)

# time difference in percents (multiply by -1 show difference - faster or lower)
def diff_perc(a, b):
if float(a) == 0.0:
return 0.0
return round( (float(a) - float(b)) / float(a) * 100 * -1, 2)

if __name__ == '__main__':
if not path.isfile(F1) or not path.isfile(F2):
print("Can't find files!")
exit(1)

with open(F1) as base, open(F2) as compare:
base_reader, comp_reader = csv.DictReader(base), csv.DictReader(compare)
b, c = { row['target']: row for row in base_reader }, { row['target']: row for row in comp_reader }

if len(c) == 0:
print("No records found")
exit(1)

for target in c:
c[target].update(
{ 'user_time_diff': 0, 'sys_time_diff': 0, 'total_diff': 0,
'user_time_perc': 0, 'sys_time_perc': 0, 'total_perc': 0 }
)
if b[target] is None:
continue
c[target]['sys_time_diff'] = diff_secs(b[target]['sys_time'], c[target]['sys_time'])
c[target]['user_time_diff'] = diff_secs(b[target]['user_time'], c[target]['user_time'])
c[target]['total_diff'] = diff_secs(b[target]['total'], c[target]['total'])
c[target]['sys_time_perc'] = diff_perc(b[target]['sys_time'], c[target]['sys_time'])
c[target]['user_time_perc'] = diff_perc(b[target]['user_time'], c[target]['user_time'])
c[target]['total_perc'] = diff_perc(b[target]['total'], c[target]['total'])

with open ('diff.csv', 'w+') as csvfile:
fieldnames = ['target', 'work_type',
'sys_time', 'user_time', 'total',
'sys_time_diff', 'user_time_diff', 'total_diff',
'sys_time_perc', 'user_time_perc', 'total_perc'
]
# fieldnames = sorted(next(iter(c.iteritems()))[1].keys())
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for row in c:
writer.writerow(c[row])
2 changes: 2 additions & 0 deletions .jenkinsci-new/helpers/compilers/clang++-6.0.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
( /usr/bin/time -f "%S\t%U" clang++-6.0 "${@}" 2> >(cat <(echo "clang++-6.0 ${@}") - )) | sponge
2 changes: 2 additions & 0 deletions .jenkinsci-new/helpers/compilers/clang++-7.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
( /usr/bin/time -f "%S\t%U" clang++-7 "${@}" 2> >(cat <(echo "clang++-7 ${@}") - )) | sponge
2 changes: 2 additions & 0 deletions .jenkinsci-new/helpers/compilers/clang++.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
( /usr/bin/time -f "%S\t%U" clang++ "${@}" 2> >(cat <(echo "clang++ ${@}") - )) | sponge
2 changes: 2 additions & 0 deletions .jenkinsci-new/helpers/compilers/g++-5.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
( /usr/bin/time -f "%S\t%U" g++-5 "${@}" 2> >(cat <(echo "g++-5 ${@}") - )) | sponge
2 changes: 2 additions & 0 deletions .jenkinsci-new/helpers/compilers/g++-7.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
( /usr/bin/time -f "%S\t%U" g++-7 "${@}" 2> >(cat <(echo "g++-7 ${@}") - )) | sponge
49 changes: 49 additions & 0 deletions .jenkinsci-new/helpers/exportBuildTime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env python
#
# Copyright Soramitsu Co., Ltd. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
#

#
# Compares 2 csv files with build time data, makes new file with difference in seconds and percents
#

import re
import argparse
import csv

parser = argparse.ArgumentParser(description='Process time output for compiler')

parser.add_argument('log_file', type=str, help='input file')

args = parser.parse_args()
if __name__ == "__main__":
lines = []
with open(args.log_file, "r") as f:
lines = f.readlines()
i = 0
units = []
while i < len(lines):
unit = {}
if "g++" not in lines[i]:
i+=1
continue
try:
sys_time, user_time = lines[i+1].rstrip().split("\t")
unit['target'] = re.findall(r"-o (\S+) ", lines[i])[0]
unit['work_type'] = 'linking' if "-Wl" in lines[i] else "build"
unit['sys_time'] = float(sys_time)
unit['user_time'] = float(user_time)
unit['total'] = round(unit['sys_time'] + unit['user_time'], 2)
units.append(unit)
i+=2
except:
i+=1
continue

csv_filename = args.log_file.split(".")[0] + ".csv"
with open(csv_filename, 'w') as csvfile:
fieldnames = ['target', 'sys_time', 'user_time', 'total', 'work_type']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(units)
10 changes: 5 additions & 5 deletions .jenkinsci-new/utils/vars.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
//

def compilerMapping () {
return ['gcc5': ['cxx_compiler':'g++-5', 'cc_compiler':'gcc-5'],
'gcc7' : ['cxx_compiler':'g++-7', 'cc_compiler':'gcc-7'],
'clang6': ['cxx_compiler':'clang++-6.0', 'cc_compiler':'clang-6.0'],
'clang7': ['cxx_compiler':'clang++-7', 'cc_compiler':'clang-7'],
'appleclang': ['cxx_compiler':'clang++', 'cc_compiler':'clang'],
return ['gcc5': ['cxx_compiler':"${WORKSPACE}/.jenkinsci-new/helpers/compilers/g++-5.sh", 'cc_compiler':'gcc-5'],
'gcc7' : ['cxx_compiler':"${WORKSPACE}/.jenkinsci-new/helpers/compilers/g++-7.sh", 'cc_compiler':'gcc-7',],
'clang6': ['cxx_compiler':"${WORKSPACE}/.jenkinsci-new/helpers/compilers/clang++-6.0.sh", 'cc_compiler':'clang-6.0'],
'clang7': ['cxx_compiler':"${WORKSPACE}/.jenkinsci-new/helpers/compilers/clang++-7.sh", 'cc_compiler':'clang-7'],
'appleclang': ['cxx_compiler':"${WORKSPACE}/.jenkinsci-new/helpers/compilers/clang++.sh", 'cc_compiler':'clang'],
]
}

Expand Down
4 changes: 2 additions & 2 deletions .jenkinsci/debug-build.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def doDebugBuild(coverageEnabled=false) {
+ " -v /tmp/${GIT_COMMIT}-${BUILD_NUMBER}:/tmp/${GIT_COMMIT}") {

def scmVars = checkout scm
def cmakeOptions = ""
def cmakeOptions = "-DCMAKE_CXX_COMPILER=${WORKSPACE}/.jenkinsci/helpers/build.sh"
if ( coverageEnabled ) {
cmakeOptions += " -DCOVERAGE=ON "
}
Expand Down Expand Up @@ -95,7 +95,7 @@ def doDebugBuild(coverageEnabled=false) {
-DIROHA_VERSION=${env.IROHA_VERSION} \
${cmakeOptions}
"""
sh "cmake --build build -- -j${parallelism}"
sh "cmake --build build -- -j${parallelism} | sponge buildTimeResult.txt"
sh "ccache --show-stats"
if ( coverageEnabled ) {
sh "cmake --build build --target coverage.init.info"
Expand Down
65 changes: 65 additions & 0 deletions .jenkinsci/helpers/analyzeBuildTime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env python
#
# Copyright Soramitsu Co., Ltd. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
#

#
# Analyzes build time per each iroha build target (g++ target) and stores all results to csv-file:
# target, work_type, sys_time, user_time, total, sys_time_diff, user_time_diff, total_diff, sys_time_perc, user_time_perc, total_perc
#

import csv
from sys import argv
from os import path

F1, F2 = argv[1], argv[2] # base, compare

# time difference in seconds (multiply by -1 show difference - faster or lower)
def diff_secs(a, b):
return round( (float(a) - float(b)) * -1 , 2)

# time difference in percents (multiply by -1 show difference - faster or lower)
def diff_perc(a, b):
if float(a) == 0.0:
return 0.0
return round( (float(a) - float(b)) / float(a) * 100 * -1, 2)

if __name__ == '__main__':
if not path.isfile(F1) or not path.isfile(F2):
print("Can't find files!")
exit(1)

with open(F1) as base, open(F2) as compare:
base_reader, comp_reader = csv.DictReader(base), csv.DictReader(compare)
b, c = { row['target']: row for row in base_reader }, { row['target']: row for row in comp_reader }

if len(c) == 0:
print("No records found")
exit(1)

for target in c:
c[target].update(
{ 'user_time_diff': 0, 'sys_time_diff': 0, 'total_diff': 0,
'user_time_perc': 0, 'sys_time_perc': 0, 'total_perc': 0 }
)
if b[target] is None:
continue
c[target]['sys_time_diff'] = diff_secs(b[target]['sys_time'], c[target]['sys_time'])
c[target]['user_time_diff'] = diff_secs(b[target]['user_time'], c[target]['user_time'])
c[target]['total_diff'] = diff_secs(b[target]['total'], c[target]['total'])
c[target]['sys_time_perc'] = diff_perc(b[target]['sys_time'], c[target]['sys_time'])
c[target]['user_time_perc'] = diff_perc(b[target]['user_time'], c[target]['user_time'])
c[target]['total_perc'] = diff_perc(b[target]['total'], c[target]['total'])

with open ('diff.csv', 'w+') as csvfile:
fieldnames = ['target', 'work_type',
'sys_time', 'user_time', 'total',
'sys_time_diff', 'user_time_diff', 'total_diff',
'sys_time_perc', 'user_time_perc', 'total_perc'
]
# fieldnames = sorted(next(iter(c.iteritems()))[1].keys())
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for row in c:
writer.writerow(c[row])
2 changes: 2 additions & 0 deletions .jenkinsci/helpers/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
( /usr/bin/time -f "%S\t%U" g++ "$@" 2> >(cat <(echo "g++ $@") - )) | sponge
2 changes: 2 additions & 0 deletions .jenkinsci/helpers/build_cmake.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
( /usr/bin/time -f "%S\t%U" g++ "$@" 2> >(cat <(echo "g++ $@") - )) | sponge
49 changes: 49 additions & 0 deletions .jenkinsci/helpers/exportBuildTime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env python
#
# Copyright Soramitsu Co., Ltd. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
#

#
# Compares 2 csv files with build time data, makes new file with difference in seconds and percents
#

import re
import argparse
import csv

parser = argparse.ArgumentParser(description='Process time output for compiler')

parser.add_argument('log_file', type=str, help='input file')

args = parser.parse_args()
if __name__ == "__main__":
lines = []
with open(args.log_file, "r") as f:
lines = f.readlines()
i = 0
units = []
while i < len(lines):
unit = {}
if "g++" not in lines[i]:
i+=1
continue
try:
sys_time, user_time = lines[i+1].rstrip().split("\t")
unit['target'] = re.findall(r"-o (\S+) ", lines[i])[0]
unit['work_type'] = 'linking' if "-Wl" in lines[i] else "build"
unit['sys_time'] = float(sys_time)
unit['user_time'] = float(user_time)
unit['total'] = round(unit['sys_time'] + unit['user_time'], 2)
units.append(unit)
i+=2
except:
i+=1
continue

csv_filename = args.log_file.split(".")[0] + ".csv"
with open(csv_filename, 'w') as csvfile:
fieldnames = ['target', 'sys_time', 'user_time', 'total', 'work_type']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(units)
4 changes: 4 additions & 0 deletions .jenkinsci/helpers/platform_tag.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
#!/usr/env/python
#
# Copyright Soramitsu Co., Ltd. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
#
import xml.etree.ElementTree as ET
import argparse

Expand Down
15 changes: 15 additions & 0 deletions .jenkinsci/linux-post-step.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ def linuxPostStep() {
try {
// stop write core dumps
sh "ulimit -c 0"

// handling coredumps (if tests crashed)
if (currentBuild.currentResult != "SUCCESS" && params.coredump) {
def dumpsFileName = sprintf('coredumps-%1$s.bzip2',
Expand All @@ -16,6 +17,20 @@ def linuxPostStep() {
echo "Build is not SUCCESS! See core dumps at: https://nexus.iroha.tech/repository/artifacts/iroha/coredumps/${dumpsFileName}"
}
}

// handling build time results
if (currentBuild.currentResult == "SUCCESS" && !params.fuzzing) {
sh(".jenkinsci/helpers/exportBuildTime.py buildTimeResult.txt")
zip archive: true, dir: '', glob: 'buildTimeResult.csv', zipFile: 'buildTimeMeasurement.zip'
archiveArtifacts artifacts: 'buildTimeMeasurement.zip'

copyArtifacts(projectName: 'develop', filter: 'buildTimeMeasurement.zip', target: 'buildTimeMeasurement-develop');
unzip zipFile: 'buildTimeMeasurement-develop/buildTimeMeasurement.zip', dir: 'buildTimeMeasurement-develop'
sh ".jenkinsci/helpers/analyzeBuildTime.py buildTimeMeasurement-develop/buildTimeResult.csv buildTimeResult.csv"
zip archive: true, dir: '', glob: 'diff.csv', zipFile: 'diff.zip'
archiveArtifacts artifacts: 'diff.zip'
}

if (currentBuild.currentResult == "SUCCESS" && GIT_LOCAL_BRANCH ==~ /(master|develop)/) {
def artifacts = load ".jenkinsci/artifacts.groovy"
def commit = env.GIT_COMMIT
Expand Down
8 changes: 6 additions & 2 deletions Jenkinsfile-new
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ node ('master') {
coverage = false
coverage_mac = false
doxygen = false

buildTimeGraph = true

build_type = 'Debug'
packageBuild = false
pushDockerTag = 'not-supposed-to-be-pushed'
Expand Down Expand Up @@ -262,9 +263,12 @@ node ('master') {
parallelism==0 ?x64LinuxWorker.cpusAvailable : parallelism, x64linux_compiler_list, 'Release', specialBranch, false,
false , testList, false, false, false, true, false, false, false, environmentList)}]
}
if (build_scenario == 'Before merge to trunk') {
buildTimeGraph = false
}
x64LinuxPostSteps = new Builder.PostSteps(
always: [{x64LinuxBuildScript.alwaysPostSteps(environmentList)}],
success: [{x64LinuxBuildScript.successPostSteps(scmVars, packagePush, pushDockerTag, environmentList)}])
success: [{x64LinuxBuildScript.successPostSteps(scmVars, packagePush, pushDockerTag, environmentList, buildTimeGraph)}])
}
def x64MacBuildSteps
def x64MacBuildPostSteps = new Builder.PostSteps()
Expand Down
2 changes: 1 addition & 1 deletion docker/develop/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ENV IROHA_HOME /opt/iroha
ENV IROHA_BUILD /opt/iroha/build

RUN apt-get update && \
apt-get -y --no-install-recommends install apt-utils software-properties-common wget; \
apt-get -y --no-install-recommends install apt-utils software-properties-common wget time moreutils; \
apt-get -y clean

# add repos
Expand Down

0 comments on commit cf71e0a

Please sign in to comment.