diff options
author | Martin Peres <martin.peres@free.fr> | 2016-02-01 20:29:11 +0200 |
---|---|---|
committer | Martin Peres <martin.peres@free.fr> | 2016-02-01 20:32:10 +0200 |
commit | be598bf0ecd54119bd9462d9e438036a9b4b7700 (patch) | |
tree | b3a42120cdbd7a732787efbad29e5ceffeb24bb5 | |
parent | f2c5febd7e20d0c336709d42e30b85d9888cbbba (diff) |
77 files changed, 1 insertions, 8889 deletions
@@ -1,212 +1 @@ -= EzBench = - -This repo contains a collection of tools to benchmark graphics-related -patch-series. - -== Core.sh == - -WARNING: This tool can be used directly from the CLI but it is recommenced that -you use ezbench in conjunction with ezbenchd which together support testing the -kernel and which are much more robust to errors. - -This tool is responsible for collecting the data and generating logs that will -be used by another tool to generate a visual report. - -To operate, this script requires a git repo, the ability to compile and deploy -a commit and then benchmarks to be run. To simplify the usage, a profile should -be written for each repo you want to test that will allow ezbench to check the -current version that is deployed, to compile and install a new version and set -some default parameters to avoid typing very-long command lines every time a -set of benchmarks needs to be run. - -By default, the logs will be outputed in logs/<date of the run>/ and are stored -mostly as csv files. The main report is found under the name results and needs -to read with "less -r" to get the colours out! The list of commits tested is -found under the name commit_list. A comprehensive documentation of the file -structure will be written really soon. - -You may specify whatever name you want by adding -N <name> to the command line. -This is very useful when testing kernel-related stuff as we need to reboot on -a new kernel to test a new commit. - -=== Dependencies === - - - A recent-enough version of bash - - make - - awk - - all the other typical binutils binaries - -=== Configuration === - -The tests configuration file is named user_parameters.sh. A sample file called -user_parameters.sh.sample comes with the repo and is a good basis for your first -configuration file. - -You will need to adjust this file to give the location of the base directory of -all the benchmark folders and repositories for the provided profiles. - -Another important note about core.sh is that it is highly modular and -hook-based. Have a look at profiles.d/$profile/conf.d/README for the -documentation about the different hooks. - -=== Examples === - -==== Testing every patchset of a series ==== - -The following command will test all the GLB27:Egypt cases but the ones -containing the word cpu in them. It will run all the benchmarks 5 times on -the 10 commits before HEAD~~. - - ./core.sh -p ~/repos/mesa -B cpu -b GLB27:Egypt -r 5 -n 10 -H HEAD~~ - -The following command run the synmark:Gl21Batch2 benchmark (note the $ at the -end that indicates that we do not want the :cpu variant). It will run all the -benchmarks 3 times on 3 commits (in this order), HEAD~5 HEAD~2 HEAD~10. - - ./core.sh -p ~/repos/mesa -b synmark:Gl21Batch2$ -r 3 HEAD~5 HEAD~2 HEAD~10 - -To use the mesa profile, which has the advantage of checking that the deployment -was successful, you may achieve the same result by running: - - ./core.sh -P mesa -b synmark:Gl21Batch2$ -r 3 HEAD~5 HEAD~2 HEAD~10 - -==== Retrospectives ==== - -Here is an example of how to generate a retrospective. The interesting part is -the call to utils/get_commit_list.py which generates a list of commits - - ./core.sh -p ~/repos/mesa -B cpu -b GLB27:Egypt:offscreen \ - -b GLB27:Trex:offscreen -b GLB30:Manhattan:offscreen \ - -b GLB30:Trex:offscreen -b unigine:heaven:1080p:fullscreen \ - -b unigine:valley:1080p:fullscreen -r 3 \ - -m "./recompile-release.sh" \ - `utils/get_commit_list.py -p ~/repos/mesa -s 2014-12-01 -i "1 week"` - -== ezbench == - -This tool is meant to make the usage of core.sh easy and support testing -performance across reboots. - -It allows creating a new performance report, scheduling benchmark -runs, changing the execution rounds on the fly and then start, pause or halt -the execution of this report. - -This tool uses core.sh as a backend for checking that the commits SHA1 and tests -do exist so you are sure that the work can be executed when the time comes. - -=== Dependencies === - - - python3 - - numpy - -=== Examples === - -==== Creating a report ==== - -The ezbench command allows you to create a new performance report. To create -a performance report named 'mesa-tracking-pub-benchmarks', using the core.sh -profile 'mesa', you need to run the following command: - - ./ezbench -p mesa mesa-tracking-pub-benchmarks - -==== Adding benchmarks runs ==== - -Adding the 2 rounds of benchmark GLB27:Egypt:offscreen to the report -mesa-tracking-pub-benchmarks for the commit HEAD can be done using the following -command: - - ./ezbench -r 2 -b GLB27:Egypt:offscreen -c HEAD mesa-tracking-pub-benchmarks - -A retrospective can be made in the same fashion as with core.sh at the exception -made that it would also work across reboots which is good when testing kernels: - - ./ezbench -r 3 -b GLB27:Egypt:offscreen -b GLB27:Trex:offscreen \ - -b GLB30:Manhattan:offscreen -b GLB30:Trex:offscreen \ - -b unigine:heaven:1080p:fullscreen -b unigine:valley:1080p:fullscreen \ - -c "`utils/get_commit_list.py -p ~/repos/mesa -s 2014-12-01 -i "1 week"`" - mesa-tracking-pub-benchmarks - -==== Checking the status of a report ==== - -You can check the status of the 'mesa-tracking-pub-benchmarks' report by calling -the following command: - - ./ezbench mesa-tracking-pub-benchmarks status - -==== Changing the execution status of the report ==== - -When creating a report, the default state of the report is "initial" which means -that nothing will happen until the state is changed. To change the state, you -need to run the following command: - - ./ezbench mesa-tracking-pub-benchmarks (run|pause|abort) - - - The "run" state says that the report is ready to be run by ezbenchd.py. - - - The "pause" and "abort" states indicate that ezbenchd.py should not be - executing any benchmarks from this report. The difference between the "pause" - and "abort" states is mostly for humans, to convey the actual intent. - -==== Starting collecting data without ezbenchd.py ==== - -If you are not using ezbenchd.py, you may simply run the following command to -start collecting data: - - ./ezbench mesa-tracking-pub-benchmarks start - -This command will automatically change the state of the report to "run". - -== utils/ezbenchd.py == - -TODO - -== stats/gen_report.py == - -WARNING: This tool is deprecated, compare_reports.py is the prefered way now even -if the single-report mode is not as advanced as the gen_report.py. - -The goal of this tool is to read the reports from ezbench and make them -presentable to engineers and managers. - -Commits can be renamed by having a file named 'commit_labels' in the logs -folder. The format is to have one label per line. The short SHA1 first, a space -and then the label. Here is an example: - bb19f2c 2014-12-01 - -If you want to generate date labels for commits, you can use the tool -utils/gen_date_labels.py to generates the 'commit_labels' file. Example: - utils/gen_date_labels.py -p ~/repos/mesa logs/seekreet_stuff/ - -It is also possible to add notes to the HTML report by adding a file called -'notes' in the report folder. Every line of the note file will be added in -an unordered list. It is possible to use HTML inside the file. - -=== Dependencies === - - - python3 - - matplotlib - - scipy - - mako - - an internet connection to read the report - -=== Example === - -This command will create an HTML report named -logs/public_benchmarks_trend_broadwell/index.html. Nothing more, nothing less. - - ./stats/gen_report.py logs/public_benchmarks_trend_broadwell/ - - -== utils/perf_bisect.py == - -WARNING: The introduction of smart ezbench made this tool absolutely useless - -The perf_bisect.py tool allows bisecting performance issues. It is quite trivial -to use, so just check out the example. - -=== Examples === - -The following command will bisect a performance difference between commit -HEAD~100 and HEAD. The -p, -b, -r and -m arguments are the same as core.sh. - - utils/perf_bisect.py -p ~/repos/mesa -b glxgears:window -r 1 HEAD~100 HEAD +The repo changed, new url: http://cgit.freedesktop.org/ezbench diff --git a/SHA1_DB/sha1_db b/SHA1_DB/sha1_db deleted file mode 100755 index 0361b85..0000000 --- a/SHA1_DB/sha1_db +++ /dev/null @@ -1,188 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2015, Intel Corporation -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of Intel Corporation nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -function usage() { - echo "Usage: $0 SHA1_DB sha1 (add version path upstream | add_git git_repo binary_path | read_attr (version | path | upstream | \$attr) | write_attr \$attr \$value)" - - exit $1 -} - -function exit_error() { - echo $@ - exit 1 -} - -function db_get_file() { - sha1_db=$1 - sha1=$2 - - echo "$sha1_db/db/$sha1" -} - -function db_add() { - sha1_db=$1 - sha1=$2 - version=$3 - path=$4 - upstream=$5 - - sha1_db_file=$(db_get_file $sha1_db $sha1) - if [ -f $sha1_db_file ] - then - orig_path=$(db_read $sha1_db $sha1 path) - echo "SHA1_DB: The SHA1 $sha1 already exists (orig=$orig_path vs new=$path), exit..." - exit 0 - fi - - mkdir -p $(dirname $sha1_db_file) 2> /dev/null - - echo "SHA1_DB_VERSION=1" > $sha1_db_file - echo "version=$version" >> $sha1_db_file - echo "path=$path" >> $sha1_db_file - echo "upstream=$upstream" >> $sha1_db_file - - echo "SHA1_DB: '$path' ($sha1) add under version=$version, upstream=$upstream" - - exit 0 -} - -function db_add_git() { - sha1_db=$1 - sha1=$2 - git_repo=$3 - binary=$4 - - if [ "$sha1" == "-" ] - then - sha1=$(sha1sum $binary | cut -d ' ' -f 1) - fi - - pwd=$(pwd) - cd $git_repo 2> /dev/null || exit_error "Error: cannot open the folder '$git_repo'." - git status > /dev/null 2>&1 || exit_error "Error: the folder '$git_repo' is not a git repo." - - git_sha1=$(git rev-parse --short HEAD) - tracked_branch=$(git branch -vv --no-color | grep --color=never "^*" | cut -d '[' -f 2 | cut -d ']' -f 1) - remote=$(echo "$tracked_branch" | cut -d '/' -f 1) - branch=$(echo "$tracked_branch" | cut -d '/' -f 2) - - # handle local branches by just using the local - if [ -n "$(echo "$branch" | grep " ")" ] - then - # Local branch detected - fetch_url="$USER@$(hostname):$(pwd)" - branch=$(git rev-parse --abbrev-ref HEAD) - else - fetch_url=$(git remote show -n origin | grep "Fetch URL:" | cut -d ':' -f 2- | cut -d ' ' -f 2-) - fi - cd $pwd - - db_add "$sha1_db" "$sha1" "$git_sha1" "$binary" "$fetch_url/$branch" -} - -function db_read() { - sha1_db=$1 - sha1=$2 - attribute=$3 - - sha1_db_file=$(db_get_file $sha1_db $sha1) - [ ! -f $sha1_db_file ] && exit 1 - - value=$(grep $attribute $sha1_db_file | cut -d '=' -f 2-) - [ -z "$value" ] && exit 1 - - echo $value - exit 0 -} - -function db_write() { - sha1_db=$1 - sha1=$2 - attribute=$3 - value=$4 - - sha1_db_file=$(db_get_file $sha1_db $sha1) - [ ! -f $sha1_db_file ] && exit 1 - - existing_value=$(grep $attribute $sha1_db_file | cut -d '=' -f 2-) - if [ -z "$value" ] - then - # add the value - echo "$attribute=$value" > $sha1_db_file - else - #replace the value - sed -i "s~$attribute=$existing_value~$attribute=$value~g" $sha1_db_file - fi - exit 0 -} - -if [[ $# -lt 4 ]] -then - usage 1 -fi - -sha1_db=$1 -sha1=$2 -action=$3 - -case "$action" in - add) - if [[ $# -ne 6 ]] - then - usage 1 - fi - version=$4 - path=$5 - upstream=$6 - db_add "$sha1_db" "$sha1" "$version" "$path" "$upstream" - ;; - - add_git) - if [[ $# -ne 5 ]] - then - usage 1 - fi - git_repo=$4 - binary=$5 - db_add_git "$sha1_db" "$sha1" "$git_repo" "$binary" - ;; - read_attr) - attribute=$4 - db_read "$sha1_db" "$sha1" "$attribute" - ;; - write_attr) - if [[ $# -ne 5 ]] - then - usage 1 - fi - attribute=$4 - value=$5 - db_write "$sha1_db" "$sha1" "$attribute" "$value" - ;; - *) echo "SHA1_DB: invalid action '$action'" - ;; -esac
\ No newline at end of file @@ -1,143 +0,0 @@ -= TODO = - -== Priority list == - - watchdogs - - auto deploying of the component being tested - - experiment mode - -== core.sh == - -=== Watchdog support === - -Add watchdog support to reboot the machine if the test is taking too long to -execute and the machine does not want to work anymore. - -Systemd has some nice features which could be built-in smart-ezbench and ezbenchd -but this watchdog cannot be stopped or re-programmed during compilation which may -take any amount of time. - -More investigation needs to be made. - -=== Profiles === - - - Add auto-deployment support which would download from the git repo of - interest and setup ezbench to make use of it. - - - Create a new repo every time we are about to compile, this should be very - cheap and would guarantee that we do not destroy the current state of the repo. - - - Add information about how to create working URLs for every commit SHA1, this - is useful when creating reports. - -==== Kernel ==== - -Make the default kernel profile work on ubuntu and not just archlinux by -supporting the initramfs creation tool from ubuntu. - -=== Tests === - - - Auto deploy benchmarks - - - Do dependency checking a bit better so as we can report what is missing for - one benchmark - - - Add a benchmark-testing mode that will run the benchmark a hundred time and - deduce the variance of it. This will be used by smart ezbench to figure out how - many runs are necessary. - - - Output multiple metrics, possibly under the name - ${commit}_bench_${benchmark}.${metric}_metric - -=== Reset the environment to a previously-used one === - -When wanting to add data to a certain commit, we need to check the environment -did not change, or, if it did, make at least that the results do not have a -different average. At the very least, we should prevent adding data if anything -in the environment changed except volatile information like the throttling count. - -== Reports == - - - Store the execution runid along with the value in the result file to avoid - mis-labeling run IDs and to detect execution errors! - -=== Move commits to a different folder === - -The current report folder is kind of a mess because it potentially contains -thousands of files. - -We could create one folder per commit and store the data there. The name could -be suffixed with the commit date. - -=== Potentially share commit results between reports === - -Benchmarks take forever to run, so it really is infuriating to have to re-run -them over and over again when nothing changed! - -This issue will be mitigated when Smart_Ezbench lands as one could copy the -benchmark results of a previous run in the new report folder to avoid -re-executing them. This would be made easy if using folders per commits. - -The actual solution will be to store results in a separate folder with the state -that got used to generate them. This would allow re-using results when nothing -changed :) - -In the mean time, we can store the results of each commits in a separate folder - -=== Experiment mode === - -There is currently only one mode to ezbench, it is making a report. - -This is not very convenient during the development phase as we often want to -compare different approches to a baseline. - -The goal would be to remember what were the settings set for the baseline and -automatically run the experiment when asked to by the user. - -At a user's wish (amd probably at the end of every run), a report should be -created to show the differences. - -Upon changes to the baseline parameters (set of benchmarks, # of runs, ...), the -previous experiments should also be updated to contain all the needed data. This -allows the developer to add data over-night for a broader set of benchmarks or -reducing the variance by adding runs. - -EDIT: Profiles already get us close to this, but not entirely. I will need to -think more about this - -== Utils == - -=== Easy way to build the graphics stack from git === - -To ease up the set-up of the build environment which is also error-prone and -prone to having differences from machines to machines, we propose adding a bunch -of scripts that would set up the graphics stack from git, have sane defaults -values and work together. - -Having such a script set could allow us to store the git SHA1 IDs and build-ids -in the generated binaries. - -EDIT: Chad's script would be good for mesa already! - http://sarah.thesharps.us/2015/12/17/building-a-custom-intel-graphics-stack/ - -== gen_report.py == - -=== Allow filtering the results === - -There is a ton of data in a performance report. It would be nice if we could -filter the rest of the data when we unselect a benchmark in the trend view. - -== env-dump == - - - Save the SHA1 of the config (zcat /proc/config.gz | sha1sum -) and compare - that to the SHA1_DB to get where it comes from. If it is not found in the DB, - I guess we will have to keep it as unknown and hope the kernel version is - enough information for us to check the config. - - - Save the kernel parameters - - - Save the list of modules loaded - - - Save the configure command line in the SHA1-DB - - - Add a way to save storage by storing a diff with a previous report. This - means we need to add support for applying a patch diff --git a/core.sh b/core.sh deleted file mode 100755 index c6785e6..0000000 --- a/core.sh +++ /dev/null @@ -1,672 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2015, Intel Corporation -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of Intel Corporation nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# The script is known to work with recent versions of bash. -# Authors: -# - Martin Peres <martin.peres@intel.com> -# - Chris Wilson <chris@chris-wilson.co.uk> - -# Error codes: -# Argument parsing: -# - 11: Need a profile name after the -P option -# - 12: The profile does not exist -# - 13: Missing optarg after a parameter -# - 14: Missing git repository directory -# -# OS: -# - 30: The shell does not support globstat -# - 31: Cannot create the log folder -# - 32: Cannot move to the git repo directory -# -# Git: -# - 50: Unable to preserve dirty state of the repository -# - 51: Invalid commit ID -# -# Compilation & deployment: -# - 70: Compilation or deployment failed -# - 71: Compilation failed -# - 72: Deployment failed -# - 73: The deployed version does not match the wanted version -# - 74: A reboot is necessary -# -# Tests: -# - 100: At least one test does not exist -# - -# Uncomment the following to track all the executed commands -#set -o xtrace - -shopt -s globstar || { - echo "ERROR: ezbench requires bash 4.0+ or zsh with globstat support." - exit 30 -} - -# Printf complains about floating point numbers having , as a delimiter otherwise -LC_NUMERIC="C" - -ezBenchDir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) - -# initial cleanup -mkdir "$ezBenchDir/logs" 2> /dev/null - -# set the default run_bench function which can be overriden by the profiles: -# Bash variables: $run_log_file : filename of the log report of the current run -# Arguments: $1 : timeout (set to 0 for infinite wait) -# $2+: command line executing the test AND NOTHING ELSE! -function run_bench { - timeout=$1 - shift - cmd="LIBGL_DEBUG=verbose vblank_mode=0 stdbuf -oL timeout $timeout" - bench_binary=$(echo "$1" | rev | cut -d '/' -f 1 | rev) - - env_dump_path="$ezBenchDir/utils/env_dump/env_dump.so" - if [ -f "$env_dump_path" ]; then - run_log_file_env_dump="$run_log_file.env_dump" - env_dump_launch="$ezBenchDir/utils/env_dump/env_dump.sh" - cmd="$cmd $env_dump_launch $run_log_file_env_dump $@" - else - cmd="$cmd $@" - fi - - run_log_file_stdout="$run_log_file.stdout" - run_log_file_stderr="$run_log_file.stderr" - if [ ! -z "$run_log_file" ]; then - cmd="$cmd > >(tee $run_log_file_stdout) 2> >(tee $run_log_file_stderr >&2)" - fi - - callIfDefined run_bench_pre_hook - eval $cmd - callIfDefined run_bench_post_hook - - if [ -f "$env_dump_path" ]; then - $ezBenchDir/utils/env_dump/env_dump_extend.sh "$SHA1_DB" "$run_log_file_env_dump" - fi - - # delete the log files if they are empty - if [ ! -s "$run_log_file_stdout" ] ; then - rm "$run_log_file_stdout" - fi - if [ ! -s "$run_log_file_stderr" ] ; then - rm "$run_log_file_stderr" - fi -} - -# parse the options -function available_tests { - # Generate the list of available tests - echo -n "Available tests: " - for test_dir in ${testsDir:-$ezBenchDir/tests.d}; do - for test_file in $test_dir/**/*.test; do - unset test_name - unset test_exec_time - - source "$test_file" || continue - [ -z "$test_name" ] && continue - [ -z "$test_exec_time" ] && continue - for t in $test_name; do - echo -n "$t " - done - done - done - echo -} -function callIfDefined() { - if [ "$(type -t "$1")" == 'function' ]; then - local funcName=$1 - shift - $funcName "$@" - else - return 1 - fi -} - -function show_help { - echo " core.sh [list of SHA1]" - echo "" - echo " Optional arguments:" - echo " -P <profile name>" - echo " -p <path_git_repo>" - echo " -r <benchmarking rounds> (default: 3)" - echo " -b <benchmark regexp> include these benchmarks to run" - echo " -B <benchmark regexp> exclude these benchamrks from running" - echo " -H <git-commit-id> benchmark the commits preceeding this one" - echo " -n <last n commits>" - echo " -m <make and deploy command> (default: 'make -j8 install', '' to skip the compilation)" - echo " -N <log folder's name> (default: current date and time)" - echo " -T <path> source the test definitions from this folder" - echo " -k dry run, do not compile any commit or execute any benchmark" - echo " -c configuration shell script to be run after user_parameters.sh" - echo "" - echo " Other actions:" - echo " -h/?: Show this help message" - echo " -l: List the available tests" -} - -# Read the user parameters -source "$ezBenchDir/user_parameters.sh" - -# First find the profile, if it is set -optString="h?P:p:n:N:H:r:b:B:m:T:lkc:" -profile="default" -while getopts "$optString" opt; do - case "$opt" in - P) profile=$OPTARG - ;; - :) - echo "Option -$OPTARG requires an argument." >&2 - exit 11 - ;; - esac -done - -# Check if the profile exists -profileDir="$ezBenchDir/profiles.d/$profile" -if [ ! -d "$profileDir" ]; then - echo "Profile '$profile' does not exist." >&2 - exit 12 -fi - -# Default user options -for conf in $profileDir/conf.d/**/*.conf; do - [ "$conf" = "$ezBenchDir/conf.d/**/*.conf" ] && continue - source "$conf" -done -source "$profileDir/profile" - -# Start again the argument parsing, this time with every option -unset OPTIND -while getopts "$optString" opt; do - case "$opt" in - h|\?) - show_help - exit 0 - ;; - p) gitRepoDir=$OPTARG - ;; - n) lastNCommits=$OPTARG - ;; - N) reportName=$OPTARG - ;; - H) uptoCommit=$OPTARG - ;; - r) rounds=$OPTARG - ;; - b) testsList="$testsList $OPTARG" - ;; - B) testExcludeList="$testExcludeList $OPTARG" - ;; - m) makeAndDeployCmd=$OPTARG - ;; - T) testsDir="$testsDir $OPTARG" - ;; - l) - available_tests - exit 0 - ;; - k) - dry_run=1 - ;; - c) - source "$OPTARG" - ;; - :) - echo "Option -$OPTARG requires an argument." >&2 - exit 13 - ;; - esac -done -shift $((OPTIND-1)) - -# redirect the output to both a log file and stdout -if [ -z "$dry_run" ] -then - logsFolder="$ezBenchDir/logs/${reportName:-$(date +"%Y-%m-%d-%T")}" - [ -d $logsFolder ] || mkdir -p $logsFolder || exit 30 - exec > >(tee -a $logsFolder/results) - exec 2>&1 -fi - -function read_git_version_deployed() { - if [ -n "$gitVersionDeployedCmd" ] - then - eval "$gitVersionDeployedCmd" - return $? - fi - return 1 -} - -# functions to call on exit -function __ezbench_reset_git_state__ { - git reset --hard "$commit_head" 2> /dev/null - [ -n "$stash" ] && git stash apply "$stash" > /dev/null -} - -function __ezbench_finish__ { - exitcode=$? - action=$1 - - # to be executed on exit, possibly twice! - __ezbench_reset_git_state__ - - # Execute the user-defined post hook - callIfDefined ezbench_post_hook - - if [ "$action" == "reboot" ] - then - printf "Rebooting with error code $exitcode\n" - sudo reboot - else - printf "Exiting with error code $exitcode\n" - exit $exitcode - fi -} -trap __ezbench_finish__ EXIT -trap __ezbench_finish__ INT # Needed for zsh - -# Execute the user-defined pre hook -callIfDefined ezbench_pre_hook - -# Check the git repo, saving then displaying the HEAD commit -if [ -z "$gitRepoDir" ] -then - echo "ERROR: You did not specify a git repository path (-p). Aborting..." - exit 14 -fi -cd "$gitRepoDir" || exit 1 -commit_head=$(git rev-parse HEAD 2>/dev/null) -if [ $? -ne 0 ] -then - echo "ERROR: The path '$gitRepoDir' does not contain a valid git repository. Aborting..." - exit 1 -fi -printf "Repo = $gitRepoDir, HEAD = $commit_head" - -deployedVersion=$(read_git_version_deployed) -[ $? -eq 0 ] && printf ", deployed version = $deployedVersion" -echo - -# Preserve any local modifications -stash=$(git stash create) -if [ $? -ne 0 ] -then - echo "ERROR: Unable to preserve dirty state in '$gitRepoDir'. Aborting..." - exit 50 -fi -[ -n "$stash" ] && echo "Preserving work-in-progress" - -commitList= -for id in "$@"; do - if [[ $id =~ \.\. ]]; then - commitList+=$(git rev-list --abbrev-commit --reverse "$id" 2> /dev/null) - else - commitList+=$(git rev-list --abbrev-commit -n 1 "$(git rev-parse "$id" 2> /dev/null)" 2> /dev/null) - fi - [ $? -ne 0 ] && printf "ERROR: Invalid commit ID '$id'\n" && exit 51 - commitList+=" " -done - -# Seed the results with the last round? -commitListLog="$logsFolder/commit_list" -last_commit=$(tail -1 "$commitListLog" 2>/dev/null | cut -f 1 -d ' ') - -# Generate the actual list of tests -typeset -A testNames -typeset -A testInvert -typeset -A testPrevFps -typeset -A testFilter -total_tests=0 -total_round_time=0 -echo -n "Tests that will be run: " -for test_dir in ${testsDir:-$ezBenchDir/tests.d}; do - for test_file in $test_dir/**/*.test; do - unset test_name - unset test_unit - unset test_invert - unset test_exec_time - - source "$test_file" || continue - - for t in $test_name; do - # Check that the user wants this test or not - found=1 - if [ -n "$testsList" ]; then - found=0 - for filter in $testsList; do - if [[ $t =~ $filter ]]; then - testFilter[$filter]=1 - found=1 - break - fi - done - fi - if [ -n "$testExcludeList" ]; then - for filter in $testExcludeList; do - if [[ $t =~ $filter ]]; then - testFilter[$filter]=-1 - found=0 - break - fi - done - fi - [ $found -eq 0 ] && continue - - # Set the default unit to FPS - [ -z "$test_unit" ] && test_unit="FPS" - - testNames[$total_tests]=$t - testUnit[$total_tests]=$test_unit - testInvert[$total_tests]=$test_invert - - last_result="$logsFolder/${last_commit}_result_${t}" - if [ -e "$logsFolder/${last_commit}_result_${t}" ]; then - testPrevFps[$total_tests]=$(cat "$last_result") - fi - unset last_result - - echo -n "${testNames[$total_tests]} " - - total_round_time=$(dc <<<"$total_round_time $test_exec_time + p") - total_tests=$(( total_tests + 1)) - done - done -done -total_round_time=${total_round_time%.*} -echo -unset last_commit - -missing_tests= -for t in $testsList; do - [ -z ${testFilter[$t]} ] && missing_tests+="$t " -done -if [ -n "$missing_tests" ]; then - echo "The tests \"${missing_tests:0:-1}\" do not exist" - available_tests - exit 100 -fi - -# Set the average compilation time to 0 when we are not compiling -if [ -z "$makeAndDeployCmd" ] -then - avgBuildTime=0 - - # Since we cannot deploy a new version, we need to use the version that is - # currently deployed - if [ -n "$deployedVersion" ] - then - printf "WARNING: Cannot deploy new versions, forcing the commit list to $deployedVersion\n" - commitList=$deployedVersion - fi -else - avgBuildTime=$(git config --get ezbench.average-build-time 2>/dev/null || echo 30) -fi - -# finish computing the list of commits -if [ -z "$commitList" ]; then - commitList=$(git rev-list --abbrev-commit --reverse -n "${lastNCommits}" "${uptoCommit}") - [ "${uptoCommit}" == "HEAD" ] && commitList="${commitList} ${stash}" -fi -num_commits=$(wc -w <<< $commitList) -printf "Testing %d commits: %s\n" $num_commits "$(echo "$commitList" | tr '\n' ' ')" - -# Estimate the execution time -secs=$(( ($total_round_time * $rounds + $avgBuildTime) * $num_commits)) -finishDate=$(date +"%y-%m-%d - %T" --date="$secs seconds") -printf "Estimated finish date: $finishDate (%02dh:%02dm:%02ds)\n\n" $(($secs/3600)) $(($secs%3600/60)) $(($secs%60)) -startTime=`date +%s` - -# ANSI colors -c_red='\e[31m' -c_bright_red='\e[1;31m' -c_bright_green='\e[1;32m' -c_bright_yellow='\e[1;33m' -c_bright_white='\e[1;37m' -c_reset='\e[0m' - -bad_color=$c_bright_red -good_color=$c_bright_green -meh_color=$c_bright_yellow - -function compile_and_deploy { - # Accessible variables - # $commit [RO]: SHA1 id of the current commit - # $commitName [RO]: Name of the commit - - # early exit if the deployed version is the wanted commit - version=$(read_git_version_deployed) - [ $? -eq 0 ] && [[ "$version" =~ "$commit" ]] && return 0 - - # Make sure we are in the right folder - cd "$gitRepoDir" || exit 31 - - # Select the commit of interest - if [ "$commit" == "$stash" ] - then - git reset --hard "$commit_head" > /dev/null - git stash apply "$stash" > /dev/null - echo -e "${c_bright_yellow}WIP${c_reset}" - echo "$commit" >> "$commitListLog" - git diff > "$logsFolder/${commit}.patch" - else - git reset --hard "$commit" > /dev/null - git show --format="%Cblue%h%Creset %Cgreen%s%Creset" -s - if [ -z "$(grep ^"$commit" "$commitListLog" 2> /dev/null)" ] - then - git show --format="%h %s" -s >> "$commitListLog" - fi - git format-patch HEAD~ --format=fuller --stdout > "$logsFolder/${commit}.patch" - fi - - # Call the user-defined pre-compile hook - callIfDefined compile_pre_hook - - # Compile the commit and check for failure. If it failed, go to the next commit. - compile_logs=$logsFolder/${commit}_compile_log - compile_start=$(date +%s) - eval "$makeAndDeployCmd" > "$compile_logs" 2>&1 - local exit_code=$? - compile_end=$(date +%s) - - # The exit code 74 actually means everything is fine but we need to reboot - if [ $exit_code -eq 74 ] - then - printf "Exiting with error code 0\n" >> "$compile_logs" - else - printf "Exiting with error code $exit_code\n" >> "$compile_logs" - fi - - # Reset to the original commit early - __ezbench_reset_git_state__ - - # Call the user-defined post-compile hook - callIfDefined compile_post_hook - - # Check for compilation errors - if [ "$exit_code" -ne '0' ]; then - # Forward the error code from $makeAndDeployCmd if it is a valid error code - if [ $exit_code -eq 71 ]; then - component="Compilation" - elif [ $exit_code -eq 72 ]; then - component="Deployment" - elif [ $exit_code -eq 74 ]; then - $?=$exit_code - __ezbench_finish__ "reboot" - else - exit_code=70 - fi - - printf " ${c_bright_red}ERROR${c_reset}: $component failed, log saved in $compile_logs\n" - exit $exit_code - fi - - # Update our build time estimator - avgBuildTime=$(bc <<< "0.75*$avgBuildTime + 0.25*($compile_end - $compile_start)") - git config --replace-all ezbench.average-build-time "$(printf "%.0f" "$avgBuildTime")" - - # Check that the deployed image is the right one - version=$(read_git_version_deployed) - if [ $? -eq 0 ] && [[ ! "$version" =~ "$commit" ]] - then - printf " ${c_bright_red}ERROR${c_reset}: The deployed version ($version) does not match the wanted one($commit)\n" - exit 73 - fi -} - -if [ $rounds -eq 0 ] -then - echo "Nothing to do (rounds == 0), exit." - exit 0 -fi - -if [ -n "$dry_run" ] -then - echo "Dry-run mode, exit." - exit 0 -fi - -# Iterate through the commits -for commit in $commitList -do - # compile and deploy the commit - compile_and_deploy $commit - - # Iterate through the tests - fpsALL="" - for (( t=0; t<${#testNames[@]}; t++ )); - do - benchName=${testNames[$t]} - - # Generate the logs file names - fps_logs=$logsFolder/${commit}_bench_${testNames[$t]} - error_logs=${fps_logs}.errors - - # Find the first run id available - if [ -f "$fps_logs" ]; then - # The logs file exist, look for the number of runs - run=0 - while [ -f "${fps_logs}#${run}" ] - do - run=$((run+1)) - done - else - if [ -z "${testInvert[$t]}" ]; then - direction="more is better" - else - direction="less is better" - fi - echo "# ${testUnit[$t]} ($direction) of '${testNames[$t]}' using commit ${commit}" > "$fps_logs" - run=0 - fi - - # display the run name - printf "%28s: " "${testNames[$t]}" - - # compute the different hook names - runFuncName=${testNames[$t]}_run - preHookFuncName=${testNames[$t]}_run_pre_hook - postHookFuncName=${testNames[$t]}_run_post_hook - processHookFuncName=${testNames[$t]}_process - - # Run the benchmark - for (( c=$run; c<$run+$rounds; c++ )) - do - run_log_file="${fps_logs}#$c" - - callIfDefined "$preHookFuncName" - callIfDefined benchmark_run_pre_hook - - # This function will return multiple fps readings - "$runFuncName" > "$run_log_file" 2> /dev/null - - callIfDefined benchmark_run_post_hook - callIfDefined "$postHookFuncName" - - if [ -s "$run_log_file" ]; then - # Add the fps values before adding the result to the average fps for - # the run. - fps_avg=$(awk '{sum=sum+$1} END {print sum/NR}' $run_log_file) - echo "$fps_avg" >> "$fps_logs" - else - echo "0" >> "$run_log_file" - echo "0" >> "$fps_logs" - fi - done - - # Process the data ourselves - output=$(tail -n +2 "$fps_logs") # Read back the data, minus the header - statistics= - result=$(callIfDefined "$processHookFuncName" "$output") || { - statistics=$(echo "$output" | "$ezBenchDir/fps_stats.awk") - result=$(echo "$statistics" | cut -d ' ' -f 1) - statistics=$(echo "$statistics" | cut -d ' ' -f 2-) - } - echo $result > $logsFolder/${commit}_result_${testNames[$t]} - if [ -z "${testPrevFps[$t]}" ]; then - testPrevFps[$t]=$result - fi - if [ -z "${testInvert[$t]}" ]; then - fpsDiff=$(echo "scale=3;($result * 100.0 / ${testPrevFps[$t]}) - 100" | bc 2>/dev/null) - else - fpsDiff=$(echo "scale=3;(100.0 * ${testPrevFps[$t]} / $result) - 100" | bc 2>/dev/null) - fi - [ $? -eq 0 ] && testPrevFps[$t]=$result - if (( $(bc -l <<< "$fpsDiff < -1.5" 2>/dev/null || echo 0) )); then - color=$bad_color - elif (( $(bc -l <<< "$fpsDiff > 1.5" 2>/dev/null || echo 0) )); then - color=$good_color - else - color="$meh_color" - fi - printf "%9.2f ($color%+.2f%%$c_reset): %s\n" "$result" "$fpsDiff" "$statistics" - [ -z "$result" ] || fpsALL="$fpsALL $result" - done - - # finish with the geometric mean (when we have multiple tests) - if [ $t -gt 1 ]; then - fpsALL=$(awk '{r=0; for(i=1; i<=NF; i++) { r += log($i) } print exp(r / NF) }' <<< $fpsALL) - if [ -z "${testPrevFps[-1]}" ]; then - testPrevFps[-1]=$fpsALL - fi - fpsDiff=$(echo "scale=3;($fpsALL * 100.0 / ${testPrevFps[-1]}) - 100" | bc 2>/dev/null) - [ $? -eq 0 ] && testPrevFps[-1]=$fpsALL - if (( $(bc -l <<< "$fpsDiff < -1.5" 2>/dev/null || echo 0) )); then - color=$bad_color - elif (( $(bc -l <<< "$fpsDiff > 1.5" 2>/dev/null || echo 0) )); then - color=$good_color - else - color="$meh_color" - fi - printf "$c_bright_white%28s: %9.2f ($color%+.2f%%$c_bright_white)$c_reset\n" \ - "geometric mean" \ - "$fpsALL" \ - "$fpsDiff" - fi - echo -done - -endTime=$(date +%s) -runtime=$((endTime-startTime)) -printf "Actual run time: %02dh:%02dm:%02ds\n\n" $((runtime/3600)) $((runtime%3600/60)) $((runtime%60)) diff --git a/ezbench b/ezbench deleted file mode 100755 index 6a11bf1..0000000 --- a/ezbench +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env python3 - -""" -Copyright (c) 2015, Intel Corporation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -""" - -from subprocess import call,check_output -from pprint import pprint -from numpy import * -import subprocess -import argparse -import shutil -import sys -import os - -# Import ezbench from the utils/ folder -ezbench_dir = os.path.abspath(sys.path[0]) -sys.path.append(ezbench_dir + '/utils/') -from ezbench import * - -def break_lists(input_list, sep=" "): - res = [] - if input_list is None: - return res - for entry in input_list: - res.extend(entry.split(sep)) - return res - -# parse the options -parser = argparse.ArgumentParser() -parser.add_argument("-b", dest='benchmarks', help="<benchmark regexp> include these benchmarks to run", - action="append") -parser.add_argument("-B", dest='benchmarks_exclude', help="<benchmark regexp> exclude these benchamrks from running", - action="append") -parser.add_argument("-c", dest='commits', help="Commits to run the benchmarks on", - action="append") -parser.add_argument("-r", dest='rounds', help="Number of execution rounds", - action="store", type=int, nargs='?') -parser.add_argument("-p", dest='profile', help="Profile to be used by ezbench", - action="store") -parser.add_argument("report_name") -parser.add_argument("command", help="Command to execute", nargs='?', - choices=('start', 'run', 'pause', 'abort', 'status')) -args = parser.parse_args() - -sbench = SmartEzbench(ezbench_dir, args.report_name) - -if sbench.profile() is None and args.profile is not None: - sbench.set_profile(args.profile) - -# add commits and benchmarks -if args.commits is not None and args.benchmarks is not None: - # remove duplicates in the lists - commits = list(set(break_lists(args.commits))) - benchmarks = list(set(break_lists(args.benchmarks))) - benchmarks_exclude = list(set(break_lists(args.benchmarks_exclude))) - - # we cannot fetch the git sha1 without a profile/git repo - if sbench.profile() is None: - print("No profile is set, set one first with -p before adding benchmark runs") - - # get the list of benchmarks that actually need to be ran - ezbench = Ezbench(ezbench_path=ezbench_dir + "/core.sh", - profile=sbench.profile(), - report_name="tmp") - run_info = ezbench.run_commits(commits, benchmarks, benchmarks_exclude, dry_run=True) - if not run_info.success(): - sys.exit(1) - - # Add all the commits and benchmarks to commit - for commit in run_info.commits: - for bench in run_info.benchmarks: - print("add {count} runs to {bench} on {commit}".format(count=args.rounds, bench=bench, commit=commit)) - sbench.add_benchmark(commit, bench, args.rounds) - -if args.command is not None: - if args.command == "start": - sbench.run() - elif args.command == "run": - sbench.set_running_mode(RunningMode.RUN) - elif args.command == "pause": - sbench.set_running_mode(RunningMode.PAUSE) - elif args.command == "abort": - sbench.set_running_mode(RunningMode.ABORT) - elif args.command == "status": - pprint.pprint(sbench.state) - else: - print("Unknown command '{cmd}'".format(cmd=args.command)) diff --git a/fps_stats.awk b/fps_stats.awk deleted file mode 100755 index 041d584..0000000 --- a/fps_stats.awk +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/awk -f - -BEGIN { - min = 10000000 -} - -{ - val = $1 - - if (val < min) - min = val - if (val > max) - max = val - - delta = val - mean - mean += delta / NR - v += delta * (val - mean) - - # percentiles - array[NR] = val -} - -END { - if (NR > 1) - v = v/(NR-1) - else - v = 0 - - qsort(array, 1, NR) - - p50 = int(NR / 2) - p90 = int(NR * 0.9) - p95 = int(NR * 0.95) - p99 = int(NR * 0.99) - - print mean " min/p50/90/95/99/max/std = " min " / " array[p50] " / " array[p90] " / " array[p95] " / " array[p99] " / " max " / " sqrt(v) " n=" NR -} - -function qsort(A, left, right, i, last) { - if (left >= right) - return - swap(A, left, left+int((right-left+1)*rand())) - last = left - for (i = left+1; i <= right; i++) - if (A[i] < A[left]) - swap(A, ++last, i) - swap(A, left, last) - qsort(A, left, last-1) - qsort(A, last+1, right) -} -function swap(A, i, j, t) { - t = A[i]; A[i] = A[j]; A[j] = t -} diff --git a/profiles.d/README b/profiles.d/README deleted file mode 100644 index eed5780..0000000 --- a/profiles.d/README +++ /dev/null @@ -1,29 +0,0 @@ -# Profiles - -Here, you can find all the pre-set profiles to check the performance of some -components. - -The 'default' profile is the one that is picked when no profile is explicitely -selected. Other profiles can be added by the user or one can use some other -profiles provided with ezbench. - -## File hierarchy - -profiles.d/$profile_name/ - - profile: this file contains the default values to be used by the profile - - conf.d/: this folder contains multiple file named '*.conf' that can set - some hooks (described in the hooks section). - -### Hooks - -Hooks can be defined in a profile's conf.d/ folder. Here is a list of them: - - ezbench_pre_hook: called when core is launched - - ezbench_post_hook: called when core is being closed - - compile_pre_hook: called before the compilation/deployment happens - - compile_post_hook: called after the compilation/deployment happened - - benchmark_run_pre_hook: called before running a benchmark - - benchmark_run_post_hook: called after running a benchmark - - <benchmark name>_run_pre_hook: called before running a particular benchmark - - <benchmark name>_run_post_hook: called after running a particular benchmark - - run_bench_pre_hook: called before executing the benchmark's command line - - run_bench_post_hook: called after executing the benchmark's command line diff --git a/profiles.d/default/conf.d/compile.conf b/profiles.d/default/conf.d/compile.conf deleted file mode 100644 index 75d429b..0000000 --- a/profiles.d/default/conf.d/compile.conf +++ /dev/null @@ -1,21 +0,0 @@ -source "$ezBenchDir/profiles.d/utils/common.sh" - -function compile_pre_hook() { - # Accessible variables - # $commit [RO]: SHA1 id of the current commit - # $commitName [RO]: Name of the commit - - cpu_reclocking_disable_stop - sleep 0.1 -} - -function compile_post_hook() { - # Accessible variables - # $commit [RO]: SHA1 id of the current commit - # $commitName [RO]: Name of the commit - - cpu_reclocking_disable_start - - # reset the turbo state - sleep 5 -} diff --git a/profiles.d/default/conf.d/compile.conf.sample b/profiles.d/default/conf.d/compile.conf.sample deleted file mode 100644 index 4548d84..0000000 --- a/profiles.d/default/conf.d/compile.conf.sample +++ /dev/null @@ -1,11 +0,0 @@ -function compile_pre_hook() { - # Accessible variables - # $commit [RO]: SHA1 id of the current commit - # $commitName [RO]: Name of the commit -} - -function compile_post_hook() { - # Accessible variables - # $commit [RO]: SHA1 id of the current commit - # $commitName [RO]: Name of the commit -} diff --git a/profiles.d/default/conf.d/ezbench.conf b/profiles.d/default/conf.d/ezbench.conf deleted file mode 100644 index 5bb7f2a..0000000 --- a/profiles.d/default/conf.d/ezbench.conf +++ /dev/null @@ -1,18 +0,0 @@ -source "$ezBenchDir/profiles.d/utils/common.sh" - -function ezbench_pre_hook() { - xserver_setup_start - cpu_reclocking_disable_start -} - -function ezbench_post_hook() { - xserver_setup_stop - cpu_reclocking_disable_stop -} - -function benchmark_run_pre_hook() { - # Reset the state of the xserver before running a new benchmark (resolution, others?) - xserver_reset - - # TODO: Do not run if the temperature of the CPU is too high (> 60°C) -} diff --git a/profiles.d/default/conf.d/ezbench.conf.sample b/profiles.d/default/conf.d/ezbench.conf.sample deleted file mode 100644 index 2413ad4..0000000 --- a/profiles.d/default/conf.d/ezbench.conf.sample +++ /dev/null @@ -1,5 +0,0 @@ -function ezbench_pre_hook() { -} - -function ezbench_post_hook() { -} diff --git a/profiles.d/default/conf.d/run_bench.conf.sample b/profiles.d/default/conf.d/run_bench.conf.sample deleted file mode 100644 index 1e0650a..0000000 --- a/profiles.d/default/conf.d/run_bench.conf.sample +++ /dev/null @@ -1,15 +0,0 @@ -function run_bench_pre_hook() { - # Accessible variables - # $bench_binary [RO]: name of the binary of the game/benchmark - # $cmd [RO]: complete command line of the benchmark to be run - # $run_log_file [RO]: path to the log file of the run - - run_log_file_metrics="$run_log_file.metrics" - pid=$(stdbuf -oL sudo $ezBenchDir/profiles.d/utils/_launch_background.sh $ezBenchDir/utils/custom_metrics_collector.py $bench_binary 2> $run_log_file_metrics) - export EZBENCH_METRICS_COLLECTOR_PID=$pid -} - -function run_bench_post_hook() { - sudo kill $EZBENCH_METRICS_COLLECTOR_PID - unset EZBENCH_METRICS_COLLECTOR_PID -} diff --git a/profiles.d/default/profile b/profiles.d/default/profile deleted file mode 100644 index 6cd930c..0000000 --- a/profiles.d/default/profile +++ /dev/null @@ -1,32 +0,0 @@ -source "$ezBenchDir/profiles.d/utils/common.sh" - -# Accessible variables -# $ezBenchDir [RO]: Directory of the ezbench -# ------------------ -# $rounds [WO]: Default number of rounds -# $makeAndDeployCmd [WO]: Command to compile and deploy the current git HEAD -# $gitVersionDeployedCmd [WO]: Command to print out the sha1 of the version currently deployed -# $lastNCommits [WO]: Specifies how many commits back should be benchmarked -# $uptoCommit [WO]: Define starting from which commit $lastNCommits should count -# $uptoCommit [WO]: Define starting from which commit $lastNCommits should count -# $gitRepoDir [WO]: Path to the git repo to use for this profile -# $reportName [WO]: Name to give to your report -# $testsDir [WO]: List of pathes to the directories containing the tests for this profile -# $testsList [WO]: List of tests that should be ran in this profile -# $testExcludeList [WO]: List of tests that should be excluded in this profile - -function __default_make_and_deploy__() { - # Return error codes: - # 71: Compilation error - # 72: Deployment error - - make -j8 || exit 71 - make_install_sha1_dump || exit 72 -} - -rounds=3 -makeAndDeployCmd="__default_make_and_deploy__" -lastNCommits= -uptoCommit="HEAD" -gitRepoDir='' -gitVersionDeployedCmd='' diff --git a/profiles.d/kernel/conf.d/compile.conf b/profiles.d/kernel/conf.d/compile.conf deleted file mode 120000 index 65a229f..0000000 --- a/profiles.d/kernel/conf.d/compile.conf +++ /dev/null @@ -1 +0,0 @@ -../../default/conf.d/compile.conf
\ No newline at end of file diff --git a/profiles.d/kernel/conf.d/ezbench.conf b/profiles.d/kernel/conf.d/ezbench.conf deleted file mode 120000 index 91e103c..0000000 --- a/profiles.d/kernel/conf.d/ezbench.conf +++ /dev/null @@ -1 +0,0 @@ -../../default/conf.d/ezbench.conf
\ No newline at end of file diff --git a/profiles.d/kernel/profile b/profiles.d/kernel/profile deleted file mode 100644 index 855de13..0000000 --- a/profiles.d/kernel/profile +++ /dev/null @@ -1,72 +0,0 @@ -source "$ezBenchDir/profiles.d/utils/common.sh" - -# Accessible variables -# $ezBenchDir [RO]: Directory of the ezbench -# ------------------ -# $rounds [WO]: Default number of rounds -# $makeAndDeployCmd [WO]: Command to compile and deploy the current git HEAD -# $gitVersionDeployedCmd [WO]: Command to print out the sha1 of the version currently deployed -# $lastNCommits [WO]: Specifies how many commits back should be benchmarked -# $uptoCommit [WO]: Define starting from which commit $lastNCommits should count -# $uptoCommit [WO]: Define starting from which commit $lastNCommits should count -# $gitRepoDir [WO]: Path to the git repo to use for this profile -# $reportName [WO]: Name to give to your report -# $testsDir [WO]: List of pathes to the directories containing the tests for this profile -# $testsList [WO]: List of tests that should be ran in this profile -# $testExcludeList [WO]: List of tests that should be excluded in this profile - -function __compile__() { - # Return error codes: - # 71: Compilation error - # 72: Deployment error - - # Compile the kernel. If any question arises, the default choice will be taken - # This part assumes that you have a working .config already set up. You can generate it using make localmodconfig. - yes ' - ' | make oldconfig || return 71 - make -j8 || return 71 - capture=$(sudo make modules_install) - echo "$capture" - kernel_id=$(echo "$capture" | grep DEPMOD | grep -o '[^ ]*$') - - # Tweak this part for your distribution - sudo cp arch/x86_64/boot/bzImage /boot/vmlinuz-linux-intel || return 72 - sudo mkinitcpio -k "$kernel_id" -g /boot/initramfs-linux-intel.img || return 72 - - # Force grub to boot on the non-distro kernel that we just compiled - # - # WARNING: Make sure that grub reverts to the distro's kernel if the - # computer crashes! - sudo grub-reboot 1 || return 72 -} - -function __default_make_and_deploy__() { - # Return error codes: - # 71: Compilation error - # 72: Deployment error - - x_show_debug_info_start - - __compile__ - compile_error=$? - - x_show_debug_info_stop - - [ "$compile_error" -ne 0 ] && return $compile_error - - # Return that a reboot is necessary - return 74 -} - -function __git_version_deployed__() { - # Transforms 4.3.0-rc2-10901-gbcb183d into bcb183d - # This requires CONFIG_LOCALVERSION_AUTO=y - uname -r | cut -d 'g' -f 2 -} - -rounds=3 -makeAndDeployCmd="__default_make_and_deploy__" -lastNCommits= -uptoCommit="HEAD" -gitRepoDir="$REPO_LINUX" -gitVersionDeployedCmd="__git_version_deployed__" diff --git a/profiles.d/mesa/conf.d/compile.conf b/profiles.d/mesa/conf.d/compile.conf deleted file mode 120000 index 65a229f..0000000 --- a/profiles.d/mesa/conf.d/compile.conf +++ /dev/null @@ -1 +0,0 @@ -../../default/conf.d/compile.conf
\ No newline at end of file diff --git a/profiles.d/mesa/conf.d/ezbench.conf b/profiles.d/mesa/conf.d/ezbench.conf deleted file mode 120000 index 91e103c..0000000 --- a/profiles.d/mesa/conf.d/ezbench.conf +++ /dev/null @@ -1 +0,0 @@ -../../default/conf.d/ezbench.conf
\ No newline at end of file diff --git a/profiles.d/mesa/profile b/profiles.d/mesa/profile deleted file mode 100644 index 880e9dd..0000000 --- a/profiles.d/mesa/profile +++ /dev/null @@ -1,48 +0,0 @@ -source "$ezBenchDir/profiles.d/utils/common.sh" - -# Accessible variables -# $ezBenchDir [RO]: Directory of the ezbench -# ------------------ -# $rounds [WO]: Default number of rounds -# $makeAndDeployCmd [WO]: Command to compile and deploy the current git HEAD -# $gitVersionDeployedCmd [WO]: Command to print out the sha1 of the version currently deployed -# $lastNCommits [WO]: Specifies how many commits back should be benchmarked -# $uptoCommit [WO]: Define starting from which commit $lastNCommits should count -# $uptoCommit [WO]: Define starting from which commit $lastNCommits should count -# $gitRepoDir [WO]: Path to the git repo to use for this profile -# $reportName [WO]: Name to give to your report -# $testsDir [WO]: List of pathes to the directories containing the tests for this profile -# $testsList [WO]: List of tests that should be ran in this profile -# $testExcludeList [WO]: List of tests that should be excluded in this profile - -function __compile__() { - make -j8 || return 71 - make_install_sha1_dump || return 72 - return 0 -} - -function __default_make_and_deploy__() { - # Return error codes: - # 71: Compilation error - # 72: Deployment error - - x_show_debug_info_start - - __compile__ - compile_error=$? - - x_show_debug_info_stop - - return $compile_error -} - -function __git_version_deployed__() { - glxinfo 2> /dev/null | sed -n 's/.*(git-\(.*\)).*/\1/p' | head -1 -} - -rounds=3 -makeAndDeployCmd="__default_make_and_deploy__" -lastNCommits= -uptoCommit="HEAD" -gitRepoDir="$REPO_MESA" -gitVersionDeployedCmd="__git_version_deployed__" diff --git a/profiles.d/utils/_launch_background.sh b/profiles.d/utils/_launch_background.sh deleted file mode 100755 index a8fd6d3..0000000 --- a/profiles.d/utils/_launch_background.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -$@ >&2 & -echo "$!" diff --git a/profiles.d/utils/_show_debug_info.sh b/profiles.d/utils/_show_debug_info.sh deleted file mode 100755 index 1990401..0000000 --- a/profiles.d/utils/_show_debug_info.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -# Start a compositor -twm& - -# Start xterm to follow the compilation logs -xterm -geometry 80x66+0+0 -e "tail -f $EZBENCH_COMPILATION_LOGS"& - -# Start xterm to follow the compilation logs -exec xterm -geometry 80x50+494+51
\ No newline at end of file diff --git a/profiles.d/utils/common.sh b/profiles.d/utils/common.sh deleted file mode 100644 index 801e19d..0000000 --- a/profiles.d/utils/common.sh +++ /dev/null @@ -1,149 +0,0 @@ -source "$ezBenchDir/profiles.d/utils/sha1_db.sh" - -# Requires xset, chvt,X -function xserver_setup_start() { - [[ $dry_run -eq 1 ]] && return - - export EZBENCH_VT_ORIG=$(sudo -n fgconsole) - - sudo -n chvt 5 - sleep 1 # Wait for the potential x-server running to release MASTER - x_pid=$(sudo -n $ezBenchDir/profiles.d/utils/_launch_background.sh Xorg -nolisten tcp -noreset :42 vt5 -auth /tmp/ezbench_XAuth 2> /tmp/lolo) # TODO: Save the xorg logs - export EZBENCH_X_PID=$x_pid - - export DISPLAY=:42 - export XAUTHORITY=/tmp/ezbench_XAuth - - # disable DPMS. The X-Server may not have started yet, so try multiple times (up to 5 seconds) - for i in {0..50} - do - xset s off -dpms 2> /dev/null - [ $? -eq 0 ] && return 0 - sleep 0.1 - done - - echo "ERROR: The X-Server still has not started after 5 seconds" >&2 - xserver_setup_stop - return 1 -} - -function xserver_setup_stop() { - [[ $dry_run -eq 1 ]] && return - - sudo -n kill $EZBENCH_X_PID - wait_random_pid $EZBENCH_X_PID - unset EZBENCH_X_PID - - sudo -n chvt $EZBENCH_VT_ORIG - unset EZBENCH_VT_ORIG - sleep 1 -} - -# Requires xrandr -function xserver_reset() { - [[ $dry_run -eq 1 ]] && return - - xrandr --auto -} - -function x_show_debug_info_start() { - [[ $dry_run -eq 1 ]] && return - [ -z $DISPLAY ] && return - - export EZBENCH_COMPILATION_LOGS=$compile_logs - export EZBENCH_COMMIT_SHA1=$commit - - $ezBenchDir/profiles.d/utils/_show_debug_info.sh& - export EZBENCH_DEBUG_SESSION_PID=$! - - unset EZBENCH_COMMIT_SHA1 - unset EZBENCH_COMPILATION_LOGS -} - -function x_show_debug_info_stop() { - [[ $dry_run -eq 1 ]] && return - [ -z "$DISPLAY" ] && return - [ -z "$EZBENCH_DEBUG_SESSION_PID" ] && return - - # Kill all the processes under the script - # FIXME: Would be better with a session id of a pid namespace - kill $(ps -o pid= --ppid $EZBENCH_DEBUG_SESSION_PID) - unset EZBENCH_DEBUG_SESSION_PID -} - -function cpu_id_max_get() { - grep "processor" /proc/cpuinfo | tail -n 1 | rev | cut -f 1 -d ' ' -} - -function cpu_reclocking_disable_start() { - # Disable turbo (TODO: Fix it for other cpu schedulers) - sudo -n sh -c "echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo" - - # Set the frequency to a fixed one - [ -z "$WANTED_CPU_FREQ_kHZ" ] && return - cpu_id_max=$(cpu_id_max_get) - for (( i=0; i<=${cpu_id_max}; i++ )); do - sudo -n sh -c "echo $WANTED_CPU_FREQ_kHZ > /sys/devices/system/cpu/cpu${i}/cpufreq/scaling_max_freq" - sudo -n sh -c "echo $WANTED_CPU_FREQ_kHZ > /sys/devices/system/cpu/cpu${i}/cpufreq/scaling_min_freq" - done - export EZBENCH_CPU_RECLOCKED=1 -} - -function cpu_reclocking_disable_stop() { - # Re-enable turbo (TODO: Fix it for other cpu schedulers) - sudo -n sh -c "echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo" - - # Reset the scaling to the original values - [ -z "EZBENCH_CPU_RECLOCKED" ] && return - cpu_id_max=$(cpu_id_max_get) - cwd=$(pwd) - for (( i=0; i<=${cpu_id_max}; i++ )); do - cd "/sys/devices/system/cpu/cpu${i}/cpufreq/" - sudo -n sh -c "cat cpuinfo_min_freq > scaling_min_freq" - sudo -n sh -c "cat cpuinfo_max_freq > scaling_max_freq" - done - cd $cwd - unset EZBENCH_CPU_RECLOCKED -} - -function aslr_disable_start() { - sudo -n sh -c "echo 0 > /proc/sys/kernel/randomize_va_space" -} - -function aslr_disable_stop() { - sudo -n sh -c "echo 1 > /proc/sys/kernel/randomize_va_space" -} - -function thp_disable_start() { - sudo -n sh -c "echo never > /sys/kernel/mm/transparent_hugepage/enabled" - sudo -n sh -c "echo never > /sys/kernel/mm/transparent_hugepage/defrag" -} - -function thp_disable_stop() { - sudo -n sh -c "echo always > /sys/kernel/mm/transparent_hugepage/enabled" - sudo -n sh -c "echo always > /sys/kernel/mm/transparent_hugepage/defrag" -} - -# function irq_remap_start() { -# cpu_id_max=$(cpu_id_max_get) -# for d in /proc/irq/*/ ; do -# sudo sh -c "echo $cpu_id_max > $d/smp_affinity" -# done -# } -# -# function irq_remap_stop() { -# for d in /proc/irq/*/ ; do -# sudo sh -c "echo 0 > $d/smp_affinity" -# done -# } - -function wait_random_pid() { - # This is generally unsafe, but better than waiting a random amount of time - - ps -p $1 > /dev/null 2> /dev/null - while [[ ${?} == 0 ]] - do - sleep .01 - ps -p $1 > /dev/null 2> /dev/null - done -} diff --git a/profiles.d/utils/sha1_db.sh b/profiles.d/utils/sha1_db.sh deleted file mode 100644 index 33f6492..0000000 --- a/profiles.d/utils/sha1_db.sh +++ /dev/null @@ -1,30 +0,0 @@ -function make_install_sha1_dump() { - # First, install to the right folder - make install || exit 72 - - [ -z "$SHA1_DB" ] && echo "Error: No SHA1_DB specified" && return 0 - - # make a temporary folder to install our SW in - root=$(mktemp -d) - - # install the deps - make DESTDIR=$root install 2> /dev/null - if [ $? -ne 0 ] - then - rm -rf $root - exit 72 - fi - - # list all the binaries installed and add them to the SHA1_DB - for binary in $(find $root -type f -executable) - do - [[ ${binary: -3} == ".la" ]] && continue - - binary=${binary#$root} - - $SHA1_DB/sha1_db $SHA1_DB - add_git . $binary - done - - rm -rf $root - return 0 -} diff --git a/stats/compare_reports.py b/stats/compare_reports.py deleted file mode 100755 index fe9d160..0000000 --- a/stats/compare_reports.py +++ /dev/null @@ -1,731 +0,0 @@ -#!/usr/bin/env python3 - -""" -Copyright (c) 2015, Intel Corporation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -""" - -from mako.template import Template -import pprint -import collections -import argparse -import sys -import os - -# Import ezbench from the utils/ folder -ezbench_dir = os.path.abspath(sys.path[0]+'/../') -sys.path.append(ezbench_dir+'/utils/') -sys.path.append(ezbench_dir+'/utils/env_dump') -from ezbench import * -from env_dump_parser import * - -# constants -html_name="index.html" - -# parse the options -parser = argparse.ArgumentParser() -parser.add_argument("--title", help="Set the title for the report") -parser.add_argument("--unit", help="Set the output unit (Default: ms)") -parser.add_argument("--output", help="Report html file path", required=True) -parser.add_argument("--commit_url", help="HTTP URL pattern, {commit} contains the SHA1") -parser.add_argument("--verbose", help="Be more verbose when generating the report", action="store_true") -parser.add_argument("log_folder", nargs='+') -args = parser.parse_args() - -# select the right unit -if args.unit is not None: - output_unit = args.unit -else: - output_unit = "ms" - -# Parse the results and then create one report with the following structure: -# commit -> report_name -> benchmark -> bench results -db = dict() -db["commits"] = collections.OrderedDict() -db["reports"] = list() -db["events"] = dict() -db["benchmarks"] = list() -db['env_sets'] = dict() -db["envs"] = dict() -db["targets"] = dict() -human_envs = dict() -git_history = None -for log_folder in args.log_folder: - print("{f}: ".format(f=log_folder), end="") - report_name = [x for x in log_folder.split('/') if x][-1] - try: - sbench = SmartEzbench(ezbench_dir, report_name, readonly=True) - if git_history is None: - git_history = sbench.git_history() - report = sbench.report(git_history=git_history) - except RuntimeError: - report = genPerformanceReport(log_folder) - - db["reports"].append(report_name) - - # drop the no-op benchmark - report.benchmarks = list(filter(lambda b: b.full_name != "no-op", report.benchmarks)) - - # make sure all the benchmarks are listed in db["envs"] - for benchmark in report.benchmarks: - db["envs"][benchmark.full_name] = dict() - - db["events"][report_name] = list() - for event in report.events: - if type(event) is EventBuildBroken: - event.commit_range.new.annotation = event.commit_range.new.sha1 + ": build broken" - event.commit_range.new.annotation_long = str(event) - elif type(event) is EventBuildFixed: - event.fixed_commit_range.new.annotation = event.fixed_commit_range.new.sha1 + ": build fixed" - event.fixed_commit_range.new.annotation_long = str(event) - elif type(event) is EventPerfChange: - for result in event.commit_range.new.results: - if result.benchmark.full_name != event.benchmark.full_name: - continue - result.annotation = str(event) - db["events"][report_name].append(event) - - # add all the commits - for commit in report.commits: - # drop the no-op results - commit.results = list(filter(lambda r: r.benchmark.full_name != "no-op", commit.results)) - if len(commit.results) == 0 and not hasattr(commit, 'annotation'): - continue - - if not commit.sha1 in db["commits"]: - db["commits"][commit.sha1] = dict() - db["commits"][commit.sha1]['reports'] = dict() - db["commits"][commit.sha1]['commit'] = commit - if not commit.build_broken(): - db["commits"][commit.sha1]['build_color'] = "#00FF00" - else: - db["commits"][commit.sha1]['build_color'] = "#FF0000" - db["commits"][commit.sha1]['build_error'] = str(EzbenchExitCode(commit.compil_exit_code)).split('.')[1] - db["commits"][commit.sha1]['reports'][report_name] = dict() - - # Add the results and perform some stats - score_sum = 0 - count = 0 - for result in commit.results: - if not result.benchmark.full_name in db["benchmarks"]: - db["benchmarks"].append(result.benchmark.full_name) - db["commits"][commit.sha1]['reports'][report_name][result.benchmark.full_name] = result - average = convert_unit(result.result(), result.unit_str, output_unit) - score_sum += average - count += 1 - result.average = float("{0:.2f}".format(average)) - result.margin_str = float("{0:.2f}".format(result.margin() * 100)) - - # Compare to the target - if not result.benchmark.full_name in db["targets"]: - db["targets"][result.benchmark.full_name] = average - - # Environment - if result.benchmark.full_name not in human_envs: - for envfile in result.env_files: - if envfile is not None: - human_envs[result.benchmark.full_name] = EnvDumpReport(log_folder + "/" + envfile, True) - if result.benchmark.full_name not in db['env_sets']: - db['env_sets'][result.benchmark.full_name] = list() - for e in range(0, len(result.env_files)): - # Create the per-run information - envfile = result.env_files[e] - if envfile is None: - continue - - r = EnvDumpReport(log_folder + "/" + envfile, False).to_set(['^DATE', - '^ENV.ENV_DUMP_FILE', - '^ENV.EZBENCH_PERFMETER_PID', - '^ENV.EZBENCH_X_PID', - 'SHA1$', - 'extension count$', - 'window id$']) - tup = dict() - tup['log_folder'] = report_name - tup['commit'] = commit - tup['run'] = e - - # Compare the set to existing ones - found = False - for report in db['env_sets'][result.benchmark.full_name]: - if r == report['set']: - report['users'].append(tup) - found = True - - # Add the report - if not found: - new_entry = dict() - new_entry['set'] = r - new_entry['users'] = list() - new_entry['users'].append(tup) - db['env_sets'][result.benchmark.full_name].append(new_entry) - - if count > 0: - avg = score_sum / count - else: - avg = 0 - db["commits"][commit.sha1]['reports'][report_name]["average"] = float("{0:.2f}".format(avg)) - db["commits"][commit.sha1]['reports'][report_name]["average_unit"] = output_unit - -# Generate the environment -for bench in human_envs: - env = human_envs[bench] - if env is not None: - for key in sorted(list(env.values)): - cur = db['envs'][bench] - fields = key.split(":") - for f in range(0, len(fields)): - field = fields[f].strip() - if f < len(fields) - 1: - if field not in cur: - cur[field] = dict() - cur = cur[field] - else: - cur[field] = env.values[key] - -# Generate the environment diffs -db['env_diff_keys'] = dict() -for bench in db['env_sets']: - final_union = set() - for report in db['env_sets'][bench]: - diff = db['env_sets'][bench][0]['set'] ^ report['set'] - final_union = final_union | diff - db['env_diff_keys'][bench] = sorted(dict(final_union).keys()) - -# Sort the benchmarks by name to avoid ever-changing layouts -db["benchmarks"] = sort(db["benchmarks"]) - -# Support creating new URLs -if args.commit_url is not None: - db["commit_url"] = args.commit_url - -if args.verbose: - pprint.pprint(db) - -# Generate the report -html_template=""" -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" -"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - -<%! import cgi %> - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title>${title}</title> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - <style> - body { font-size: 10pt; } - table { font-size: 10pt; } - - /* http://martinivanov.net/2011/09/26/css3-treevew-no-javascript/ */ - .css-treeview input + label + ul - { - display: none; - } - .css-treeview input:checked + label + ul - { - display: block; - } - .css-treeview input - { - position: absolute; - opacity: 0; - } - .css-treeview label, - .css-treeview label::before - { - cursor: pointer; - } - .css-treeview input:disabled + label - { - cursor: default; - opacity: .6; - } - table{ - border-collapse:collapse; - } - table td{ - padding:5px; border:#4e95f4 1px solid; - } - table tr:nth-child(odd){ - background: #b8d1f3; - } - table tr:nth-child(even){ - background: #dae5f4; - } - - .env_node:hover { - cursor: pointer; - text-decoration: underline; - } - - .close_button { - color: black; - background-color: grey; - cursor:pointer; - } - .close_button:hover { - text-decoration:underline; - } - </style> - <script type="text/javascript" src="https://www.google.com/jsapi"></script> - <script type="text/javascript"> - google.load('visualization', '1', {packages: ['corechart']}); - google.setOnLoadCallback(drawTrend); - google.setOnLoadCallback(drawDetails); - - var currentCommit = "${default_commit}"; - - function showColumn(dataTable, chart, activColumns, series, col, show) { - seriesCol = 0 - for (i = 0; i < col; i++) - if (dataTable.getColumnType(i) == 'number') - seriesCol++ - if (!show) { - activColumns[col] = { - label: dataTable.getColumnLabel(col), - type: dataTable.getColumnType(col), - calc: function () { - return null; - } - }; - series[seriesCol].color = '#CCCCCC'; - } - else { - activColumns[col] = col; - series[seriesCol].color = null; - } - } - - function showAllColumns(dataTable, chart, activColumns, series, show) { - for (var i = 1; i < dataTable.getNumberOfColumns(); i++) { - if (dataTable.getColumnType(i) == 'number') - showColumn(dataTable, chart, activColumns, series, i, show) - } - } - - function handle_selection(sel, dataTable, series, activColumns, chart) { - var col = sel[0].column; - - var allActive = true; - for (var i = 1; i < dataTable.getNumberOfColumns(); i++) { - if (dataTable.getColumnType(i) == 'number' && activColumns[i] != i) { - allActive = false; - } - } - if (activColumns[col] == col) { - // The clicked columns is active - if (allActive) { - showAllColumns(dataTable, chart, activColumns, series, false); - showColumn(dataTable, chart, activColumns, series, col, true); - } else { - showColumn(dataTable, chart, activColumns, series, col, false); - } - } - else { - // The clicked columns is inactive, show it - showColumn(dataTable, chart, activColumns, series, col, true); - } - - var activeColsCount = 0; - for (var i = 1; i < dataTable.getNumberOfColumns(); i++) { - if (dataTable.getColumnType(i) == 'number' && activColumns[i] == i) { - activeColsCount++; - } - } - if (activeColsCount == 0) - showAllColumns(dataTable, chart, activColumns, series, true); - - return activeColsCount - } - - function adjustChartSize(id_chart, reportsCount, benchmarkCount) { - var size = 75 + reportsCount * (25 + (benchmarkCount * 8)); - id_chart.style.height = size + "px"; - id_chart.style.width = "100%"; - } - - function trendUnselect() { - trend_chart.setSelection(null); - } - - function drawTrend() { - var dataTable = new google.visualization.DataTable(); - -<%def name="tooltip_commit_table(commit)">\\ -<h3>${db["commits"][commit]['commit'].full_name.replace('"', '"')} <span class='close_button' onclick='javascript:trendUnselect();' title='Close this tooltip'>[X]</span></h3>\\ -<h4>Commit\\ -% if 'commit_url' in db: - (<a href='${db["commit_url"].format(commit=commit)}' target='_blank'>URL</a>)\\ -% endif -</h4><table>\\ -<tr><td><b>Author:</b></td><td>${cgi.escape(db["commits"][commit]['commit'].author)}</td></tr>\\ -<tr><td><b>Commit date:</b></td><td>${db["commits"][commit]['commit'].commit_date}</td></tr>\\ -<tr><td><b>Build exit code:</b></td><td bgcolor='${db["commits"][commit]['build_color']}'><center>${db["commits"][commit]['build_error']}</center></td></tr>\\ -% if len(db["commits"][commit]['commit'].bugs) > 0: -<tr><td><b>Referenced bugs</b></td><td><ul>\\ -% for bug in db["commits"][commit]['commit'].bugs: -<li><a href='${bug.replace('"', '"')}' target='_blank'>${bug.replace('"', '"')}</a></li>\\ -% endfor -</ul></td></tr>\\ -% endif -% if hasattr(db["commits"][commit]['commit'], "annotation_long"): -<tr><td><b>Annotation:</b></td><td>${cgi.escape(db["commits"][commit]['commit'].annotation_long)}</td></tr>\\ -% endif -</table>\\ -</%def> - -% if len(db['reports']) > 1: - dataTable.addColumn('string', 'Commit'); - dataTable.addColumn({type: 'string', role: 'tooltip', p: { html: true }}); - % for report in db["reports"]: - dataTable.addColumn('number', '${report}'); - % endfor - dataTable.addRows([ - % for commit in db["commits"]: - ['${commit}', "${tooltip_commit_table(commit)}<h4>Perf</h4><table>\\ -% for report in db["reports"]: -% if report in db["commits"][commit]['reports']: -<tr><td><b>${report}:</b></td><td>${db["commits"][commit]['reports'][report]["average"]} ${output_unit}</td></tr>\\ -% endif -% endfor -</table><p></p>"\\ - % for report in db["reports"]: - % if report in db["commits"][commit]['reports']: -, ${db["commits"][commit]['reports'][report]["average"]}\\ - % else: -, null\\ - % endif - % endfor -], - % endfor - ]); -% else: - <% - report = db["reports"][0] - %> - dataTable.addColumn('string', 'Commits'); - dataTable.addColumn({type: 'string', role:'annotation'}); - % for benchmark in db["benchmarks"]: - dataTable.addColumn('number', '${benchmark}'); - dataTable.addColumn({type: 'string', role: 'tooltip', p: { html: true }}); - % endfor - - dataTable.addRows([ - % for commit in db["commits"]: -["${commit}"\\ - % if hasattr(db["commits"][commit]['commit'], 'annotation'): -, "${db["commits"][commit]['commit'].annotation}"\\ - %else: -, null\\ - % endif - % for benchmark in db["benchmarks"]: - % if benchmark in db["commits"][commit]['reports'][report]: -<% - result = db["commits"][commit]['reports'][report][benchmark] - diff_target = result.average * 100 / db['targets'][benchmark] - diff_target = "{0:.2f}".format(diff_target) -%>\\ -, ${diff_target}, "${tooltip_commit_table(commit)}<h4>Perf</h4><table><tr><td><b>Target</b></td><td>${diff_target} %</td></tr><tr><td><b>Raw value</b></td><td>${result.average} ${output_unit} +/- ${result.margin_str}% (n=${len(result.data)})</td></tr></table>"\\ - % else: -, null, "${benchmark}"\\ - % endif - % endfor -], - % endfor - ]); -% endif - - var activColumns = []; - var series = {}; - for (var i = 0; i < dataTable.getNumberOfColumns(); i++) { - activColumns.push(i); - if (i > 0) { - series[i - 1] = {}; - } - } - - var options = { - chart: { - title: 'Performance trend across multiple commits' - }, - % if len(db['reports']) > 1: - focusTarget: 'category', - vAxis: {title: 'Average result (${output_unit})'}, - % else: - annotations: {style: 'line', textStyle: {fontSize: 12}}, - vAxis: {title: '% of target (%)'}, - % endif - legend: { position: 'top', textStyle: {fontSize: 12}, maxLines: 3}, - tooltip: {trigger: 'selection', isHtml: true}, - crosshair: { trigger: 'both' }, - hAxis: {title: 'Commits', slantedText: true, slantedTextAngle: 45}, - series: series, - chartArea: {left:"6%", width:"95%"} - }; - - trend_chart = new google.visualization.LineChart(document.getElementById('trends_chart')); - trend_chart.draw(dataTable, options); - - google.visualization.events.addListener(trend_chart, 'select', function () { - var sel = trend_chart.getSelection(); - // See https://developers.google.com/chart/interactive/docs/reference#visgetselection - if (sel.length > 0 && typeof sel[0].row === 'object') { - handle_selection(sel, dataTable, series, activColumns, trend_chart) - - // Redraw the chart with the masked columns - var view = new google.visualization.DataView(dataTable); - view.setColumns(activColumns); - trend_chart.draw(view, options); - } - - if (sel.length > 0 && typeof sel[0].row === 'number') { - // update the other graph if there were changes - var commit = dataTable.getValue(sel[0].row, 0) - if (commit != currentCommit) { - currentCommit = commit; - drawDetails(); - } - } - - if (sel.length == 0) { - trend_chart.setSelection(null); - } - }); - } - - function drawDetails() { - var dataTable = new google.visualization.DataTable(); - dataTable.addColumn('string', 'Report'); - dataTable.addColumn('number', 'Average'); - dataTable.addColumn({type: 'string', role: 'tooltip', p: { html: true }}); - % for benchmark in db["benchmarks"]: - dataTable.addColumn('number', '${benchmark}'); - dataTable.addColumn({type: 'string', role: 'tooltip', p: { html: true }}); - % endfor - - % for commit in db["commits"]: - if (currentCommit == "${commit}") { - dataTable.addRows([ - % for report in db["reports"]: - % if report in db["commits"][commit]['reports']: - ["${report}", ${db["commits"][commit]['reports'][report]["average"]}, "<h3>${report} - Average</h3><p>\\ - % for r in db["reports"]: -<% - if not r in db["commits"][commit]: - continue - if db["commits"][commit]['reports'][report]["average"] != 0: - diff = db["commits"][commit]['reports'][r]["average"] / db["commits"][commit]['reports'][report]["average"] * 100 - diff = float("{0:.2f}".format(diff)) - else: - diff = "ERR" - btag = btagend = "" - if r == report: - btag="<b>" - btagend="</b>" - %>\\ -${btag}${r}: ${db["commits"][commit]['reports'][r]["average"]} ${output_unit} (${diff}%)${btagend}<br/>\\ - % endfor -</p>"\\ - % for benchmark in db["benchmarks"]: - % if benchmark in db["commits"][commit]['reports'][report]: -, ${db["commits"][commit]['reports'][report][benchmark].average}, "<h3>${report} - ${benchmark}</h3><p>\\ - % for r in db["reports"]: -<% - if not r in db["commits"][commit]['reports'] or benchmark not in db["commits"][commit]['reports'][r]: - continue - if db["commits"][commit]['reports'][report][benchmark].average != 0: - diff = db["commits"][commit]['reports'][r][benchmark].average / db["commits"][commit]['reports'][report][benchmark].average * 100 - diff = float("{0:.2f}".format(diff)) - else: - diff = "ERR" - btag = btagend = "" - if r == report: - btag="<b>" - btagend="</b>" - %>\\ -${btag}${r}: ${db["commits"][commit]['reports'][r][benchmark].average} ${output_unit} (${diff}%)${btagend}<br/>\\ - % endfor -</p>"\\ - % else: -, null, "${benchmark}"\\ - % endif - % endfor -], - % endif - % endfor - ]); - } - % endfor - - // adjust the size of the chart to fit the data - adjustChartSize(details_chart, dataTable.getNumberOfRows(), Math.floor(dataTable.getNumberOfColumns() / 2)); - - var activColumns = []; - var series = {}; - for (var i = 0; i < dataTable.getNumberOfColumns(); i++) { - activColumns.push(i); - if (i > 0) { - series[i - 1] = {}; - } - } - series[0] = {type: 'line'}; - - - var options = { - title : 'Performance of commit ' + currentCommit, - legend: {textStyle: {fontSize: 12}}, - tooltip: {trigger: 'focus', isHtml: true}, - vAxis: {title: 'Reports', textStyle: {fontSize: 12}}, - hAxis: {title: 'Average result (${output_unit})', textStyle: {fontSize: 12}}, - seriesType: 'bars', - orientation: 'vertical', - series: series - }; - - var chart = new google.visualization.ComboChart(document.getElementById('details_chart')); - chart.draw(dataTable, options); - - google.visualization.events.addListener(chart, 'select', function () { - var sel = chart.getSelection(); - // See https://developers.google.com/chart/interactive/docs/reference#visgetselection - if (sel.length > 0 && typeof sel[0].row === 'object') { - activeCols = handle_selection(sel, dataTable, series, activColumns, chart) - - // reduce the size of the chart to fit the data - adjustChartSize(details_chart, dataTable.getNumberOfRows(), activeCols); - - // Redraw the chart with the masked columns - var view = new google.visualization.DataView(dataTable); - view.setColumns(activColumns); - chart.draw(view, options); - } - - if (sel.length == 0) { - chart.setSelection(null); - } - }); - } - </script> - </head> - - <body> - <h1>${title}</h1> - - <h2>Trends</h2> - - <center><div id="trends_chart" style="width: 100%; height: 500px;"></div></center> - - <h2>Details</h2> - - <center><div id="details_chart" style="width: 100%; height: 500px;"></div></center> - - <h2>Benchmarks</h2> - - % for benchmark in db["benchmarks"]: - <h3>${benchmark.capitalize()}</h3> - - <div class="css-treeview"> - <%def name="outputtreenode(node, id, label, attr = '')"> - <li><input type="checkbox" id="${id}" ${attr}/><label class="env_node" for="${id}">+${label}</label><ul> - <table> - % for child in sorted(node): - % if type(node[child]) is str: - <tr><td>${child}</td><td>${node[child]}</td></tr> - % endif - % endfor - </table> - % for child in sorted(node): - % if type(node[child]) is not str: - ${outputtreenode(node[child], "{}.{}".format(id, child.replace(' ', '_')), child, '')} - % endif - % endfor - </ul></li> - </%def> - - <ul> - ${outputtreenode(db["envs"][benchmark], benchmark + "_envroot", "Environment", 'checked="checked"')} - </ul> - </div> - - <table> - <tr> - <th>Key</th> - % for env_set in db["env_sets"][benchmark]: - <% - users = "" - for user in env_set['users']: - if len(users) > 0: - users += "<br/>" - users += "{}.{}#{}".format(user['log_folder'], user['commit'].sha1, user['run']) - %>\\ - <th>${users}</th> - % endfor - </tr> - % for key in db["env_diff_keys"][benchmark]: - <tr> - <td>${key}</td> - % for env_set in db["env_sets"][benchmark]: - % if key in dict(env_set['set']): - <td>${dict(env_set['set'])[key]}</td> - % else: - <td>MISSING</td> - % endif - % endfor - </tr> - % endfor - </table> - % endfor - - <h2>Events</h2> - - % for report in db['events']: - <h3>${report}</h3> - <ul> - % for event in db['events'][report]: - <li>${event}</li> - % endfor - </ul> - % endfor - </body> - -</html> -""" - - -# Create the html file -print("Generating the HTML") - -if args.title is not None: - title = args.title -else: - title = "Performance report on the run named '{run_name}'".format(run_name=report_name) - -html = Template(html_template).render(title=title, db=db, output_unit=output_unit, - default_commit=list(db["commits"])[-1]) - -with open(args.output, 'w') as f: - f.write(html) - print("Output HTML generated at: {0}".format(args.output)) diff --git a/stats/gen_report.py b/stats/gen_report.py deleted file mode 100755 index 086a62a..0000000 --- a/stats/gen_report.py +++ /dev/null @@ -1,485 +0,0 @@ -#!/usr/bin/env python3 - -""" -Copyright (c) 2015, Intel Corporation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -""" - -from matplotlib.patches import Rectangle -import matplotlib.gridspec as gridspec -import matplotlib.pyplot as plt -from scipy.stats import gaussian_kde -from mako.template import Template -import argparse -import sys -import os - -# Import ezbench from the utils/ folder -sys.path.append(os.path.abspath(sys.path[0]+'/../utils/')) -from ezbench import * - -# constants -html_name="index.html" -report_folder="ezbench_report/" - -def genFileNameReportImg(report_folder, data_raw_file): - return report_folder + data_raw_file + ".svg" - -def genFileNameSparkline(report_folder, data_raw_file): - return report_folder + data_raw_file + ".spark.svg" - -# parse the options -parser = argparse.ArgumentParser() -parser.add_argument("--fast", help="Fast mode, do not regenerate images if they exist", - action="store_true") -parser.add_argument("--title", help="Set the title for the report") -parser.add_argument("log_folder") -args = parser.parse_args() - -# Parse the report -report = genPerformanceReport(args.log_folder) - -# Generate the labels for the commits -commitsLabels = [] -for commit in report.commits: - commitsLabels.append(commit.label) - -# Create a folder for the results -os.chdir(args.log_folder) -if not os.path.isdir(report_folder): - try: - os.mkdir(report_folder) - except OSError: - print ("Error while creating the report folder") - -def kde_scipy(x, x_grid, bandwidth=0.2, **kwargs): - kde = gaussian_kde(x, bw_method=bandwidth, **kwargs) - return kde.evaluate(x_grid) - -# Generate the spark lines -print("Generating the sparklines",end="",flush=True) -for commit in report.commits: - for result in commit.results: - sparkFile = genFileNameSparkline(report_folder, result.data_raw_file) - if args.fast and os.path.isfile(sparkFile): - continue - - fig, ax = plt.subplots(1,1,figsize=(1.25,.3)) - r_max = amax(result.data) - if r_max > 0: - plt.ylim(0, r_max) - plt.plot(result.data, linewidth=0.8) - - # remove all the axes - plt.axis('off') - for k,v in ax.spines.items(): - v.set_visible(False) - ax.set_xticks([]) - ax.set_yticks([]) - - plt.savefig(sparkFile, bbox_inches='tight', transparent=True) - plt.close() - print('.',end="",flush=True) -print(" DONE") - - -# Generate the large images -plt.rcParams.update({'font.size': 9}) -print("Generating the runs' output image",end="",flush=True) -for c in range (0, len(report.commits)): - commit = report.commits[c] - for r in range (0, len(commit.results)): - result = commit.results[r] - img_src_name = genFileNameReportImg(report_folder, result.data_raw_file) - if args.fast and os.path.isfile(img_src_name): - continue - - try: - f = plt.figure(figsize=(19.5, 4)) - gs = gridspec.GridSpec(2, 2, width_ratios=[4, 1]) - x = array(result.data) - ax1 = plt.subplot(gs[0]) - unit_dir = "more is better" - if result.more_is_better: - unit_dir = "less is better" - plt.title("Time series across all the runs ({0})".format(unit_dir)) - plt.xlabel('Run #') - plt.ylabel(result.unit_str) - - YAvg = mean(x) - boxYMin = YAvg * 0.99 - boxYMax = YAvg * 1.01 - ax1.plot(x, label="cureport.") - ax1.add_patch(Rectangle((0, boxYMin), len(x), boxYMax - boxYMin, alpha=.2, facecolor="green", label="2% box")) - if c > 0: - ax1.plot(report.commits[c - 1].results[r].data, label="prev.") - plt.legend() - - ax2 = plt.subplot(gs[1]) - plt.title("Run histogram") - plt.ylabel("Occurrence count") - plt.xlabel(result.unit_str) - x_grid = linspace(amin(x) * 0.95, amax(x) * 1.05, 1000) - for bandwidth in [0.2]: - ax2.plot(x_grid, kde_scipy(x, x_grid, bandwidth=bandwidth), - label='bw={0}'.format(bandwidth), linewidth=1, alpha=1) - ax2.hist(x, 100, fc='gray', histtype='stepfilled', alpha=0.3, normed=True, label='histogram') - - ax3 = plt.subplot(gs[2]) - plt.xlabel('Sample #') - plt.ylabel(result.unit_str) - - samples_total = [] - for i in range(0, len(result.runs)): - samples_total.extend(result.runs[i]) - ax3.plot(result.runs[i], label="{0}".format(i)) - if len(result.runs) <= 40: - plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3, ncol=20, mode="expand", borderaxespad=0.) - - ax4 = plt.subplot(gs[3]) - plt.title("Sample Histogram") - plt.ylabel("Occurrence count") - plt.xlabel(result.unit_str) - x_grid = linspace(amin(samples_total) * 0.95, amax(samples_total) * 1.05, 1000) - for bandwidth in [0.2]: - ax4.plot(x_grid, kde_scipy(samples_total, x_grid, bandwidth=bandwidth), - label='bw={0}'.format(bandwidth), linewidth=1, alpha=1) - ax4.hist(samples_total, 100, fc='gray', histtype='stepfilled', alpha=0.3, normed=True, label='histogram') - - plt.tight_layout() - plt.savefig(img_src_name, bbox_inches='tight') - except Exception as e: - exc_type, exc_obj, exc_tb = sys.exc_info() - fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] - print("Failed to generate {filename}: {error} at {fname}:{line}".format(filename=img_src_name, - error=str(e), fname=fname, - line=exc_tb.tb_lineno)) - plt.close() - print('.',end="",flush=True) -print(" DONE") - -# Generate the report -html_template=""" -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" -"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - -<html xmlns="http://www.w3.org/1999/xhtml"> - - <head> - <title>${title}</title> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - <style> - body {{ font-size: 10pt}} - </style> - <script type="text/javascript" src="https://www.google.com/jsapi"></script> - <script type="text/javascript"> - google.load('visualization', '1', {packages: ['corechart']}); - google.setOnLoadCallback(drawTrend); - - function showColumn(dataTable, chart, activColumns, series, col, show) { - var seriesIndex = Math.floor(col / 2) - if (!show) { - activColumns[col] = { - label: dataTable.getColumnLabel(col), - type: dataTable.getColumnType(col), - calc: function () { - return null; - } - }; - series[seriesIndex].color = '#CCCCCC'; - } - else { - activColumns[col] = col; - series[seriesIndex].color = null; - } - } - - function showAllColumns(dataTable, chart, activColumns, series, show) { - for (var i = 1; i < dataTable.getNumberOfColumns(); i+=2) { - showColumn(dataTable, chart, activColumns, series, i, show) - } - } - - function drawTrend() { - var dataTable = new google.visualization.DataTable(); - dataTable.addColumn('string', 'Commit'); - % for benchmark in benchmarks: - dataTable.addColumn('number', '${benchmark.full_name}'); - dataTable.addColumn({ type: "string", role: "tooltip", p: { html: true }}); - % endfor - dataTable.addRows([ - % for commit in commits: - ['${commit.label}', - % for benchmark in benchmarks: - <% - result = None - for res in commit.results: - if res.benchmark == benchmark: - result = res - sparkline_img = report_folder + result.data_raw_file + ".spark.svg" - break - %> - % if result != None: - ${result.diff_absolute}, "<h2>${commit.label} - ${benchmark.full_name}</h2><p>Commit SHA1: <a href='#commit_${commit.sha1}'>${commit.sha1}</a></p><p>Value: ${result.diff_absolute} % (Diff with prev.: ${result.diff} %)</p><p>Raw data point: ${result.value} ${result.unit_str}</p><p><a href='#commit_${commit.sha1}_bench_${benchmark.full_name}'><img src='${sparkline_img}' alt='Sparkline of the performance' /><br/>View more data</a></p>", - % else: - null, "<h2>${commit.label} - ${benchmark.full_name}</h2><p>Commit SHA1: <a href='#commit_${commit.sha1}'>${commit.sha1}</a></p><p>NO DATA</p>", - % endif - % endfor - ], - % endfor - ]); - - var activColumns = []; - var series = {}; - for (var i = 0; i < dataTable.getNumberOfColumns(); i++) { - activColumns.push(i); - if (i > 0) { - series[i - 1] = {}; - } - } - - var options = { - chart: { - title: 'Performance trend across multiple commits' - }, - legend: { position: 'top', textStyle: {fontSize: 12}, maxLines: 3}, - focusTarget: 'datum', - tooltip: {trigger: 'selection', isHtml: true}, - crosshair: { trigger: 'both' }, - hAxis: {title: 'Commits', slantedText: true, slantedTextAngle: 45}, - vAxis: {title: 'Perf. diff. with the first commit (%)'}, - series: series, - chartArea: {left:"5%", width:"95%"} - }; - - var chart = new google.visualization.LineChart(document.getElementById('trends_chart')); - chart.draw(dataTable, options); - - google.visualization.events.addListener(chart, 'select', function () { - var sel = chart.getSelection(); - // See https://developers.google.com/chart/interactive/docs/reference#visgetselection - if (sel.length > 0 && typeof sel[0].row === 'object') { - var col = sel[0].column; - - var allActive = true; - for (var i = 1; i < dataTable.getNumberOfColumns(); i+=2) { - if (activColumns[i] != i) { - allActive = false; - } - } - if (activColumns[col] == col) { - // The clicked columns is active - if (allActive) { - showAllColumns(dataTable, chart, activColumns, series, false); - showColumn(dataTable, chart, activColumns, series, col, true); - } else { - showColumn(dataTable, chart, activColumns, series, col, false); - } - } - else { - // The clicked columns is inactive, show it - showColumn(dataTable, chart, activColumns, series, col, true); - } - - var allHidden = true; - for (var i = 1; i < dataTable.getNumberOfColumns(); i+=2) { - if (activColumns[i] == i) { - allHidden = false; - } - } - if (allHidden) - showAllColumns(dataTable, chart, activColumns, series, true); - - // Redraw the chart with the masked columns - var view = new google.visualization.DataView(dataTable); - view.setColumns(activColumns); - chart.draw(view, options); - } - - if (sel.length == 0) { - chart.setSelection(null); - } - }); - } - </script> - </head> - - <%def name="makeTableheader(benchmarks)"> - <tr> - <th>Commit</th> - <th>Geometric mean</th> - % for benchmark in benchmarks: - <th>${benchmark.full_name} (${benchmark.unit_str})</th> - % endfor - </tr> - </%def> - - <%def name="makeCommitRow(commit, benchmarks)"> - <tr> - <td><a href="#commit_${commit.sha1}">${commit.label}</a></td> - <td bgcolor="${commit.geom_color}">${commit.geom} (${commit.geom_diff} %)</td> - % for benchmark in benchmarks: - <% - result = None - for res in commit.results: - if res.benchmark == benchmark: - result = res - sparkline_img = report_folder + result.data_raw_file + ".spark.svg" - break - %> - % if result != None and result.value != None: - <td bgcolor="${result.color}"> - <a href="#commit_${commit.sha1}_bench_${benchmark.full_name}"> - ${result.value} (${result.diff} %) - <img src="${sparkline_img}" alt="Test's time series and density of probability" /> - <a/> - </td> - % else: - <td bgcolor="#FFFF00"><center>NO DATA</center></td> - % endif - % endfor - </tr> - </%def> - - <body> - <h1>${title}</h1> - - <h2>Trends</h2> - - <center><div id="trends_chart" style="width: 100%; height: 500px;"></div></center> - - % if len(notes) > 0: - <h2>Notes</h2> - <ul> - % for note in notes: - <li>${note}</li> - % endfor - </ul> - % endif - - <h2>Stats</h2> - - <table border="1" style=""> - ${makeTableheader(benchmarks)} - % for commit in commits: - ${makeCommitRow(commit, benchmarks)} - % endfor - </table> - - <h2>Commits</h2> - % for commit in commits: - <h3 id="commit_${commit.sha1}">${commit.label} - ${commit.full_name}</h3> - <p><a href="${commit.patch}">Patch</a> <a href="${commit.compile_log}">Compilation logs</a></p> - <table border="1" style=""> - ${makeTableheader(benchmarks)} - ${makeCommitRow(commit, benchmarks)} - </table> - - % for benchmark in benchmarks: - <% - result = None - for res in commit.results: - if res.benchmark == benchmark: - result = res - sparkline_img = report_folder + result.data_raw_file + ".spark.svg" - break - %> - % if result != None and result.value != None: - <h4 id="commit_${commit.sha1}_bench_${benchmark.full_name}">${benchmark.full_name} (commit <a href="#commit_${commit.sha1}">${commit.full_name}</a>)</h4> - - <p><a href="${result.data_raw_file}">Original data</a></p> - - <img src="${result.img_src_name}" alt="Test's time series and density of probability" /> - % endif - % endfor - % endfor - </body> - -</html> -""" - -def computeDiffAndColor(prev, new): - if prev > 0: - diff = (new * 100.0 / prev) - 100.0 - else: - diff = 0 - - diff = float("{0:.2f}".format(diff)) - - if diff < -1.5 or diff == float('inf'): - color = "#FF0000" - elif diff > 1.5: - color = "#00FF00" - else: - color = "#FFFFFF" - - return diff, color - - -# Create the html file -print("Generating the HTML") - -if args.title is not None: - title = args.title -else: - title = "Performance report on the run named '{run_name}'".format(run_name=args.log_folder) - -geom_prev = -1 -for commit in report.commits: - benchs_txt = "" - tbl_res_benchmarks = "" - for benchmark in report.benchmarks: - result = None - for res in commit.results: - if res.benchmark == benchmark: - result = res - break - - if result != None: - result.value = float("{0:.2f}".format(array(result.data).mean())) - if not hasattr(result.benchmark, "first_value"): - result.benchmark.first_value = result.value - result.diff, result.color = computeDiffAndColor(result.benchmark.prevValue, - result.value) - result.diff_absolute, useless_color = computeDiffAndColor(result.benchmark.first_value, - result.value) - result.benchmark.prevValue = result.value - - result.img_src_name = genFileNameReportImg(report_folder, result.data_raw_file) - result.sparkline_img = genFileNameSparkline(report_folder, result.data_raw_file) - - commit.geom = float("{0:.2f}".format(commit.geom_mean())) - commit.geom_diff, commit.geom_color = computeDiffAndColor(geom_prev, commit.geom) - geom_prev = commit.geom - -html = Template(html_template).render(title=title, - report_folder=report_folder, - benchmarks=report.benchmarks, - commits=report.commits, - notes=report.notes) - -with open(html_name, 'w') as f: - f.write(html) - print("Output HTML generated at: {0}/{1}".format(os.getcwd(), html_name)) diff --git a/stats/test_report.R b/stats/test_report.R deleted file mode 100755 index 6f1ac93..0000000 --- a/stats/test_report.R +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/Rscript - -# Copyright (c) 2015, Intel Corporation -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of Intel Corporation nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -args <- commandArgs(trailingOnly = TRUE) -if(length(args) != 2) { - cat("Usage:\n\t./test_report.R input.csv output.png\n\n") - q(save="no") -} - -data <- read.csv(args[1]) - -d <- density(data[[1]]) - -png(args[2], width = 1900, height = 200) - -layout(matrix(c(1,2), 1), c(3.5,1), c(1,3)) -par(mar=c(4.3, 4.3, 2.0, 0.1)) - -plot(data[[1]], ylab="FPS", xlab="FPS sample", main="Time series of the FPS", - cex.lab=1.5, cex.axis=1.5, cex.main=1.5, cex.sub=1.5) -lines(data[[1]], type="l") -abline(h=mean(data[[1]]),col=4) -abline(h=median(data[[1]]),col=2) - -plot(d, xlab="FPS", main="Density function of the FPS", cex.lab=1.5, - cex.axis=1.5, cex.main=1.5, cex.sub=1.5) -abline(v=mean(data[[1]]),col=4) -abline(v=median(data[[1]]),col=2) diff --git a/tests.d/beignet/finance.test b/tests.d/beignet/finance.test deleted file mode 100644 index eda14ea..0000000 --- a/tests.d/beignet/finance.test +++ /dev/null @@ -1,31 +0,0 @@ -# https://github.com/cavazos-lab/FinanceBench - -test -d ${FINANCEBENCH_FOLDER} || return 1 - -# Typical output (Black-Scholes): -# Number of options: 5000000 -# -# number of platforms is 1 -# platform name is Intel Gen OCL Driver -# platform version is OpenCL 1.2 beignet 1.2 (git-7b151ad) -# number of devices is 1 -# device name is Intel(R) HD Graphics Haswell GT2 Desktop -# -# Run on GPU -# Summation of all output prices on GPU: 30030504.000000 -# Output price for option 2500000 on GPU: 0.040781 -# Processing time on GPU: 47.405998 - -__finance__() { - cd $(dirname $1) - run_bench 0 ./$(basename $1) | sed '/Processing time/!d; s/.*://' || return 1 -} - -for exe in $(find ${FINANCEBENCH_FOLDER} -name '*.exe'); do - name=$(sed "s#${FINANCEBENCH_FOLDER}/\([^/]*\).*#\1#" <<< $exe) - test_name="$test_name finance:$name" - eval "finance:${name}_run() { __finance__ $exe; }" -done -test_exec_time=2 -test_invert=1 # output is duration in milliseconds -test_unit="ms" diff --git a/tests.d/beignet/luxmark.test b/tests.d/beignet/luxmark.test deleted file mode 100644 index 69ea3ef..0000000 --- a/tests.d/beignet/luxmark.test +++ /dev/null @@ -1,20 +0,0 @@ -xdpyinfo >/dev/null 2>&1 || return 1 # LuxMark expects an X connection -test -e "$LUXMARK_FOLDER/luxmark.bin" || return 1 - -__luxmark__() { - cd $LUXMARK_FOLDER # set me in test_options.sh! - LD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATH \ - run_bench 0 ./luxmark.bin --single-run --mode=BENCHMARK_OCL_GPU --scene=$1 \ - | awk '{print $2 }' || return 1 -} - -while read name scene; do - test_name="$test_name luxmark:$name" - eval "luxmark:${name}_run() { __luxmark__ $scene; }" -done<<EOF - LuxBall LUXBALL_HDR - Microphone MICROPHONE - Hotel HOTEL -EOF - -test_exec_time=121 diff --git a/tests.d/beignet/polybench.test b/tests.d/beignet/polybench.test deleted file mode 100644 index 81da100..0000000 --- a/tests.d/beignet/polybench.test +++ /dev/null @@ -1,26 +0,0 @@ -# https://github.com/cavazos-lab/PolyBench-ACC - -test -d ${POLYBENCH_ACC_FOLDER}/OpenCL || return 1 - -# Typical output (adi): -# number of platforms is 1 -# platform name is Intel Gen OCL Driver -# platform version is OpenCL 1.2 beignet 1.2 (git-7b151ad) -# device id is 1354742880 -# device name is Intel(R) HD Graphics Haswell GT2 Desktop -# GPU Time in seconds: -# 0.153892 - -__polybench__() { - cd $(dirname $1) - run_bench 0 ./$(basename $1) | tail -n 1 || return 1 -} - -for exe in $(find ${POLYBENCH_ACC_FOLDER}/OpenCL -name '*.exe'); do - name="polybench:$(basename $exe .exe)" - test_name="$test_name $name" - eval "${name}_run() { __polybench__ $exe; }" -done -test_exec_time=20 -test_invert=1 # output is duration in seconds -test_unit="s" diff --git a/tests.d/gem/gem_create.test b/tests.d/gem/gem_create.test deleted file mode 100644 index 5bbc021..0000000 --- a/tests.d/gem/gem_create.test +++ /dev/null @@ -1,8 +0,0 @@ -test_exec_time=2 - -[ -e $IGT_BENCHMARKS/gem_create ] || return 1 -sudo -n true || return 1 - -test_name="gem:create:4k gem:create:4M" -gem:create:4k_run() { run_bench 0 sudo $IGT_BENCHMARKS/gem_create -s 4096 -r 1; } -gem:create:4M_run() { run_bench 0 sudo $IGT_BENCHMARKS/gem_create -s 4194304 -r 1; } diff --git a/tests.d/gem/gem_exec_ctx.test b/tests.d/gem/gem_exec_ctx.test deleted file mode 100644 index d9f7d0a..0000000 --- a/tests.d/gem/gem_exec_ctx.test +++ /dev/null @@ -1,18 +0,0 @@ -# This outputs a graph of time(N), the us it takes to execute N empty batches -# performing the associated context operation each time. -# e.g. 110 59 34 22 16 13 11 10 10 10 9 4 1.4 1.4 1.2 0.9 0.8 -# As a summary, print the number of nop/s (so that it matches the bigger is -# better motif of fps). - -[ -e $IGT_BENCHMARKS/gem_exec_ctx ] || return 1 -sudo -n true || return 1 - -for i in nop switch create; do - name="gem:exec:ctx:$i" - test_name="$test_name $name" - eval "${name}_run() { run_bench 0 sudo $IGT_BENCHMARKS/gem_exec_ctx -b $i -r 3; }" - eval "${name}_process() { bc -l <<< \"1000000 / \${@: -1}\"; }" -done - -test_exec_time=55 -test_unit="µs" diff --git a/tests.d/gem/gem_exec_nop.test b/tests.d/gem/gem_exec_nop.test deleted file mode 100644 index 5019a50..0000000 --- a/tests.d/gem/gem_exec_nop.test +++ /dev/null @@ -1,18 +0,0 @@ -test_name=gem:exec:nop -test_exec_time=18 - -# This outputs a graph of time(N), the us it takes to execute N empty batches. -# e.g. 110 59 34 22 16 13 11 10 10 10 9 4 1.4 1.4 1.2 0.9 0.8 -# As a summary, print the number of nop/s (so that it matches the bigger is -# better motif of fps). -# -# Ideally we want to run this per ring, -# gem_exec_nop:rcs, gem_exec_nop:bcs, gem_exec_nop:vcs -# though for the time being just one will suffice - -[ -e $IGT_BENCHMARKS/gem_exec_nop ] || return 1 -sudo -n true || return 1 - -gem:exec:nop_run() { run_bench 0 sudo $IGT_BENCHMARKS/gem_exec_nop -e 1 -r 3; } -gem:exec:nop_process() { bc -l <<< "1000000 / ${@: -1}"; } -test_unit="µs" diff --git a/tests.d/gem/gem_exec_reloc.test b/tests.d/gem/gem_exec_reloc.test deleted file mode 100644 index c2e7c08..0000000 --- a/tests.d/gem/gem_exec_reloc.test +++ /dev/null @@ -1,19 +0,0 @@ -test_exec_time=2 -test_invert=1 -test_unit="µs" - -[ -e $IGT_BENCHMARKS/gem_exec_reloc ] || return 1 -sudo -n true || return 1 - -for i in old lut; do - for j in busy cyclic fault skip none; do - for k in constant sequential reverse random; do - for b in 2 4096; do - test_name="$test_name gem:exec:reloc:$i:$j:$k:$b" - eval "gem:exec:reloc:${i}:${j}:${k}:${b}_run() { run_bench 0 sudo $IGT_BENCHMARKS/gem_exec_reloc -s 65536 -m $i -e $j -o $k -l 1 -b $b -r 4096 ; } " - done - done - done - test_name="$test_name gem:exec:reloc:$i:0:8192" - eval "gem:exec:reloc:${i}:0:8192_run() { run_bench 0 sudo $IGT_BENCHMARKS/gem_exec_reloc -s 4096 -m $i -e none -o constant -l 1 -b 8192 -r 0 ; } " -done diff --git a/tests.d/gem/gem_exec_trace.test b/tests.d/gem/gem_exec_trace.test deleted file mode 100644 index 56cf918..0000000 --- a/tests.d/gem/gem_exec_trace.test +++ /dev/null @@ -1,18 +0,0 @@ -[ -e $IGT_BENCHMARKS/gem_exec_trace ] || return 1 -sudo -n true || return 1 - -function __trace__ { - sudo $IGT_BENCHMARKS/gem_exec_trace $IGT_TRACES/$1.gem_exec_trace >/dev/null - run_bench 0 sudo $IGT_BENCHMARKS/gem_exec_trace $IGT_TRACES/$1.gem_exec_trace | sed 's/.*: //' -} - -for i in $IGT_TRACES/*.gem_exec_trace; do - trace=$(basename $i .gem_exec_trace) - name=gem:exec:trace:$trace - test_name="$test_name $name" - eval "${name}_run() { __trace__ $trace; }" -done - -test_exec_time=4 -test_invert=1 -test_unit="ms" diff --git a/tests.d/gem/gem_mmap.test b/tests.d/gem/gem_mmap.test deleted file mode 100644 index 51d2b06..0000000 --- a/tests.d/gem/gem_mmap.test +++ /dev/null @@ -1,20 +0,0 @@ -# This outputs a graph of time(N), the us it takes to read/write 1<<N bytes. -# e.g. 0 1 2 4 8 16 32 -# The last value is for 4M, convert that to MiB/s for comparison - -[ -e $IGT_BENCHMARKS/gem_mmap ] || return 1 -sudo -n true || return 1 - -for i in cpu gtt wc; do - for j in fault clear write read; do - for k in none x y; do - test_name="$test_name gem:mmap:$i:$j:$k" - eval "gem:mmap:${i}:${j}:${k}_run() { run_bench 0 sudo $IGT_BENCHMARKS/gem_mmap -m $i -d $j -t $k -r 300 ; } " - - eval "gem:mmap:${i}:${j}:${k}_process() { bc -l <<< \" 4*1000000 / \${@: -1} \" ; }" - done - done -done - -test_exec_time=1 -test_unit="µs" diff --git a/tests.d/gem/gem_prw.test b/tests.d/gem/gem_prw.test deleted file mode 100644 index 45edf32..0000000 --- a/tests.d/gem/gem_prw.test +++ /dev/null @@ -1,21 +0,0 @@ -# This outputs a graph of time(N), the time it takes to write 1<<N bytes in us. -# e.g. 0 1 2 4 8 16 32 -# The last value is for 4M, convert that to MiB/s for comparison -# -# Ideally we want to run this per ring, -# gem_exec_nop:rcs, gem_exec_nop:bcs, gem_exec_nop:vcs -# though for the time being just one will suffice - -[ -e $IGT_BENCHMARKS/gem_prw ] || return 1 -sudo -n true || return 1 - -for j in read write; do - for i in cpu gtt; do - test_name="$test_name gem:p$j:$i" - eval "gem:p$j:${i}_run() { run_bench 0 sudo $IGT_BENCHMARKS/gem_prw -D $j -d $i -r 700 ; }" - eval "gem:p$j:${i}_process() { bc -l <<< \" 4*1000000 / \${@: -1} \" ; }" - done -done - -test_exec_time=1 -test_unit="µs" diff --git a/tests.d/internal/citybench.test b/tests.d/internal/citybench.test deleted file mode 100644 index 5e82004..0000000 --- a/tests.d/internal/citybench.test +++ /dev/null @@ -1,13 +0,0 @@ -test_name=citybench -test_exec_time=60 - -test -e "$CITYBENCH_FOLDER/linux_gl/replay_GL_64" || return 1 - -unbuf="stdbuf -o L" - -citybench_run() { - cd "$CITYBENCH_FOLDER" # Set this variable in test_options.sh - cd linux_gl/ - - run_bench $test_exec_time ./replay_GL_64 -f 1478 | $unbuf grep fps | cut -d ' ' -f 1 -} diff --git a/tests.d/internal/synmark.test b/tests.d/internal/synmark.test deleted file mode 100644 index 1479d72..0000000 --- a/tests.d/internal/synmark.test +++ /dev/null @@ -1,24 +0,0 @@ -test -e "$SYNMARK_FOLDER/synmark2" || return 1 - -# 1 argument: $benchmark -function __synmark__ { - cd $SYNMARK_FOLDER # Set this variable in test_options.sh - - run_bench 0 ./synmark2 $1 | grep FPS | cut -d ' ' -f 2 -} - -# 1 argument: $benchmark -function __cpu__ { - cd /tmp # just in case synmark likes emitting stray output files - - INTEL_NO_HW=1 run_bench 0 $SYNMARK_FOLDER/synmark2 $1 | grep FPS | cut -d ' ' -f 2 -} - -for i in $($SYNMARK_FOLDER/synmark2 | tail -n +8); do - test_name="$test_name synmark:$i" - eval "synmark:${i}_run() { __synmark__ $i; }" - - test_name="$test_name synmark:$i:cpu" - eval "synmark:${i}:cpu_run() { __cpu__ $i; }" -done -test_exec_time=15 diff --git a/tests.d/kms/vblank.test b/tests.d/kms/vblank.test deleted file mode 100644 index 299b913..0000000 --- a/tests.d/kms/vblank.test +++ /dev/null @@ -1,13 +0,0 @@ -[ -e $IGT_BENCHMARKS/kms_vblank ] || return 1 -sudo -n true || return 1 - -for j in busy idle; do - for i in query event; do - name="kms:vblank:$i:$j" - test_name="$test_name $name" - eval "${name}_run() { run_bench 0 sudo $IGT_BENCHMARKS/kms_vblank -w $i -b $j -r 1; }" - done -done - -test_exec_time=2 -test_unit="µs" diff --git a/tests.d/mesa/UnrealEngine4.test b/tests.d/mesa/UnrealEngine4.test deleted file mode 100644 index 40b744e..0000000 --- a/tests.d/mesa/UnrealEngine4.test +++ /dev/null @@ -1,33 +0,0 @@ -test -d "$UE4_FOLDER" || return 1 - -# 2 arguments: $benchmark $benchmark_params -__ue4__() { - eval benchmark="$1" - test -d "$benchmark" || return 1 - benchmark=$(find "$benchmark" -type f -executable ! -name CrashReportClient) - - ENV_DUMP_FPS_PRINT_PERIOD_MS=1000 \ - run_bench 60 \"$benchmark\" -NOSOUND -BENCHMARK $2 2>&1 | grep "FPS," | cut -d ',' -f 3 -} - -# 1 argument: $benchmark -__ue4:fullscreen__() { - read width height <<< $(xdpyinfo | sed '/dimensions/!d; s/.*dimensions:\(.*\)x\(.*\) pixels.*/\1 \2/') - __ue4__ "$1" "-ResX=$width -ResY=$height" -} - -# 1 argument: $benchmark -__ue4:window__() { - __ue4__ "$1" "-ResX=$UE4_WINDOW_SIZE_X -ResY=$UE4_WINDOW_SIZE_Y" -} - -eval $(IFS= find "$UE4_FOLDER" -mindepth 1 -maxdepth 1 -type d | \ -while read benchmark; do - name=$(cat "$benchmark"/name 2>/dev/null || basename "$benchmark" | cut -f1 -d\ ) - echo "ue4:${name}:fullscreen_run() { __ue4:fullscreen__ \"\\\"$benchmark\\\"\"; };" - echo "test_name=\"\$test_name ue4:${name}:fullscreen\";" - echo "ue4:${name}:window_run() { __ue4:window__ \"\\\"$benchmark\\\"\"; };" - echo "test_name=\"\$test_name ue4:${name}:window\";" -done; ) - -test_exec_time=60 diff --git a/tests.d/mesa/glbenchmark27.test b/tests.d/mesa/glbenchmark27.test deleted file mode 100644 index be8dcef..0000000 --- a/tests.d/mesa/glbenchmark27.test +++ /dev/null @@ -1,65 +0,0 @@ -GLB27=${GLBENCHMARK27_PATH:-${GLBENCHMARK27_FOLDER}/build_x86_64/binaries/GLBenchmark} -GLB27_DATA=${GLBENCHMARK27_DATA:-${GLBENCHMARK27_FOLDER}/data} - -test -e ${GLB27} || return 1 -xdpyinfo >/dev/null 2>&1 || return 1 - -# Output: -# GLBenchmark 2.5 Egypt HD ETC1 - C24Z16 Onscreen Fixed timestep: 9340 msec (121 fps) - -# Large versions, fullscreen with flipping (seems to be variable size) -# 1 argument: $benchmark -function __gl27fullscreen__ { - local W="${GLBENCHMARK27_WIDTH:-1920}" - local H="${GLBENCHMARK27_HEIGHT:-1080}" - - read width height <<< $(xdpyinfo | sed '/dimensions/!d; s/.*dimensions:\(.*\)x\(.*\) pixels.*/\1 \2/') - - run_bench 0 ${GLB27} -data ${GLB27_DATA} -skip_load_frames \ - -w $width -h $height -ow $W -oh $H -t $1 | \ - sed '/fps/!d; s#.*: \(.*\) msec.*#1000000 / \1#' | bc -l -} - -function __gl27window__ { -# 1 argument: $benchmark - local W="${GLBENCHMARK27_WIDTH:-1920}" - local H="${GLBENCHMARK27_HEIGHT:-1080}" - - read width height <<< $(xdpyinfo | sed '/dimensions/!d; s/.*dimensions:\(.*\)x\(.*\) pixels.*/\1 \2/') - - run_bench 0 ${GLB27} -data ${GLB27_DATA} -skip_load_frames \ - -w $(( $width / 2 )) -h $(( $height / 2 )) -ow $W -oh $H -t $1 | \ - sed '/fps/!d; s#.*: \(.*\) msec.*#1000000 / \1#' | bc -l -} - -# Large versions, offscreen so no flip overhead? -# 1 argument: $benchmark -function __gl27offscreen__ { - local W="${GLBENCHMARK27_WIDTH:-1920}" - local H="${GLBENCHMARK27_HEIGHT:-1080}" - - run_bench 0 ${GLB27} -data ${GLB27_DATA} -skip_load_frames \ - -w $W -h $H -ow $W -oh $H -t $1 | \ - sed '/fps/!d; s#.*: \(.*\) msec.*#1000000 / \1#' | bc -l -} - -# Small versions, to exercise CPU overheads -# 1 argument: $benchmark -function __gl27cpu__ { - INTEL_NO_HW=1 run_bench 0 ${GLB27} -data ${GLB27_DATA} -skip_load_frames \ - -w 16 -h 16 -ow 16 -oh 16 -t $1 | \ - sed '/fps/!d; s#.*: \(.*\) msec.*#1000000 / \1#' | bc -l -} - -while read name benchmark; do - eval "${name}:fullscreen_run() { __gl27fullscreen__ \$1 $benchmark; }" - test_name="$test_name $name:fullscreen" - for i in window offscreen cpu; do - eval "${name}:${i}_run() { __gl27${i}__ \$1 ${benchmark}_Offscreen; }" - test_name="$test_name ${name}:${i}" - done -done<<EOL - GLB27:Trex GLB27_TRex_C24Z16_FixedTimeStep - GLB27:Egypt GLB27_EgyptHD_inherited_C24Z16_FixedTime -EOL -test_exec_time=14 diff --git a/tests.d/mesa/glbenchmark30.test b/tests.d/mesa/glbenchmark30.test deleted file mode 100644 index 42bff9a..0000000 --- a/tests.d/mesa/glbenchmark30.test +++ /dev/null @@ -1,85 +0,0 @@ -GLB30=${GLBENCHMARK30_FOLDER}/build/linux/gfxbench_Release/mainapp/mainapp - -test -e ${GLB30} || return 1 - -# Output: -# [INFO ]: { -# "results": -# [ -# { -# "elapsed_time": 616, -# "error_string": "", -# "gfx_result": -# { -# "egl_config_id": -1, -# "fps": 52.1, -# "frame_count": 31, -# "frametimes": [ 15, 3, 26, 21, 20, 21, 20, 21, 20, 20, 21, 38, 3, 20, 21, 22, 20, 20, 20, 20, 21, 20, -# 20, 20, 20, 21, 20, 21, 20, 20, 21 ], -# "graphics_version": "3.0 Mesa 10.3.2", -# "renderer": "Mesa DRI Intel(R) HD Graphics 5500 (Broadwell GT2) ", -# "surface_height": 1080, -# "surface_width": 1920 -# }, -# "load_time": 4427, -# "measured_time": 616, -# "result_id": -1, -# "score": 2917.64697265625, -# "status": "OK", -# "test_id": "gl_trex", -# "unit": "frames", -# "version": 1 -# } -# ] -#} - -# 1 argument: $benchmark -function __gl30run__ { - local W="${GLBENCHMARK30_WIDTH:-1920}" - local H="${GLBENCHMARK30_HEIGHT:-1080}" - - cd ${GLBENCHMARK30_FOLDER}/build/linux/gfxbench_Release/mainapp/ - - # set GL versions when needed - case "$1" in - gl_4*) - export MESA_GL_VERSION_OVERRIDE=4.3 - export MESA_GLSL_VERSION_OVERRIDE=430 - ;; - gl_manhattan31*) - export MESA_GL_VERSION_OVERRIDE=4.3 - export MESA_GLSL_VERSION_OVERRIDE=430 - ;; - gl_manhattan*) - export MESA_GL_VERSION_OVERRIDE=4.1 - export MESA_GLSL_VERSION_OVERRIDE=400 - ;; - esac - - LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${GLBENCHMARK30_FOLDER}/build/linux/poco_Release/lib/ \ - run_bench 0 ./mainapp -data ${GLB30_DATA} -w $W -h $H -ow $W -oh $H -t $1 -fullscreen $2 |\ - grep fps | cut -d : -f 2- | cut -d " " -f 2 | cut -d ',' -f 1 - - unset MESA_GL_VERSION_OVERRIDE - unset MESA_GLSL_VERSION_OVERRIDE -} - -while read name benchmark; do - eval "${name}:fullscreen_run() { __gl30run__ $benchmark 1; }" - test_name="$test_name $name:fullscreen" - - eval "${name}:window_run() { __gl30run__ $benchmark 0; }" - test_name="$test_name $name:window" - - eval "${name}:offscreen_run() { __gl30run__ ${benchmark}_off 0; }" - test_name="$test_name $name:offscreen" - - eval "${name}:cpu_run() { INTEL_NO_HW=1 __gl30run__ ${benchmark} 0; }" - test_name="$test_name $name:cpu" -done<<EOL - GLB30:Trex gl_trex - GLB30:Manhattan gl_manhattan - GLB30:Manhattan31 gl_manhattan31 - GLB30:Driver gl_driver -EOL -test_exec_time=70 diff --git a/tests.d/mesa/glxgears.test b/tests.d/mesa/glxgears.test deleted file mode 100644 index 1c6e61c..0000000 --- a/tests.d/mesa/glxgears.test +++ /dev/null @@ -1,33 +0,0 @@ -test_name="glxgears:fullscreen glxgears:window glxgears:cpu glxgears16" -test_exec_time=21 - -which glxgears >/dev/null 2>&1 || return 1 - -__glxgears__() { - run_bench 21 glxgears $1 2> /dev/null | grep 'frames in ' | cut -d ' ' -f7 -} - -glxgears:window_run() { - __glxgears__ "" -} - -glxgears:cpu_run() { - INTEL_NO_HW=1 glxgears:window_run "" -} - -glxgears:fullscreen_run() { - __glxgears__ -fullscreen -} - -glxgears16_run() { - local unbuf="stdbuf -oL" - local extract_fps="$unbuf cut -d ' ' -f7" - - for (( n=0; n<15; n++ )); do - timeout 25 glxgears >&/dev/null 2>/dev/null & - done - - run_bench 21 glxgears 2> /dev/null | eval $extract_fps - - sleep 5 -} diff --git a/tests.d/mesa/gputest.test b/tests.d/mesa/gputest.test deleted file mode 100644 index 1409ee9..0000000 --- a/tests.d/mesa/gputest.test +++ /dev/null @@ -1,35 +0,0 @@ -test -e "$GPUTEST_FOLDER/GpuTest" || return 1 - -# 2 arguments: $benchmark $benchmark_opts -__gputest__() { - cd "$GPUTEST_FOLDER" # Set this variable in test_options.sh - duration_s=30 - local benchmark="/benchmark /no_scorebox /msaa=0 /benchmark_duration_ms=${duration_s}000" - - rm _geeks3d_gputest_log.txt - MESA_GL_VERSION_OVERRIDE=4.0 MESA_GLSL_VERSION_OVERRIDE=400 \ - run_bench 0 ./GpuTest /test=$1 $benchmark $2 > /dev/null || return 1 - frames_rendered=$(cat _geeks3d_gputest_log.txt | grep "# frames rendered" | cut -d '#' -f 2 | cut -d ':' -f2) - - bc <<< "scale=3; ${frames_rendered}/${duration_s}" -} - -fullscreen="/width=1920 /height=1080 /fullscreen" -window="/width=1024 /height=768" - -GL2_1="fur pixmark_julia_fp32 pixmark_piano pixmark_volplosion plot3d triangle" -GL3_3="gi" -GL4_0="tess_x8 tess_x16 tess_x32 tess_x64 pixmark_julia_fp64" - -# 3 arguments: $rounds $fps_logs_file $runID -for t in $GL2_1 $GL3_3 $GL4_0; do - name="gputest:$t:fullscreen" - test_name="$test_name $name" - eval "${name}_run() { __gputest__ $t \"$fullscreen\"; }" - - name="gputest:$t:window" - test_name="$test_name $name" - eval "${name}_run() { __gputest__ $t \"$window\"; }" -done - -test_exec_time=37 diff --git a/tests.d/mesa/lightsmark.test b/tests.d/mesa/lightsmark.test deleted file mode 100644 index 6b6abe0..0000000 --- a/tests.d/mesa/lightsmark.test +++ /dev/null @@ -1,25 +0,0 @@ -[ -e $LIGHTSMARK_FOLDER/bin/pc-linux64 ] || return 1 - -# This is Lightsmark 2008 [Linux 64bit] log. Check it if benchmark doesn't work properly. -# Penumbra quality: 8/8 on Mesa DRI Intel(R) HD Graphics (Cherryview) . -# Loading Lightsmark2008.cfg... -# Loading objects/I_Robot_female_HD.3DS... -# Loading scenes/wop_padattic/wop_padatticBB.ani... -# Detection quality: auto->high. -# Loading scene scenes/wop_padattic/wop_padatticBB.bsp... -# Finished, average fps = 24.34. - -lightsmark_run() { - local extract_fps="sed '/Finished/!d; s/.* fps = \(.*\).$/\1/'" - - cd $LIGHTSMARK_FOLDER/bin/pc-linux64 - - LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH run_bench 0 ./backend silent 1920x1080 | eval $extract_fps -} - -lightsmark:cpu_run() { - INTEL_NO_HW=1 lightsmark_run -} - -test_name="lightsmark lightsmark:cpu" -test_exec_time=120 diff --git a/tests.d/mesa/unigine-heaven.test b/tests.d/mesa/unigine-heaven.test deleted file mode 100644 index dab3563..0000000 --- a/tests.d/mesa/unigine-heaven.test +++ /dev/null @@ -1,40 +0,0 @@ -test -e "$UNIGINE_HEAVEN_FOLDER/bin/heaven_x64" || return 1 - -function __unigine_heaven_run__ { - cd "$UNIGINE_HEAVEN_FOLDER" # Set this variable in test_options.sh - - fullscreen=$1 - width=$2 - height=$3 - - LD_LIBRARY_PATH=bin:bin/x64:$LD_LIBRARY_PATH \ - MESA_EXTENSION_OVERRIDE="-GL_ARB_sample_shading -GL_ARB_blend_func_extended" \ - MESA_GL_VERSION_OVERRIDE="3.2" \ - run_bench 0 ./bin/heaven_x64 \ - -video_app opengl \ - -data_path ../ \ - -sound_app null \ - -engine_config ../data/heaven_4.0.cfg \ - -system_script heaven/unigine.cpp \ - -extern_define PHORONIX,LANGUAGE_EN,RELEASE,QUALITY_HIGH,TESSELLATION_NORMAL \ - -video_mode -1 -video_width $width -video_height $height -video_multisample 0 \ - -video_fullscreen $fullscreen | grep FPS: | xargs | cut -d ' ' -f 2 -} - -while read name width height; do - name="unigine:heaven:${name}" - - eval "$name:fullscreen_run() { __unigine_heaven_run__ 1 $width $height; }" - test_name="$test_name $name:fullscreen" - - eval "$name:window_run() { __unigine_heaven_run__ 0 $width $height; }" - test_name="$test_name $name:window" -done<<EOL - 720p 1280 720 - 1080p 1920 1080 -EOL - -eval "unigine:heaven:cpu_run() { INTEL_NO_HW=1 __unigine_heaven_run__ 0 $width $height; }" -test_name="$test_name unigine:heaven:cpu" - -test_exec_time=300 diff --git a/tests.d/mesa/unigine-valley.test b/tests.d/mesa/unigine-valley.test deleted file mode 100644 index 63582c9..0000000 --- a/tests.d/mesa/unigine-valley.test +++ /dev/null @@ -1,40 +0,0 @@ -test -e "$UNIGINE_VALLEY_FOLDER/bin/valley_x64" || return 1 - -function __unigine_valley_run__ { - cd "$UNIGINE_VALLEY_FOLDER" # Set this variable in test_options.sh - - fullscreen=$1 - width=$2 - height=$3 - - LD_LIBRARY_PATH=bin:bin/x64:$LD_LIBRARY_PATH \ - MESA_EXTENSION_OVERRIDE="-GL_ARB_sample_shading -GL_ARB_blend_func_extended" \ - MESA_GL_VERSION_OVERRIDE="3.2" \ - run_bench 0 ./bin/valley_x64 \ - -video_app opengl \ - -data_path ../ \ - -sound_app null \ - -engine_config ../data/valley_1.0.cfg \ - -system_script valley/unigine.cpp \ - -extern_define PHORONIX,LANGUAGE_EN,RELEASE,QUALITY_HIGH,TESSELLATION_NORMAL \ - -video_mode -1 -video_width $width -video_height $height -video_multisample 0 \ - -video_fullscreen $fullscreen | grep FPS: | xargs | cut -d ' ' -f 2 -} - -while read name width height; do - name="unigine:valley:${name}" - - eval "$name:fullscreen_run() { __unigine_valley_run__ 1 $width $height; }" - test_name="$test_name $name:fullscreen" - - eval "$name:window_run() { __unigine_valley_run__ 0 $width $height; }" - test_name="$test_name $name:window" -done<<EOL - 720p 1280 720 - 1080p 1920 1080 -EOL - -eval "unigine:valley:cpu_run() { INTEL_NO_HW=1 __unigine_valley_run__ 0 $width $height; }" -test_name="$test_name unigine:valley:cpu" - -test_exec_time=190 diff --git a/tests.d/mesa/xonotic.test b/tests.d/mesa/xonotic.test deleted file mode 100644 index 9f543d0..0000000 --- a/tests.d/mesa/xonotic.test +++ /dev/null @@ -1,32 +0,0 @@ -test -e "$XONOTIC_FOLDER/xonotic-glx" || return 1 - -__xonotic__() { - fullscreen=$1 - width=$2 - height=$3 - - # 10510 frames 24.7782191 seconds 424.1628480 fps, one-second fps min/avg/max: 57 1352 7027 (336 seconds) - local extract_fps="egrep -e '[0-9]+ frames' | cut -d ' ' -f 5 2> /dev/null" - - run_bench 0 $XONOTIC_FOLDER/xonotic-glx +vid_width $width +vid_height $height \ - +vid_fullscreen $fullscreen +exec effects-high.cfg \ - -benchmark demos/the-big-keybench | eval $extract_fps -} - -while read name width height; do - name="xonotic:${name}" - - eval "$name:fullscreen_run() { __xonotic__ 1 $width $height; }" - test_name="$test_name $name:fullscreen" - - eval "$name:window_run() { __xonotic__ 0 $width $height; }" - test_name="$test_name $name:window" -done<<EOL - 720p 1280 720 - 1080p 1920 1080 -EOL - -eval "xonotic:cpu_run() { INTEL_NO_HW=1 __xonotic__ 0 $width $height; }" -test_name="$test_name xonotic:cpu" - -test_exec_time=80 diff --git a/tests.d/no-op.test b/tests.d/no-op.test deleted file mode 100644 index 0a0746f..0000000 --- a/tests.d/no-op.test +++ /dev/null @@ -1,6 +0,0 @@ -test_name=no-op -test_exec_time=0 - -no-op_run() { - echo 1 -} diff --git a/tests.d/x11/cairo-demos.test b/tests.d/x11/cairo-demos.test deleted file mode 100644 index bdcc3c2..0000000 --- a/tests.d/x11/cairo-demos.test +++ /dev/null @@ -1,22 +0,0 @@ -# Download cairo-demos at -# http://www.phoronix-test-suite.com/benchmark-files/cairo-demos-20120130.tar.bz2 - -xdpyinfo >/dev/null 2>&1 || return 1 -[ ! -d "$CAIRO_DEMOS" ] && return 1 - -# fish: 99.999 fps - -function __xlib__ { - cd $CAIRO_DEMOS - for (( c=0; c<$1; c++ )); do - run_bench 20 ./$2-demo --benchmark --xlib | sed -e '/fps/!d; s/.*: \(.*\) fps.*/\1/' - done -} - -for i in $CAIRO_DEMOS/*-demo; do - demo=$(basename $i -demo) - name="x11:cairo:demo:$demo" - test_name="$test_name $name" - eval "${name}_run() { __xlib__ \$1 $demo; }" -done -test_exec_time=20 diff --git a/tests.d/x11/swap.test b/tests.d/x11/swap.test deleted file mode 100644 index 98bbf47..0000000 --- a/tests.d/x11/swap.test +++ /dev/null @@ -1,33 +0,0 @@ -xdpyinfo >/dev/null 2>&1 || return 1 - -function __dri2__ { - for (( c=0; c<$1; c++)); do - run_bench 0 $XF86_VIDEO_INTEL/benchmarks/dri2-swap -d $2 -v $3 -w $4 - done -} - -function __dri3__ { - for (( c=0; c<$1; c++)); do - run_bench 0 $XF86_VIDEO_INTEL/benchmarks/dri3-swap -d $2 -v $3 -w $4 - done -} - -methods= -which $XF86_VIDEO_INTEL/benchmarks/dri2-swap >/dev/null 2>&1 && methods="$methods dri2" -which $XF86_VIDEO_INTEL/benchmarks/dri3-swap >/dev/null 2>&1 && methods="$methods dri3" - -for m in $methods; do - for d in on off; do - name="x11:${m}:${d}:root" - eval "${name}_run() { __${m}__ \$1 $d normal root; }" - test_name="$test_name $name" - for w in fullscreen window; do - for v in redirected normal; do - name="x11:${m}:${d}:${w}:${v}" - eval "${name}_run() { __${m}__ \$1 $d $v $w; }" - test_name="$test_name $name" - done - done - done -done -test_exec_time=10 diff --git a/tests.d/x11/x11perf.test b/tests.d/x11/x11perf.test deleted file mode 100644 index 2a5b4ae..0000000 --- a/tests.d/x11/x11perf.test +++ /dev/null @@ -1,27 +0,0 @@ -test_exec_time=10 - -which x11perf >/dev/null 2>&1 || return 1 -xdpyinfo >/dev/null 2>&1 || return 1 - -function __x11perf__ { - run_bench 0 x11perf -time 10 -repeat 1 $1 | sed -e '/reps/!d; s#.*(\(.*\)/sec.*#\1#' -} - -x11perf_help=$(x11perf --help 2>&1) -for i in \ - aa10text aa24text \ - rgb10text rgb24text \ - copywinwin10 copywinwin500 \ - copywinpix10 copywinpix500 \ - copypixwin10 copypixwin500 \ - putimage10 putimage500 \ - getimage10 getimage500 \ - shmput10 shmput500 \ - shmget10 shmget500 \ - ; -do - grep -q -w -e "-$i" <<< $x11perf_help || continue - test_name="$test_name x11:$i" - eval "x11:${i}_run() { __x11perf__ -$i; }" -done -unset x11perf_help diff --git a/user_parameters.sh.sample b/user_parameters.sh.sample deleted file mode 100644 index 0370c8c..0000000 --- a/user_parameters.sh.sample +++ /dev/null @@ -1,68 +0,0 @@ -# WARNING: Hooks should be put in the profiles, not in this file - -# SHA1 Database that contains the version of each library, based on their SHA1 -SHA1_DB=$ezBenchDir/SHA1_DB - -# Frequencies -#WANTED_CPU_FREQ_kHZ=2000000 - -# Repo addresses -REPO_MESA=/opt/git/mesa -REPO_LINUX=/opt/git/linux - -# Libraries options -LIBFRAMETIME64_SO=/usr/lib/libframetime.so -LIBFRAMETIME32_SO=/usr/lib32/libframetime.so - -# Benchmark parameters -SYNMARK_FOLDER=/opt/benchmarks/SynMark2 - -# UE4 parameters -UE4_FOLDER="/opt/benchmarks/Unreal Engine 4" -UE4_WINDOW_SIZE_X=128 -UE4_WINDOW_SIZE_Y=80 - -# Unigine settings -UNIGINE_HEAVEN_FOLDER=/opt/benchmarks/unigine-heaven-4.0 -UNIGINE_VALLEY_FOLDER=/opt/benchmarks/unigine-valley-1.0 - -# GpuTest settings -GPUTEST_FOLDER=/opt/benchmarks/GpuTest_Linux_x64_0.7.0 - -# Lightsmark settings -LIGHTSMARK_FOLDER=/opt/benchmarks/lightsmark-1.2.0/Lightsmark2008.2.0 - -# Citybench settings -CITYBENCH_FOLDER=/opt/replay_hbas_citybench - -# GLBenchmark settings -GLBENCHMARK27_FOLDER=/opt/benchmarks/glbenchmark2.7.0/ -#GLBENCHMARK27_WIDTH=1920 -#GLBENCHMARK27_HEIGHT=1080 -GLBENCHMARK30_FOLDER=/opt/benchmarks/gfxbench3_desktop/ -#GLBENCHMARK30_WIDTH=1920 -#GLBENCHMARK30_HEIGHT=1080 - -# LuxMark settings -LUXMARK_FOLDER=/opt/benchmarks/luxmark-v3.0 - -# PolyBench-ACC settings -# https://github.com/cavazos-lab/PolyBench-ACC -POLYBENCH_ACC_FOLDER=/opt/benchmarks/PolyBench-ACC - -# FinanceBench settings -# https://github.com/cavazos-lab/FinanceBench -FINANCEBENCH_FOLDER=/opt/benchmarks/FinanceBench - -# intel-gpu-tools settings -IGT_BENCHMARKS=/opt/intel-gpu-tools/benchmarks -IGT_TRACES=/opt/intel-gpu-tools/traces - -# cairo-demos settings -CAIRO_DEMOS=/opt/benchmarks/cairo-demos - -# xf86-video-intel setting -XF86_VIDEO_INTEL=/opt/benchmarks/xf86-video-intel - -# Xonotic -XONOTIC_FOLDER=/usr/bin diff --git a/utils/check_resource_usage.py b/utils/check_resource_usage.py deleted file mode 100755 index 57ce112..0000000 --- a/utils/check_resource_usage.py +++ /dev/null @@ -1,170 +0,0 @@ -#!/usr/bin/env python3 - -""" -Copyright (c) 2015, Intel Corporation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -""" - -import optparse -import psutil -import time -import sys -import os - -interval=1 # Not true, but it is a good-enough value! -processes = dict() - -class Process: - def __init__(self, pid, reportId): - try: - p = psutil.Process(pid) - times = p.cpu_times() - self.pid = pid - self.comm = p.name() - self.ppid = p.ppid() - self.utime = times.user - self.stime = times.system - self.reportId = reportId - except: - self.pid = pid - self.reportId = 0 - pass - -def readFile(path): - try: - f = open(path, "r") - return f.read() - except IOError: - sys.stderr.write("Could not read file '{0}'".format(path)) - return "" - -def log(msg): - timeStr=time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime()) - print (timeStr + ": " + msg) - -def computeCpuUsage(prev, new): - if prev == None: - prev_utime = 0 - prev_stime = 0 - else: - prev_utime = prev.utime - prev_stime = prev.stime - - userPercent=(new.utime - prev_utime) * 100 / interval - systemPercent=(new.stime - prev_stime) * 100 / interval - return (userPercent, systemPercent) - -def gen_report(p, firstRun, reportId): - if firstRun: - return - - if os.getpid() == p.pid or p.pid in ignorePids: - return - - # TODO: Check if a process died and another one took its pid by checking starttime - - if not p.pid in processes: - log ("Process {pid} ({comm}) got created".format(pid=p.pid, comm=p.comm)) - prev = None - else: - prev = processes[p.pid] - - user,system = computeCpuUsage(prev, p) - if (user + system) >= 0.5: - log ("Process {pid} ({name}) has CPU usage: user = {user:0.1f}%, system = {system:0.1f}%".format(pid=pid, - name=p.comm, - user=user, - system=system)) - -# Start by checking what the user wants to monitor! -p = optparse.OptionParser() -p.add_option('--cpu', '-c', action='store_true', default=False, help="Monitor the global cpu activity") -p.add_option('--disk', '-d', action='store_true', default=False, help="Monitor the globaldisk activity") -p.add_option('--network', '-n', action='store_true', default=False, help="Monitor the global network activity") -p.add_option('--ignorepids', '-i', action='store', type="string", default="", help="Ignore the following pids from the per-process cpu report") -options, arguments = p.parse_args() - -ignorePids = [] -for pid in options.ignorepids.split(","): - ignorePids.append(int(pid)) -print ("Warning: The CPU report will ignore the following pids {0}\n".format(ignorePids)) - -firstRun = True -reportId = 1 -prevIoCounters = psutil.disk_io_counters() -prevNetCounters = psutil.net_io_counters() -while True: - # Check CPU usage - if options.cpu: - cpu_usage = psutil.cpu_percent(interval) * psutil.cpu_count(True) - if cpu_usage > 1.0: - log ("HIGH CPU usage: {cpu_usage}%".format(cpu_usage=cpu_usage)) - else: - time.sleep(interval) - - # Check the cpu usage per process - pids = psutil.pids() - for pid in pids: - p = Process(pid, reportId) - if p.reportId == 0: - continue - gen_report(p, firstRun, reportId) - processes[p.pid] = p - - # Check for died processes - toDel=[] - for pid in processes: - if processes[pid].reportId != reportId: - log ("Process {pid} ({comm}) died".format(pid=pid, comm=processes[pid].comm)) - toDel.append(pid) - - # Delete the old pids - for pid in toDel: - processes.pop(pid, None) - - # Check the IOs - if options.disk: - io_counters = psutil.disk_io_counters() - if io_counters.read_count > prevIoCounters.read_count: - log ("Increased disk read count: +{count} ({volume} B)".format(count=io_counters.read_count - prevIoCounters.read_count, - volume=io_counters.read_bytes - prevIoCounters.read_bytes)) - if io_counters.write_count > prevIoCounters.write_count: - log ("Increased disk write count: +{count} ({volume} B)".format(count=io_counters.write_count - prevIoCounters.write_count, - volume=io_counters.write_bytes - prevIoCounters.write_bytes)) - prevIoCounters = io_counters - - # Check the network - if options.network: - netCounters = psutil.net_io_counters() - if netCounters.packets_recv > prevNetCounters.packets_recv: - log ("Incoming packets: {count} ({volume} B)".format(count=netCounters.packets_recv - prevNetCounters.packets_recv, - volume=netCounters.bytes_recv - prevNetCounters.bytes_recv)) - if netCounters.packets_sent > prevNetCounters.packets_sent: - log ("Outgoing packets : {count} ({volume} B)".format(count=netCounters.packets_sent - prevNetCounters.packets_sent, - volume=netCounters.bytes_sent - prevNetCounters.bytes_sent)) - prevNetCounters = netCounters - - firstRun = False - reportId = reportId + 1 diff --git a/utils/env_dump/Makefile b/utils/env_dump/Makefile deleted file mode 100644 index 2de8edd..0000000 --- a/utils/env_dump/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -CC = gcc -CFLAGS = -c -Wall -fPIC -g -LDFLAGS = -shared -g - -SHA1_DB ?= ../../SHA1_DB - -SOURCES = env_dump.c cpu.c drm.c fd.c gl.c libs.c linux.c net.c posix_env.c xorg.c -OBJECTS = $(SOURCES:.c=.o) - -# Name of executable target: -EXECUTABLE = env_dump.so - -# libcrypto -CFLAGS += `pkg-config --cflags libcrypto` - -# libxrandr -CFLAGS += `pkg-config --cflags xrandr` - -# libxrandr -CFLAGS += `pkg-config --cflags libdrm` - -# other libs -LDFLAGS += -lpthread -ldl - -all: $(SOURCES) $(EXECUTABLE) - -$(EXECUTABLE): $(OBJECTS) - $(CC) $(OBJECTS) -o $@ $(LDFLAGS) - @if [ -e "${SHA1_DB}/sha1_db" ]; then \ - ${SHA1_DB}/sha1_db ${SHA1_DB} - add_git . $(EXECUTABLE); \ - else \ - echo "Warning: SHA1_DB is not defined, cannot add the version to the SHA1_DB."; \ - fi - -.c.o: - $(CC) $(CFLAGS) $< -o $@ - -clean: - rm $(OBJECTS) $(EXECUTABLE) diff --git a/utils/env_dump/README b/utils/env_dump/README deleted file mode 100644 index 2479d33..0000000 --- a/utils/env_dump/README +++ /dev/null @@ -1,248 +0,0 @@ -= Env dump = - -== Description == - -This library is meant to be used in conjunction with LD_PRELOAD to dump as much -information as possible about the machine, the run, the libraries used, etc... - -The output of the library is saved in a file. You can select the filename using -the environment variable ENV_DUMP_FILE. If the file is already present, the pid -will be appended to avoid overriding existing data. If you do not set the -ENV_DUMP_FILE env. var., the default output file will be '/tmp/env_dump'. - -== Compilation == - -Please install the libcrypto and then type make in the directory containing this -README. You should get a env_dump.so. - -== Usage == - -=== Running the application === - -There are two possible ways: - - - $ LD_PRELOAD=$PWD/env_dump.so ENV_DUMP_FILE=report xonotic-glx # either this way - - $ env_dump.sh report xonotic-glx # or this way, your call! - -=== SHA1 Database === - -The SHA1 DB is meant to link the SHA1 of an executable to a release version or -git SHA1 from an upstream branch along with how it got compiled. - -The DB can be accessed through a command line interface using /SHA1_DB/sha1_db. -The tool supports adding new SHA1s, querying attributes and adding attributes. - -Use the function make_install_sha1_dump from /profiles.d/utils/sha1_db.sh to -install a git version of any project supporting DESTDIR overriding. The command -line is: - -$ SHA1_DB=/my/path/to/SHA1_DB make_install_sha1_dump - -The configuration is however not currently saved but it is being investigated. - -=== Adding data to the report === - -If you have SHA1_DB set-up and have installed packagekit and dmidecode, it is -possible to enhance the report by adding information about the HW and SW used -during the run. - -$ env_dump_extend.sh ../../SHA1_DB/ report - -=== Parsing the output === - -The output is a CSV file which should be easy to parse. The plan is to write a -python parser that will evolve in sync with the format of the CSV. - -This work has not been started yet and will be the basis of a tool comparing -the environment between two runs. - -=== Viewing the final report === - -Here is an example of report for the game xonotic. - -$ cat report --- Env dump start (version 1) -- -MOTHERBOARD,ASUSTeK COMPUTER INC.,Z97-A,Rev 1.xx -BIOS,American Megatrends Inc.,1204,06/20/2014 -PROCESSOR,1,Intel,C3 06 03 00 FF FB EB BF,Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz,4,8,256 kB,1024 kB,8192 kB,3800 MHz,1 -RAM_STICK,1,DDR3,1315,BLS4G3D1609DS1S00.,A90D6072,4096 MB,1600 MHz -RAM_STICK,2,DDR3,Kingston,KHX1600C9D3/4GX,6E2A1C4B,4096 MB,1600 MHz -RAM_STICK,3,DDR3,1315,BLS4G3D1609DS1S00.,A90D6071,4096 MB,1600 MHz -RAM_STICK,4,DDR3,Kingston,KHX1600C9D3/4GX,6B2A204B,4096 MB,1600 MHz -EXE,/usr/bin/xonotic-glx,'xonotic-glx',3d1e4934b68d33f967796d662ca150829cbb6393,Arch-xonotic-0.8.1-1.x86_64 -ENV,LD_PRELOAD=/home/mupuf/benchmarks/ezbench/utils/env_dump/env_dump.so -ENV,ENV_DUMP_FILE=report -ENV,XDG_VTNR=1 -ENV,KDE_MULTIHEAD=false -ENV,XDG_SESSION_ID=c1 -ENV,TERM=xterm -ENV,SHELL=/bin/bash -ENV,KONSOLE_DBUS_SERVICE=:1.32 -ENV,GTK2_RC_FILES=/etc/gtk-2.0/gtkrc:/home/mupuf/.gtkrc-2.0:/home/mupuf/.config/gtkrc-2.0 -ENV,KONSOLE_PROFILE_NAME=Shell -ENV,ACLOCAL=aclocal -I /home/mupuf/install/share/aclocal -ENV,GTK_RC_FILES=/etc/gtk/gtkrc:/home/mupuf/.gtkrc:/home/mupuf/.config/gtkrc -ENV,MESA_DEBUG=1 -ENV,GS_LIB=/home/mupuf/.fonts -ENV,WINDOWID=71303198 -ENV,SHELL_SESSION_ID=7cd19f2c4e054000a020612a6f00374a -ENV,GTK_MODULES=canberra-gtk-module -ENV,KDE_FULL_SESSION=true -ENV,NVD=/home/mupuf/install -ENV,USER=mupuf -ENV,LD_LIBRARY_PATH=/home/mupuf/install/lib -ENV,XCURSOR_SIZE=24 -ENV,SSH_AUTH_SOCK=/tmp/ssh-f7fMDVJ2Hzsf/agent.864 -ENV,SESSION_MANAGER=local/beast:@/tmp/.ICE-unix/21516,unix/beast:/tmp/.ICE-unix/21516 -ENV,MOZ_PLUGIN_PATH=/usr/lib/mozilla/plugins -ENV,PATH=/home/mupuf/install/bin/:/home/mupuf/install/bin/:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/opt/vogl -ENV,MAIL=/var/spool/mail/mupuf -ENV,PWD=/home/mupuf/benchmarks/ezbench/utils/env_dump -ENV,EDITOR=nano -ENV,LANG=en_GB.UTF-8 -ENV,KDE_SESSION_UID=1000 -ENV,KONSOLE_DBUS_SESSION=/Sessions/2 -ENV,SSH_ASKPASS=/usr/bin/ksshaskpass -ENV,SHLVL=5 -ENV,XDG_SEAT=seat0 -ENV,COLORFGBG=15;0 -ENV,HOME=/home/mupuf -ENV,LANGUAGE= -ENV,KDE_SESSION_VERSION=5 -ENV,XCURSOR_THEME=Breeze_Snow -ENV,LOGNAME=mupuf -ENV,DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-UUXbqWS2HW,guid=da94550fcaef7911bb07f9e45640cbe2 -ENV,XDG_DATA_DIRS=/usr/share:/usr/share:/usr/local/share -ENV,PKG_CONFIG_PATH=/home/mupuf/install/lib/pkgconfig/:/home/mupuf/install/share/pkgconfig/ -ENV,WINDOWPATH=1 -ENV,DISPLAY=:0 -ENV,XDG_RUNTIME_DIR=/run/user/1000 -ENV,PROFILEHOME= -ENV,XDG_CURRENT_DESKTOP=KDE -ENV,XAUTHORITY=/tmp/xauth-1000-_0 -ENV,_=/usr/bin/xonotic-glx -KERNEL,Linux,beast,4.2.5-1-ARCH,#1 SMP PREEMPT Tue Oct 27 08:13:28 CET 2015,x86_64,(none) -SCHED,SCHED_OTHER,8,8,255,0 -CPU_FREQ,8,800000,4000000,800000,4000000,800000,4000000,800000,4000000,800000,4000000,800000,4000000,800000,4000000,800000,4000000 -THROTTLING,8,0,0,0,0,0,0,0,0,0 -INTEL_PSTATE,33,13,0,20,100 -BOOTLINK,linux-vdso.so.1,UNK,UNKNOWN_VERSION -BOOTLINK,/home/mupuf/benchmarks/ezbench/utils/env_dump/env_dump.so,b53d74f5e0bf38f02ed0135489a7552857c78e3b,UNKNOWN_VERSION -BOOTLINK,/usr/lib/libm.so.6,b7cf4803a0a49905d990adfcc56989721b156e71,Arch-glibc-2.22-3.x86_64 -BOOTLINK,/usr/lib/libz.so.1,a2f2ed3e528cee1527cf30a14f01ca246bf530b5,Arch-zlib-1.2.8-4.x86_64 -BOOTLINK,/usr/lib/libjpeg.so.8,12f18a159967f13e108fbba1fe2a5b95b59389e0,Arch-libjpeg-turbo-1.4.2-1.x86_64 -BOOTLINK,/usr/lib/librt.so.1,93294cf925d436e5167e0777ca875d7ca14647a8,Arch-glibc-2.22-3.x86_64 -BOOTLINK,/usr/lib/libdl.so.2,3e032a705b7724f27e78d4f078d7c6961ffd54e0,Arch-glibc-2.22-3.x86_64 -BOOTLINK,/usr/lib/libX11.so.6,70b697ed434727e99bbd3b8f2f486c9267690a56,Arch-libx11-1.6.3-1.x86_64 -BOOTLINK,/usr/lib/libXpm.so.4,fbbd6634d7edf3070bcd9b742e74a9a2d75e99b6,Arch-libxpm-3.5.11-1.x86_64 -BOOTLINK,/usr/lib/libXext.so.6,3359d6805126c28630c922219a6daaf9a5836f42,Arch-libxext-1.3.3-1.x86_64 -BOOTLINK,/usr/lib/libXxf86vm.so.1,4a916951fe388431de5448d9818e293b73191d32,Arch-libxxf86vm-1.1.4-1.x86_64 -BOOTLINK,/usr/lib/libasound.so.2,3791381047b0f3c25b9a808f8feeb0765ff07051,Arch-alsa-lib-1.0.29-1.x86_64 -BOOTLINK,/usr/lib/libpthread.so.0,54f2d4f765876c54194bed2964bdd1a0cdde03db,Arch-glibc-2.22-3.x86_64 -BOOTLINK,/usr/lib/libc.so.6,e3e01c77ab3d4d73ff3f969948465debaffa2b61,Arch-glibc-2.22-3.x86_64 -BOOTLINK,/lib64/ld-linux-x86-64.so.2,7911a1b3866a389fa9ad46a08432b7efe2639478,UNKNOWN_VERSION -BOOTLINK,/usr/lib/libxcb.so.1,25ec0f295c31eebb496ba429d038348719724b35,Arch-libxcb-1.11.1-1.x86_64 -BOOTLINK,/usr/lib/libXau.so.6,df47f8963111fa3850a26fa61f0b4c137433a745,Arch-libxau-1.0.8-2.x86_64 -BOOTLINK,/home/mupuf/install/lib/libXdmcp.so.6,ba5e8960254ccfc4122af1fc1844e4c28b3efbab,git://anongit.freedesktop.org/xorg/lib/libXdmcp/master-b10f382 -BOOTLINK,/usr/lib/libbsd.so.0,599ee6ed3c735d0518829b3547cf9c45f344331e,Arch-libbsd-0.7.0-1.x86_64 -BOOTLINK,/usr/lib/libcrypto.so,211d0b48fb40546c8524303e67493819d531aea8,Arch-openssl-1.0.2.d-1.x86_64 -DYNLINK,/usr/lib/libd0_blind_id.so.0.0.0,99d9ef467ffce9a45fe80450daa7a17f674f96d2,Arch-xonotic-0.8.1-1.x86_64 -DYNLINK,/usr/lib/libd0_blind_id.so.0,99d9ef467ffce9a45fe80450daa7a17f674f96d2,Arch-xonotic-0.8.1-1.x86_64 -DYNLINK,/usr/lib/libgmp.so.10,d87b6bbdbc2fcbe4acd30dc2ef7a19a347147a4e,Arch-gmp-6.0.0-2.x86_64 -DYNLINK,/usr/lib/libcurl.so.4.4.0,1e13f692bda6d5905d1320e6d4b840edd3d0ba3b,Arch-curl-7.45.0-1.x86_64 -DYNLINK,/usr/lib/libcurl.so.4,1e13f692bda6d5905d1320e6d4b840edd3d0ba3b,Arch-curl-7.45.0-1.x86_64 -DYNLINK,/usr/lib/libidn.so.11,5a08d437b09087ada4f1b83168a1d87a5fac101b,Arch-libidn-1.32-1.x86_64 -DYNLINK,/usr/lib/libssh2.so.1,7d6f5792c906b3d83424d4f1d09ce8f00c5fa366,Arch-libssh2-1.6.0-1.x86_64 -DYNLINK,/usr/lib/libssl.so.1.0.0,8e4090c0889f6f75a896fafa3ec5d78052d032c3,Arch-openssl-1.0.2.d-1.x86_64 -DYNLINK,/usr/lib/libgssapi_krb5.so.2,503b9db4d5e1deabdcda54326d1e59785f10a703,Arch-krb5-1.13.2-1.x86_64 -DYNLINK,/usr/lib/libkrb5.so.3,3a5aa48c1bad6e58e3c7141abb655e4fa1691130,Arch-krb5-1.13.2-1.x86_64 -DYNLINK,/usr/lib/libk5crypto.so.3,cc9bee4d4e58ba0d54166f0407f3fcb00edb681e,Arch-krb5-1.13.2-1.x86_64 -DYNLINK,/usr/lib/libcom_err.so.2,0a5123fcad89311eba22dbc6cc5a5d1c8ce2f1da,Arch-e2fsprogs-1.42.13-1.x86_64 -DYNLINK,/usr/lib/libkrb5support.so.0,8c89d9855e5571df27350ed04448a2fadf3693d5,Arch-krb5-1.13.2-1.x86_64 -DYNLINK,/usr/lib/libkeyutils.so.1,a0fb75e3bb8a46c9c42aa2d370be99440470d550,Arch-keyutils-1.5.9-1.x86_64 -DYNLINK,/usr/lib/libresolv.so.2,a31a77f08069f211113d3aafb3d422c11694dd97,Arch-glibc-2.22-3.x86_64 -DYNLINK,/usr/lib/libvorbis.so.0.4.8,7fdd26b3895c1c8a1cdb0fc8d4523d6cb84beeff,Arch-libvorbis-1.3.5-1.x86_64 -DYNLINK,/usr/lib/libvorbis.so.0,7fdd26b3895c1c8a1cdb0fc8d4523d6cb84beeff,Arch-libvorbis-1.3.5-1.x86_64 -DYNLINK,/usr/lib/libogg.so.0,a58a93ec9181e3682b9bfdaa9041cf68d06bb9dd,Arch-libogg-1.3.2-1.x86_64 -DYNLINK,/usr/lib/libvorbisfile.so.3.3.7,ff1089401173f89b0d40aea11dfef9bbc151705c,Arch-libvorbis-1.3.5-1.x86_64 -DYNLINK,/usr/lib/libvorbisfile.so.3,ff1089401173f89b0d40aea11dfef9bbc151705c,Arch-libvorbis-1.3.5-1.x86_64 -DYNLINK,/usr/lib/libogg.so.0.8.2,a58a93ec9181e3682b9bfdaa9041cf68d06bb9dd,Arch-libogg-1.3.2-1.x86_64 -DYNLINK,/usr/lib/libtheora.so.0.3.10,20e4c310ee24d055476bc64f60a4c5d94b64070b,Arch-libtheora-1.1.1-3.x86_64 -DYNLINK,/usr/lib/libtheora.so.0,20e4c310ee24d055476bc64f60a4c5d94b64070b,Arch-libtheora-1.1.1-3.x86_64 -DYNLINK,/usr/lib/libvorbisenc.so.2.0.11,94c4a7c1a204be09463acefd151d9f1bc5665937,Arch-libvorbis-1.3.5-1.x86_64 -DYNLINK,/usr/lib/libvorbisenc.so.2,94c4a7c1a204be09463acefd151d9f1bc5665937,Arch-libvorbis-1.3.5-1.x86_64 -DYNLINK,/home/mupuf/install/lib/libGL.so.1.2.0,7cffd8343a755ac5cf93d9cf2cb2ee4c0ec9cbb8,ssh://mperes@people.freedesktop.org/~mperes/mesa.git/egl_dri3-a6f2d32 -DYNLINK,/home/mupuf/install/lib/libGL.so.1,7cffd8343a755ac5cf93d9cf2cb2ee4c0ec9cbb8,ssh://mperes@people.freedesktop.org/~mperes/mesa.git/egl_dri3-a6f2d32 -DYNLINK,/usr/lib/libexpat.so.1,084d5f181adc197d5cf12ba1e576b82ce9aa865e,Arch-expat-2.1.0-4.x86_64 -DYNLINK,/usr/lib/libxcb-dri3.so.0,1624047c67518e052720261f844562d82f9ead96,Arch-libxcb-1.11.1-1.x86_64 -DYNLINK,/usr/lib/libxcb-present.so.0,c430a8ae6fdef25763419d8c872e4e9694a9fd8c,Arch-libxcb-1.11.1-1.x86_64 -DYNLINK,/usr/lib/libxcb-randr.so.0,7105e21c07aaf7ab5ce9f919ceb966d64ea3c278,Arch-libxcb-1.11.1-1.x86_64 -DYNLINK,/usr/lib/libxcb-xfixes.so.0,192e198c8e5bbc73264b1072305c7a8a19c17ea6,Arch-libxcb-1.11.1-1.x86_64 -DYNLINK,/usr/lib/libxcb-render.so.0,8a3a44d2ddb3ee7bb729d086b4017caf454faa3b,Arch-libxcb-1.11.1-1.x86_64 -DYNLINK,/usr/lib/libxcb-shape.so.0,468d3168d4cea5fc68a7ad5f6ce0145f08cb7919,Arch-libxcb-1.11.1-1.x86_64 -DYNLINK,/usr/lib/libxcb-sync.so.1,1b65ffe57b8f7bd2b233f9f44a6dcaa4acba644b,Arch-libxcb-1.11.1-1.x86_64 -DYNLINK,/usr/lib/libxshmfence.so.1,a2a173f77eb3c34e6022780a3ca2ea778472be54,Arch-libxshmfence-1.2-1.x86_64 -DYNLINK,/home/mupuf/install/lib/libglapi.so.0,d52b4ce373af37e32a52c48aca47c4a4a873edd1,ssh://mperes@people.freedesktop.org/~mperes/mesa.git/egl_dri3-a6f2d32 -DYNLINK,/usr/lib/libXdamage.so.1,5628004f4fe77abeca831a8ead1c24e54ed3890a,Arch-libxdamage-1.1.4-2.x86_64 -DYNLINK,/usr/lib/libXfixes.so.3,c116fb23a09d318ea0d32012374a0b4819529c8d,Arch-libxfixes-5.0.1-1.x86_64 -DYNLINK,/usr/lib/libX11-xcb.so.1,a5cce5a5e2d6a6c3f8e4d9a31c9ef0445f63b4b3,Arch-libx11-1.6.3-1.x86_64 -DYNLINK,/usr/lib/libxcb-glx.so.0,ea5dc27e4bae75cdff70216ebeaffccfc22ce1bb,Arch-libxcb-1.11.1-1.x86_64 -DYNLINK,/usr/lib/libxcb-dri2.so.0,24ff4164929f13a15ec65336a836739f6f557d55,Arch-libxcb-1.11.1-1.x86_64 -DYNLINK,/home/mupuf/install/lib/libdrm.so.2,e26b62afaa450ad5b9c9d606e4603d51bea7cc71,ssh://mperes@people.freedesktop.org/~mperes/drm/master: ahead 226-3045523 -SOCKET_UNIX_CONNECT,/tmp/.X11-unix/X0,/home/mupuf/install/lib/xorg-server/Xorg,'/home/mupuf/install/lib/xorg-server/Xorg' '-nolisten' 'tcp' ':0' 'vt1' '-auth' '/tmp/serverauth.9qXVoDcHr7',a3e0e9075ef5f32991e2b9890d60c6d102d5faa6,ssh://mperes@people.freedesktop.org/~mperes/xserver/master: ahead 270, behind 3-c99fb55 -XORG_SESSION_OPENED,(null) -XORG_DISPLAY,0,KWin,3120,1920,24 -DYNLINK,/usr/lib/libudev.so.1.6.4,6587c22b9f0ba359d68a6315cc7f24284664f52f,Arch-libsystemd-227-1.x86_64 -DYNLINK,/usr/lib/libudev.so.1,6587c22b9f0ba359d68a6315cc7f24284664f52f,Arch-libsystemd-227-1.x86_64 -DYNLINK,/usr/lib/libcap.so.2,0e11f218f90843afb6359c1d1856d974a1d9fe58,Arch-libcap-2.24-2.x86_64 -DYNLINK,/usr/lib/libattr.so.1,f0cdbed41dcfb9772873406569fac2e155abd222,Arch-attr-2.4.47-1.x86_64 -DYNLINK,/home/mupuf/install/lib/dri/i965_dri.so,7f46e221c0eae5219f642e9e7e98507ad9928fc4,ssh://mperes@people.freedesktop.org/~mperes/mesa.git/egl_dri3-a6f2d32 -DYNLINK,/home/mupuf/install/lib/dri//i965_dri.so,7f46e221c0eae5219f642e9e7e98507ad9928fc4,ssh://mperes@people.freedesktop.org/~mperes/mesa.git/egl_dri3-a6f2d32 -DYNLINK,/usr/lib/libnettle.so.6,141b6bf17aa0176724a3b913150db7b566e75674,Arch-nettle-3.1.1-1.x86_64 -DYNLINK,/home/mupuf/install/lib/libdrm_intel.so.1,d2ba16b233cf260e12977b71358266c6e306e058,ssh://mperes@people.freedesktop.org/~mperes/drm/master: ahead 226-3045523 -DYNLINK,/usr/lib/libpciaccess.so.0,035c8ad06e10405e5b850af23f98ff6eff03c96c,Arch-libpciaccess-0.13.4-1.x86_64 -DYNLINK,/usr/lib/libstdc++.so.6,130106e6ae93ddb4796ea583e1cdddfaf5257b35,Arch-gcc-libs-multilib-5.2.0-2.x86_64 -DYNLINK,/usr/lib/libgcc_s.so.1,36183ac5fa1774a8591c6bbb473d959077f3bb6e,Arch-gcc-libs-multilib-5.2.0-2.x86_64 -IOCTL,/dev/dri/renderD128 -LIBDRM,1,3,0 -DRM,1,6,0,i915,20150522,Intel Graphics,0x8086,0x0412,hsw_gt2,Intel(R) Haswell Desktop -INTEL_DRM,450,1200,1200,350,200 -XORG_WINDOW_CREATE,215,4194306,3120,1920,24 -DYNLINK,/usr/lib/libXcursor.so.1.0.2,c5cf29c97803bef02c8845fe83646b9d25ade4ee,Arch-libxcursor-1.1.14-2.x86_64 -DYNLINK,/usr/lib/libXcursor.so.1,c5cf29c97803bef02c8845fe83646b9d25ade4ee,Arch-libxcursor-1.1.14-2.x86_64 -DYNLINK,/usr/lib/libXrender.so.1,0ae36e0af4c2385084bc7b6cfd77289bb2a0b746,Arch-libxrender-0.9.9-1.x86_64 -DYNLINK,/usr/lib/libtxc_dxtn.so,61959dd2bc5b130891e44c780d9a2d0ce74b6b3c,Arch-libtxc_dxtn-1.0.1-6.x86_64 -DYNLINK,/usr/lib/libpng16.so.16.18.0,6b0396a700ac3de412f727f9ca2755654275fe3d,Arch-libpng-1.6.18-1.x86_64 -DYNLINK,/usr/lib/libpng16.so.16,6b0396a700ac3de412f727f9ca2755654275fe3d,Arch-libpng-1.6.18-1.x86_64 -DYNLINK,/usr/lib/libfreetype.so.6.12.1,fcd097713f4ffb9250791ea46728240a5bd807ab,Arch-freetype2-2.6.1-1.x86_64 -DYNLINK,/usr/lib/libfreetype.so.6,fcd097713f4ffb9250791ea46728240a5bd807ab,Arch-freetype2-2.6.1-1.x86_64 -DYNLINK,/usr/lib/libbz2.so.1.0,a1f1a03092277b1a9033bdde5b891e0c93367372,Arch-bzip2-1.0.6-5.x86_64 -DYNLINK,/usr/lib/libharfbuzz.so.0,8a36a67c2dc4956756296836957885815576d9bf,Arch-harfbuzz-1.0.6-2.x86_64 -DYNLINK,/usr/lib/libglib-2.0.so.0,2d4db66da30dca7d000053f67659081b7ed41ff1,Arch-glib2-2.46.1-1.x86_64 -DYNLINK,/usr/lib/libgraphite2.so.3,dfd45840fa8b87be8b8dfba5ac049e3a349198a5,Arch-graphite-1:1.3.3-1.x86_64 -DYNLINK,/usr/lib/libpcre.so.1,5cbf4c5a40574ed70aff464dbf590a981eba40b9,Arch-pcre-8.37-4.x86_64 -DYNLINK,/usr/lib/libasound.so.2.0.0,3791381047b0f3c25b9a808f8feeb0765ff07051,Arch-alsa-lib-1.0.29-1.x86_64 -DYNLINK,/usr/lib/alsa-lib/libasound_module_pcm_pulse.so,b876d8ed3ff4afe990f5010bded42bc155f43d8e,Arch-alsa-plugins-1.0.29-2.x86_64 -DYNLINK,/usr/lib/libpulse.so.0,c353a67917100f0dbe298a16f6a9a31dc9a218ea,Arch-libpulse-7.1-1.x86_64 -DYNLINK,/usr/lib/pulseaudio/libpulsecommon-7.1.so,e6017b3fedf6c2eb9a00924ad49063715d1975a3,Arch-libpulse-7.1-1.x86_64 -DYNLINK,/usr/lib/libjson-c.so.2,c3067219d38425f9694574175bb8cb76cb291439,Arch-json-c-0.12-2.x86_64 -DYNLINK,/usr/lib/libdbus-1.so.3,57557f9ce8961062342bd15363a55890c7646f91,Arch-libdbus-1.10.2-1.x86_64 -DYNLINK,/usr/lib/libsystemd.so.0,2805f47aa8a276f5232469836286162e26de04c1,Arch-libsystemd-227-1.x86_64 -DYNLINK,/usr/lib/libsndfile.so.1,15ac12c40a9a8eba4557ded4816b4b115440cb14,Arch-libsndfile-1.0.25-3.x86_64 -DYNLINK,/usr/lib/libasyncns.so.0,5898825647e02c6a4713b0c84d51540f3398d7f3,Arch-libasyncns-0.8-5.x86_64 -DYNLINK,/usr/lib/liblzma.so.5,5f0042e5eeb74a2cde80160b5dc469a5b1879123,Arch-xz-5.2.2-1.x86_64 -DYNLINK,/usr/lib/liblz4.so.1,044a31894df0f640c1280dc0bca6da5c287a6ff4,Arch-lz4-131-1.x86_64 -DYNLINK,/usr/lib/libgcrypt.so.20,a5961be4e46cbfc71417e24d7848cccb2d6eea29,Arch-libgcrypt-1.6.4-1.x86_64 -DYNLINK,/usr/lib/libgpg-error.so.0,4db3e11bf9cab86fdb60024be8d71fbc94ce0edf,Arch-libgpg-error-1.20-1.x86_64 -DYNLINK,/usr/lib/libFLAC.so.8,6f712553fc15a0ffd9517abe8568cfeb708561b9,Arch-flac-1.3.1-1.x86_64 -DYNLINK,/usr/lib/libnsl.so.1,f6fe7165c7ca1a143583ec61de4523048ee3b31b,Arch-glibc-2.22-3.x86_64 -SOCKET_UNIX_CONNECT,/tmp/.X11-unix/X0,/home/mupuf/install/lib/xorg-server/Xorg,'/home/mupuf/install/lib/xorg-server/Xorg' '-nolisten' 'tcp' ':0' 'vt1' '-auth' '/tmp/serverauth.9qXVoDcHr7',a3e0e9075ef5f32991e2b9890d60c6d102d5faa6,ssh://mperes@people.freedesktop.org/~mperes/xserver/master: ahead 270, behind 3-c99fb55 -SOCKET_UNIX_CONNECT,/run/user/1000/pulse/native,/usr/lib/systemd/systemd,'/usr/lib/systemd/systemd' '--user',68cbcef676aff69e9e72697c30e9f3af0012a663,Arch-systemd-227-1.x86_64 -IOCTL,/dev/sr0 -IOCTL,socket:[642525] -IOCTL,socket:[640914] -XORG_CLOSE,:0 -THROTTLING,8,0,0,0,0,0,0,0,0,0 --- Env dump end -- - -That's it for now, folks! diff --git a/utils/env_dump/cpu.c b/utils/env_dump/cpu.c deleted file mode 100644 index e4d1399..0000000 --- a/utils/env_dump/cpu.c +++ /dev/null @@ -1,197 +0,0 @@ -/* Copyright (c) 2015, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define _GNU_SOURCE - -#include "env_dump.h" - -#include <sys/resource.h> -#include <sys/sysinfo.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <malloc.h> -#include <stdint.h> -#include <sched.h> - - -char * -_env_dump_read_file(const char *path, size_t len_max) -{ - size_t len; - char *buf; - - FILE *file = fopen(path, "r"); - if (!file) - return NULL; - - buf = calloc(len_max, sizeof(char)); - if (!buf) { - fclose(file); - return buf; - } - - len = fread(buf, 1, len_max, file); - - /* get rid of the final \n */ - if (len > 0 && buf[len - 1] == '\n') - buf[len - 1] = '\0'; - - return buf; -} - -static void -dump_cpu_common() -{ - char *path = malloc(255); - int i; - - fprintf(env_file, "CPU_FREQ,%i", get_nprocs_conf()); - for (i = 0; i < get_nprocs_conf(); i++) { - char *min, *max; - snprintf(path, 255, - "/sys/devices/system/cpu/cpu%i/cpufreq/scaling_min_freq", - i); - min = _env_dump_read_file(path, 20); - - snprintf(path, 255, - "/sys/devices/system/cpu/cpu%i/cpufreq/scaling_max_freq", - i); - max = _env_dump_read_file(path, 20); - - fprintf(env_file, ",%s,%s", min, max); - free(min); - free(max); - } - fprintf(env_file, "\n"); - - free(path); -} - -static void -dump_shed_common() -{ - uint64_t affinity = 0; - const char *sched_str; - int prio, sched, i; - cpu_set_t cpu_set; - - /* FIXME: This does not work when having more than 64 CPUs */ - sched_getaffinity(0, sizeof(cpu_set), &cpu_set); - for (i = 0; i < 64; i++) { - affinity |= (CPU_ISSET(i, &cpu_set) != 0) << i; - } - - sched = sched_getscheduler(0); - switch (sched) { - case SCHED_OTHER: - sched_str = "SCHED_OTHER"; - break; - case SCHED_BATCH: - sched_str = "SCHED_BATCH"; - break; - case SCHED_IDLE: - sched_str = "SCHED_IDLE"; - break; - case SCHED_FIFO: - sched_str = "SCHED_FIFO"; - break; - case SCHED_RR: - sched_str = "SCHED_RR"; - break; - case -1: - sched_str = "ERROR"; - break; - default: - sched_str = "UNKNOWN"; - break; - } - - prio = getpriority(PRIO_PROCESS, 0); - - fprintf(env_file, "SCHED,%s,%i,%i,%lu,%i\n", sched_str, - get_nprocs_conf(), get_nprocs(), affinity, prio); -} - -static void -dump_throttling_common() -{ - char *package, *path = malloc(255); - int i; - - package = _env_dump_read_file("/sys/devices/system/cpu/cpu0/thermal_throttle/package_throttle_count", 20); - - fprintf(env_file, "THROTTLING,%i,%s", get_nprocs_conf(), package); - for (i = 0; i < get_nprocs_conf(); i++) { - char *core; - snprintf(path, 255, - "/sys/devices/system/cpu/cpu%i/thermal_throttle/core_throttle_count", - i); - core = _env_dump_read_file(path, 20); - fprintf(env_file, ",%s", core); - free(core); - } - fprintf(env_file, "\n"); - - free(path); -} - -static void -dump_intel_pstate() -{ - struct stat pstate_dir; - char *num_pstates, *turbo_pct, *min, *max, *turbo; - - /* check that the intel pstate governor is being used */ - if (stat("/sys/devices/system/cpu/intel_pstate/", &pstate_dir)) - return; - - /* read the different values */ - num_pstates = _env_dump_read_file("/sys/devices/system/cpu/intel_pstate/num_pstates", 10); - turbo_pct = _env_dump_read_file("/sys/devices/system/cpu/intel_pstate/turbo_pct", 10); - min = _env_dump_read_file("/sys/devices/system/cpu/intel_pstate/min_perf_pct", 4); - max = _env_dump_read_file("/sys/devices/system/cpu/intel_pstate/max_perf_pct", 4); - turbo = _env_dump_read_file("/sys/devices/system/cpu/intel_pstate/no_turbo", 2); - - fprintf(env_file, "INTEL_PSTATE,%s,%s,%s,%s,%s\n", num_pstates, - turbo_pct, turbo, min, max); - - free(num_pstates); free(turbo_pct); free(min); free(max); free(turbo); -} - -void -_env_dump_cpu_init() -{ - dump_shed_common(); - dump_cpu_common(); - dump_throttling_common(); - dump_intel_pstate(); -} - -void -_env_dump_cpu_fini() -{ - dump_throttling_common(); -}
\ No newline at end of file diff --git a/utils/env_dump/drm.c b/utils/env_dump/drm.c deleted file mode 100644 index 5416dfa..0000000 --- a/utils/env_dump/drm.c +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright (c) 2015, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define _GNU_SOURCE - -#include "env_dump.h" - -#include <xf86drm.h> -#include <stdlib.h> -#include <string.h> - -static char * -read_drm_sysfs(const char *node, const char *file, size_t len_max) -{ - char sysfs_path[101]; - - snprintf(sysfs_path, sizeof(sysfs_path), "/sys/class/drm/%s/%s", node, file); - return _env_dump_read_file(sysfs_path, len_max); -} - -static long -read_drm_sysfs_int(const char *node, const char *file, int base) -{ - char *val = read_drm_sysfs(node, file, 20); - long ret = -1; - - if (val) { - ret = strtol(val, NULL, base); - free(val); - } - - return ret; - -} - -static void -_env_dump_drm_i915_dump_info(const char *node_name, - const char *primary_node_name, int fd) -{ - long min, max, rp0, rp1, rpn; - - min = read_drm_sysfs_int(primary_node_name, "gt_min_freq_mhz", 10); - max = read_drm_sysfs_int(primary_node_name, "gt_max_freq_mhz", 10); - rp0 = read_drm_sysfs_int(primary_node_name, "gt_RP0_freq_mhz", 10); - rp1 = read_drm_sysfs_int(primary_node_name, "gt_RP1_freq_mhz", 10); - rpn = read_drm_sysfs_int(primary_node_name, "gt_RPn_freq_mhz", 10); - - fprintf(env_file, "INTEL_DRM,%li,%li,%li,%li,%li\n", min, max, rp0, rp1, rpn); -} - -void -_env_dump_drm_dump_info(const char *path, int fd) -{ - char *(*orig_drmGetPrimaryDeviceNameFromFd)(int fd); - drmVersionPtr (*orig_drmGetLibVersion)(int fd); - drmVersionPtr (*orig_drmGetVersion)(int fd); - void (*orig_drmFreeVersion)(drmVersionPtr v); - drmVersionPtr version_lib = NULL, version_drm = NULL; - char *node_name = NULL, *primary_node = NULL, *primary_node_name = NULL; - char *vendor = NULL, *devid = NULL; - - /* resolve symbols */ - orig_drmGetPrimaryDeviceNameFromFd = _env_dump_resolve_symbol_by_name("drmGetPrimaryDeviceNameFromFd"); - orig_drmGetVersion = _env_dump_resolve_symbol_by_name("drmGetVersion"); - orig_drmGetLibVersion = _env_dump_resolve_symbol_by_name("drmGetLibVersion"); - orig_drmFreeVersion = _env_dump_resolve_symbol_by_name("drmFreeVersion"); - if (!orig_drmGetPrimaryDeviceNameFromFd || !orig_drmGetVersion || - !orig_drmGetLibVersion || !orig_drmFreeVersion) - return; - - /* Check if the path starts with /, as it should be */ - if (path[0] != '/') - goto exit; - - /* Get the general DRM information */ - primary_node = orig_drmGetPrimaryDeviceNameFromFd(fd); - node_name = strrchr(path, '/'); - if (!node_name || !primary_node) - goto exit; - - primary_node_name = strrchr(primary_node, '/'); - version_lib = orig_drmGetLibVersion(fd); - version_drm = orig_drmGetVersion(fd); - if (!primary_node_name || !version_lib || !version_drm) - goto exit; - - /* get rid of the '/' in the name */ - node_name++; - primary_node_name++; - - /* fetch the BusID */ - vendor = read_drm_sysfs(node_name, "device/vendor", 16); - devid = read_drm_sysfs(node_name, "device/device", 16); - - fprintf(env_file, "LIBDRM,%i,%i,%i\n", version_lib->version_major, - version_lib->version_minor, - version_lib->version_patchlevel); - fprintf(env_file, "DRM,%i,%i,%i,%s,%s,%s,%s,%s\n", - version_drm->version_major, version_drm->version_minor, - version_drm->version_patchlevel, version_drm->name, - version_drm->date, version_drm->desc, vendor, devid); - - free(vendor); free(devid); - - /* Add data, per vendor */ - if (strcmp(version_drm->name, "i915") == 0) - _env_dump_drm_i915_dump_info(node_name, primary_node_name, fd); - -exit: - if (primary_node) - free(primary_node); - if (version_lib) - orig_drmFreeVersion(version_lib); - if (version_drm) - orig_drmFreeVersion(version_drm); -}
\ No newline at end of file diff --git a/utils/env_dump/env_dump.c b/utils/env_dump/env_dump.c deleted file mode 100644 index cd65b81..0000000 --- a/utils/env_dump/env_dump.c +++ /dev/null @@ -1,157 +0,0 @@ -/* Copyright (c) 2015, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define _GNU_SOURCE - -#include "env_dump.h" - -#include <sys/stat.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdio.h> -#include <time.h> -#include <link.h> - -FILE *env_file = NULL; - -static void fini(); - -/* Yes, the program may call _exit() and in this case, the fini() function will - * never be called. Fix this! - */ -void _exit(int status) -{ - void (*const orig__exit)(int) = _env_dump_resolve_symbol_by_name("_exit"); - fini(); - orig__exit(status); -} - -/* handle exit signals to run the fini() functions */ -static void -sig_handler(int sig, siginfo_t *siginfo, void *context) -{ - /* this will also call fini! */ - _exit(-1); -} - -static void -register_signal_handler(int signal) -{ - struct sigaction act; - memset (&act, '\0', sizeof(act)); - act.sa_sigaction = &sig_handler; - act.sa_flags = SA_SIGINFO; - if (sigaction(signal, &act, NULL) < 0) { - perror ("sigaction"); - } -} - -static void -print_date_and_time() -{ - struct tm* tm_info; - time_t timer; - char buf[51]; - - time(&timer); - tm_info = localtime(&timer); - - strftime(buf, sizeof(buf), "%Y:%m:%d,%H:%M:%S,%Z(%z)", tm_info); - - fprintf(env_file, "DATE,%s\n", buf); -} - -__attribute__((constructor)) -static void init() { - const char *base_path = getenv("ENV_DUMP_FILE"); - char *path; - int fd; - - if (base_path == NULL) - base_path = "/tmp/env_dump"; - - if (strcmp(base_path, "stderr") != 0) { - /* if the file asked by the user already exists, append the pid to the - * name. Otherwise, just use the name. - */ - fd = open(base_path, O_EXCL | O_CREAT | O_WRONLY, 0666); - if (fd >= 0) { - env_file = fdopen(fd, "w"); - fprintf(stderr, "path = %s\n", base_path); - } else { - path = malloc(strlen(base_path) + 1 + 10 + 1); /* log(2^32) = 10 */ - if (!path) - exit(1); - sprintf(path, "%s.%i", base_path, getpid()); - fprintf(stderr, "path = %s.%i\n", base_path, getpid()); - env_file = fopen(path, "w"); - free(path); - } - /* do not buffer this stream */ - setvbuf(env_file, (char *)NULL, _IONBF, 0); - } else { - env_file = stderr; - } - - /* handle some signals that would normally result in an exit without - * calling the fini functions. This will hopefully be done before any - * other library does it. It is however OK if the program replaces the - * handler as long as it calls exit() or _exit(). - */ - register_signal_handler(SIGHUP); - register_signal_handler(SIGINT); - register_signal_handler(SIGPIPE); - register_signal_handler(SIGTERM); - - fprintf(env_file, "-- Env dump start (version 1) --\n"); - - print_date_and_time(); - - _env_dump_posix_env_init(); - _env_dump_fd_init(); - _env_dump_gl_init(); - _env_dump_linux_init(); - _env_dump_cpu_init(); - _env_dump_libs_init(); - _env_dump_net_init(); -} - -__attribute__((destructor)) -static void fini() { - _env_dump_net_fini(); - _env_dump_libs_fini(); - _env_dump_cpu_fini(); - _env_dump_linux_fini(); - _env_dump_gl_fini(); - _env_dump_fd_init(); - _env_dump_posix_env_fini(); - - fprintf(env_file, "-- Env dump end --\n"); - fclose(env_file); -} diff --git a/utils/env_dump/env_dump.h b/utils/env_dump/env_dump.h deleted file mode 100644 index 3b03ad6..0000000 --- a/utils/env_dump/env_dump.h +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (c) 2015, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _ENV_DUMP_H_ -#define _ENV_DUMP_H_ - -#include <GL/glx.h> -#include <stdio.h> - -extern FILE *env_file; - -#define likely(x) __builtin_expect(!!(x), 1) -#define unlikely(x) __builtin_expect(!!(x), 0) - -typedef void (*fd_callback)(int fd, void *user); - -void _env_dump_libs_init(); -void _env_dump_libs_fini(); - -void _env_dump_cpu_init(); -void _env_dump_cpu_fini(); - -void _env_dump_drm_dump_info(const char *path, int fd); - -void _env_dump_fd_init(); -void _env_dump_fd_fini(); -void _env_dump_close_callback(int fd, fd_callback cb, void *user); - -void _env_dump_gl_init(); -void _env_dump_gl_fini(); - -void _env_dump_linux_init(); -void _env_dump_linux_fini(); - -void _env_dump_net_init(); -void _env_dump_net_fini(); - -void _env_dump_posix_env_init(); -void _env_dump_posix_env_fini(); - -void _env_dump_compute_and_print_sha1(const char *full_path); -void env_var_dump_binary_information(int pid); - -char *_env_dump_read_file(const char *path, size_t len_max); - -/* internal pointer-tracking mechanism */ -enum symbol_key_t { - SYMB_IOCTL = 0, - SYMB_GLXSWAPBUFFERS, - SYMB_EGLSWAPBUFFERS, - SYMB_GLXMAKECURRENT, - SYMB_EGLMAKECURRENT, - SYMB_END -}; /* do not forget to duplicate the name in libs.c's symbol_key_str */ - -void *_env_dump_resolve_local_symbol_by_name(const char *symbol); -void *_env_dump_resolve_symbol_by_name(const char *symbol); -void *_env_dump_resolve_symbol_by_id(enum symbol_key_t symbol); -void _env_dump_replace_symbol(const char *symbol, void *ptr); - -#endif diff --git a/utils/env_dump/env_dump.sh b/utils/env_dump/env_dump.sh deleted file mode 100755 index 7c906d7..0000000 --- a/utils/env_dump/env_dump.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -if [ $# -eq 0 ] -then - echo "Usage: $0 env_dump_file binary param1 param2 ..." -fi - -dir=$(dirname $(readlink -f $0)) -so_path="$dir/env_dump.so" -dump_file="$1" -shift - -LD_PRELOAD="$so_path" ENV_DUMP_FILE="$dump_file" "$@" -exit $? diff --git a/utils/env_dump/env_dump_extend.sh b/utils/env_dump/env_dump_extend.sh deleted file mode 100755 index 465a097..0000000 --- a/utils/env_dump/env_dump_extend.sh +++ /dev/null @@ -1,194 +0,0 @@ -#!/bin/bash - -# Requires pkcon from packagekit, the file /etc/lsb-release, dmidecode and msr-tools - -if [[ $# -ne 2 ]] -then - echo "Usage: $0 SHA1_DB env_dump_file" -fi - -SHA1_DB="$1" -dump_file="$2" - -root_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -function get_binary_version() { - filename=$1 - sha1=$2 - - upstream=$($SHA1_DB/sha1_db $SHA1_DB $sha1 read_attr upstream 2> /dev/null) - version=$($SHA1_DB/sha1_db $SHA1_DB $sha1 read_attr version 2> /dev/null) - - if [ -n "$upstream" ] && [ -n "$version" ]; then - echo $upstream-$version - return 0 - else - # We did not find the file, add it to the sha1 DB. First check if it was - # provided by the distro - if [[ $distro =~ ^Ubuntu ]]; then - pkg=$(dpkg -S $filename 2> /dev/null | cut -d ':' -f 2 | xargs) - else - pkg=$(pkcon search file $filename 2> /dev/null | grep Installed | xargs | cut -d ' ' -f 2) - fi - [ -z "$pkg" ] && echo "UNKNOWN_VERSION" && return 1 - - # Now check that the SHA1 still matches the one used by the benchmark - if [ "$sha1" == $(sha1sum $filename | cut -d ' ' -f 1) ] - then - $SHA1_DB/sha1_db $SHA1_DB $sha1 add $pkg $filename $distro > /dev/null - echo $distro-$pkg - return 0 - fi - fi -} - -function resolve_SHA1() { - SHA1_DB="$1" - dump_file="$2" - - [ -z "$SHA1_DB" ] && return 0 - - # Try to get the name of the distro from lsb-release, revert to pkcon if not - # available - distro=$(grep DISTRIB_ID /etc/lsb-release 2> /dev/null | cut -d '=' -f2) - distro_version=$(grep DISTRIB_RELEASE /etc/lsb-release 2> /dev/null | cut -d '=' -f2) - if [ -z "$distro" ] - then - distro=$(pkcon backend-details 2> /dev/null | grep Name | xargs | cut -d ' ' -f 2) - [ -z "$distro" ] && distro="UNK_DISTRO"] - elif [ -n "$distro_version" ] && [ "$distro_version" != "rolling" ] - then - distro="${distro}_${distro_version}" - fi - - # resolve the SHA1 of the EXE - exe_line=$(grep -e '^EXE,' $dump_file) - filename=$(echo "$exe_line" | cut -d ',' -f 2) - sha1=$(echo "$exe_line" | cut -d ',' -f 4) - version=$(get_binary_version $filename $sha1) - sed -i "s\`$exe_line\`$exe_line,$version\`g" $dump_file - - # resolve the SHA1 of the libraries - for line in $(grep -e '^BOOTLINK\|^DYNLINK,' $dump_file) - do - filename=$(echo "$line" | cut -d ',' -f 2) - sha1=$(echo "$line" | cut -d ',' -f 3) - version=$(get_binary_version $filename $sha1) - sed -i "s\`$line\`$line,$version\`g" $dump_file - done - - # resolve the SHA1 of the binary on the other side of a unix socket - grep -e '^SOCKET_UNIX_CONNECT,' $dump_file | while read line - do - filename=$(echo "$line" | cut -d ',' -f 3) - sha1=$(echo "$line" | cut -d ',' -f 5) - version=$(get_binary_version $filename $sha1) - sed -i "s\`$line\`$line,$version\`g" $dump_file - done - - return 0 -} - -function add_dmidecode_info() { - dimdecode=$(sudo -n dmidecode 2> /dev/null) - - # test if dmidecode ran properly - [ $? -ne 0 ] && echo "WARNING; dmidecode is not present or not working..." && return 0 - - # Motherboard information - mobo_info=$(echo "$dimdecode" | grep -A 3 "Base Board Information") - manufacturer=$(echo "$mobo_info" | grep "Manufacturer:" | cut -d ':' -f 2- | xargs) - product_name=$(echo "$mobo_info" | grep "Product Name:" | cut -d ':' -f 2- | xargs) - version=$(echo "$mobo_info" | grep "Version:" | cut -d ':' -f 2- | xargs) - mobo_info=$(echo "MOTHERBOARD,$manufacturer,$product_name,$version\n") - - # BIOS information - bios_info=$(echo "$dimdecode" | grep -A 6 "BIOS Information") - vendor=$(echo "$bios_info" | grep "Vendor:" | cut -d ':' -f 2- | xargs) - version=$(echo "$bios_info" | grep "Version:" | cut -d ':' -f 2- | xargs) - date=$(echo "$bios_info" | grep "Release Date:" | cut -d ':' -f 2- | xargs) - bios_info=$(echo "BIOS,$vendor,$version,$date\n") - - # CPU information - cpu_count=$(echo "$dimdecode" | grep "Processor Information" | wc -l) - grep_lines=$(echo "$dimdecode" | sed -n '/Processor Information/!b;:a;/Handle 0x/!{$!{N;ba}};{/Processor Information/p}' | wc -l) - cpu_max=$((cpu_count - 1)) - cpu_info="" - for i in $(seq 0 $cpu_max) - do - e=$(($i + 1)) - - manufacturer=$(echo "$dimdecode" | grep -m $e -A $grep_lines "Processor Information$" | grep "Manufacturer:" | tail -n 1 | cut -d ':' -f 2- | xargs) - id=$(echo "$dimdecode" | grep -m $e -A $grep_lines "Processor Information$" | grep "ID:" | tail -n 1 | cut -d ':' -f 2- | xargs) - version=$(echo "$dimdecode" | grep -m $e -A $grep_lines "Processor Information$" | grep "Version:" | tail -n 1 | cut -d ':' -f 2- | xargs) - max_speed=$(echo "$dimdecode" | grep -m $e -A $grep_lines "Processor Information$" | grep "Max Speed:" | tail -n 1 | cut -d ':' -f 2- | xargs) - core_count=$(echo "$dimdecode" | grep -m $e -A $grep_lines "Processor Information$" | grep "Core Count" | tail -n 1 | cut -d ':' -f 2- | xargs) - thread_count=$(echo "$dimdecode" | grep -m $e -A $grep_lines "Processor Information$" | grep "Thread Count:" | tail -n 1 | cut -d ':' -f 2- | xargs) - - l1_handle=$(echo "$dimdecode" | grep -m $e -A $grep_lines "Processor Information$" | grep "L1 Cache Handle:" | tail -n 1 | cut -d ':' -f 2- | xargs) - l2_handle=$(echo "$dimdecode" | grep -m $e -A $grep_lines "Processor Information$" | grep "L2 Cache Handle:" | tail -n 1 | cut -d ':' -f 2- | xargs) - l3_handle=$(echo "$dimdecode" | grep -m $e -A $grep_lines "Processor Information$" | grep "L3 Cache Handle:" | tail -n 1 | cut -d ':' -f 2- | xargs) - - l1_size=$(echo "$dimdecode" | grep -A 15 "Handle $l1_handle" | grep "Installed Size:" | tail -n 1 | cut -d ':' -f 2- | xargs) - l2_size=$(echo "$dimdecode" | grep -A 15 "Handle $l2_handle" | grep "Installed Size:" | tail -n 1 | cut -d ':' -f 2- | xargs) - l3_size=$(echo "$dimdecode" | grep -A 15 "Handle $l3_handle" | grep "Installed Size:" | tail -n 1 | cut -d ':' -f 2- | xargs) - - if [ "$msr_loaded" -eq 1 ] && [[ "$manufacturer" == "Intel" ]] - then - # See table 35-2 of the IA-32 - virt_enabled=$((($(sudo -n rdmsr -p $i 0x3A) & 0x4) != 0)) - else - virt_enabled="-1" - fi - - cpu_info=$(echo "${cpu_info}PROCESSOR,$i,$manufacturer,$id,$version,$core_count,$thread_count,$l1_size,$l2_size,$l3_size,$max_speed,$virt_enabled\n") - done - - # RAM information - stick_count=$(echo "$dimdecode" | grep "Memory Device$" | wc -l) - stick_max=$((stick_count - 1)) - ram_info="" - for i in $(seq 0 $stick_max) - do - e=$(($i + 1)) - - manufacturer=$(echo "$dimdecode" | grep -m $e -A 21 "Memory Device$" | grep "Manufacturer:" | tail -n 1 | cut -d ':' -f 2- | xargs) - part_number=$(echo "$dimdecode" | grep -m $e -A 21 "Memory Device$" | grep "Part Number:" | tail -n 1 | cut -d ':' -f 2- | xargs) - serial=$(echo "$dimdecode" | grep -m $e -A 21 "Memory Device$" | grep "Serial Number:" | tail -n 1 | cut -d ':' -f 2- | xargs) - type=$(echo "$dimdecode" | grep -m $e -A 21 "Memory Device$" | grep "Type:" | tail -n 1 | cut -d ':' -f 2- | xargs) - size=$(echo "$dimdecode" | grep -m $e -A 21 "Memory Device$" | grep "Size:" | tail -n 1 | cut -d ':' -f 2- | xargs) - clock=$(echo "$dimdecode" | grep -m $e -A 21 "Memory Device$" | grep "Configured Clock Speed:" | tail -n 1 | cut -d ':' -f 2- | xargs) - locator=$(echo "$dimdecode" | grep -m $e -A 21 "Memory Device$" | grep "Locator:" | grep -v "Bank" | tail -n 1 | cut -d ':' -f 2- | xargs) - - ram_info=$(echo "${ram_info}RAM_STICK,$i,$type,$manufacturer,$part_number,$serial,$size,$clock,$locator\n") - done - - sed -i "s\`^EXE,\`${mobo_info}${bios_info}${cpu_info}${ram_info}EXE,\`g" $dump_file -} - -function resolve_gpu_name() { - dump_file="$1" - - drm_gpu=$(grep -e '^DRM,' $dump_file) - vendor=$(echo $drm_gpu | cut -d ',' -f 8) - devid=$(echo $drm_gpu | cut -d ',' -f 9) - - case "$vendor" in - 0x8086) - chipset=$($root_dir/scripts/intel-gpu-search-pci-id.sh "$devid") - name=$(echo "$chipset" | cut -d , -f 2 | xargs) - general_name=$(echo "$chipset" | cut -d , -f 3 | xargs | rev | cut -d \) -f 2- | rev) - sed -i "s\`$drm_gpu\`$drm_gpu,$name,$general_name\`g" $dump_file - ;; - esac -} - -# Try to load the MSR module to query MSRs -sudo -n modprobe msr -msr_loaded=$(test -z "$(grep ^msr /proc/modules)" ; echo $?) - -resolve_SHA1 "$SHA1_DB" "$dump_file" -add_dmidecode_info "$dump_file" -resolve_gpu_name "$dump_file" - -exit 0 diff --git a/utils/env_dump/env_dump_parser.py b/utils/env_dump/env_dump_parser.py deleted file mode 100755 index 03d14a1..0000000 --- a/utils/env_dump/env_dump_parser.py +++ /dev/null @@ -1,229 +0,0 @@ -#!/usr/bin/env python3 - -""" -Copyright (c) 2015, Intel Corporation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS -""" - -import collections -import re - -class EnvDumpReport: - csv_layout_v1 = [ - ['BIOS', 'vendor', 'version', 'date'], - ['BOOTLINK', 'fullpath', 'SHA1', 'provider'], - ['CPU_FREQ', 'cpu count', 'cpu#0 min', 'cpu#0 max', 'cpu#1 min', 'cpu#1 max', 'cpu#2 min', 'cpu#2 max', 'cpu#3 min', 'cpu#3 max', 'cpu#4 min', 'cpu#4 max', 'cpu#5 min', 'cpu#5 max', 'cpu#6 min', 'cpu#6 max', 'cpu#7 min', 'cpu#7 max', 'cpu#8 min', 'cpu#8 max', 'cpu#9 min', 'cpu#9 max', 'cpu#10 min', 'cpu#10 max', 'cpu#11 min', 'cpu#11 max'], - ['DATE', 'day', 'time', 'timezone'], - ['DRM', 'major', 'minor', 'patchlevel', 'driver', 'description', 'vendor', 'devid'], - ['DYNLINK', 'fullpath', 'SHA1', 'provider'], - ['EGL_NEWCONTEXTUSED', 'vendor', 'version', 'client APIs', 'extensions'], - ['ENV', 'key', 'value'], - ['ENV_SET', 'key', 'value'], - ['ENV_UNSET', 'value'], - ['ENV_CLEAR', 'value'], - ['EXE', 'fullpath', 'cmdline', 'SHA1', 'provider'], - ['GL_NEWCONTEXTUSED', 'vendor', 'renderer', 'version', 'GL version', 'GLSL version', 'extension count', 'extensions'], - ['GLX_NEWCONTEXTUSED', 'vendor', 'version', 'extensions'], - ['INTEL_DRM', 'freq min (MHz)', 'freq max (MHz)', 'freq RP0 (MHz)', 'freq RP1 (MHz)', 'freq RPn (MHz)'], - ['INTEL_PSTATE', 'pstate count', 'turbo pstate (%)', 'turbo disabled', 'min (%)', 'max (%)'], - ['IOCTL', 'fullpath'], - ['KERNEL', 'name', 'nodename', 'release', 'version', 'archicture', 'domain name'], - ['LIBDRM', 'major', 'minor', 'patchlevel'], - ['MOTHERBOARD', 'manufacturer', 'product name', 'version'], - ['PROCESSOR', 'index', 'manufacturer', 'id', 'version', 'core count', 'thread count', 'L1 size', 'L2 size', 'L3 size', 'max clock', 'virtualization enabled'], - ['RAM_STICK', 'index', 'type', 'manufacturer', 'part number', 'serial', 'size', 'actual clock', 'location'], - ['SCHED', 'policy', 'cpu installed', 'cpu active', 'affinity', 'priority'], - ['SOCKET_UNIX_CONNECT', 'fullpath', 'server fullpath', 'server cmdline', 'SHA1', 'provider'], - ['THROTTLING', 'cpu count', 'package', 'cpu list', 'cpu0', 'cpu1', 'cpu2', 'cpu3', 'cpu4', 'cpu5', 'cpu6', 'cpu7', 'cpu8', 'cpu9', 'cpu10', 'cpu11'], - ['XORG_CLOSE', 'display'], - ['XORG_DISPLAY', 'screen id', 'compositor', 'width', 'height', 'depth'], - ['XORG_SESSION_OPENED', 'display name'], - ['XORG_WINDOW_CREATE', 'parent window id', 'window id', 'width', 'height', 'depth'], - ['XORG_WINDOW_RESIZE', 'window id', 'width', 'height'], - ] - - keys = [ - ['BOOTLINK', 'fullpath', '([^/]*)$'], - ['DYNLINK', 'fullpath', '([^/]*)$'], - ['ENV', 'key', ''], - ['PROCESSOR', 'index', ''], - ['RAM_STICK', 'index', ''], - ] - - # format: LINE_HEADER, Key template, value template - human_v1 = [ - ['BIOS', 'HW: BIOS', '${vendor} ${version} ${date}'], - ['BOOTLINK', 'SW: Link (boot): ${fullpath}', '${provider}'], - ['CPU_FREQ', 'OS: CPU governor', 'freq. ranges (kHz): [${cpu#0 min}, ${cpu#0 max}], [${cpu#1 min}, ${cpu#1 max}], [${cpu#2 min}, ${cpu#2 max}], [${cpu#3 min}, ${cpu#3 max}], [${cpu#4 min}, ${cpu#4 max}], [${cpu#5 min}, ${cpu#5 max}], [${cpu#6 min}, ${cpu#6 max}], [${cpu#7 min}, ${cpu#7 max}], [${cpu#8 min}, ${cpu#8 max}], [${cpu#9 min}, ${cpu#9 max}], [${cpu#10 min}, ${cpu#10 max}], [${cpu#11 min}, ${cpu#11 max}]'], - ['DATE', 'OS: Date', '${day} ${time} ${timezone}'], - ['DRM', 'SW: DRM driver', '${vendor}:${devid} : ${driver}(${major}.${minor}.${patchlevel})'], - ['DYNLINK', 'SW: Link (dynamic): ${fullpath}', '${provider}'], - ['EGL_NEWCONTEXTUSED', 'SW: EGL context', '${vendor}, version ${version}, APIs \'${client APIs}\', extensions: ${extensions}'], - ['ENV', 'OS: Env (startup): ${key}', '${value}'], - ['ENV_SET', 'OS: Env set: ${key}', '${value}'], - ['ENV_UNSET', 'OS: Env unset: ${value}', ''], - ['ENV_CLEAR', 'OS: Env clear', ''], - ['EXE', 'OS: Binary cmdline (${fullpath})', '${cmdline} (${provider})'], - ['GL_NEWCONTEXTUSED', 'SW: GL context ${version} GLSL ${GLSL version}', '${vendor}, ${renderer}, ${GL version}, extensions: ${extensions}'], - ['GLX_NEWCONTEXTUSED', 'SW: GLX context', '${vendor}, version ${version}, extensions: ${extensions}'], - ['INTEL_DRM', 'OS: GPU governor', 'freq. range (MHz) = [${freq min (MHz)}, ${freq max (MHz)}], RP0 = ${freq RP0 (MHz)}, RP1 = ${freq RP1 (MHz)}, RPn = ${freq RPn (MHz)}'], - ['INTEL_PSTATE', 'OS: CPU governor pstate', 'range = [${min (%)}%, ${max (%)}%], turbo disabled? ${turbo disabled}'], - ['IOCTL', 'HW: Device node', '${fullpath}'], - ['KERNEL', 'OS: Kernel', '${name}, ${nodename}, ${release}, ${version}, ${achitecture}, ${domain name}'], - ['LIBDRM', 'SW: Libdrm', 'ABI version ${major}.${minor}.${patchlevel}'], - ['MOTHERBOARD', 'HW: Motherboard', '${manufacturer} ${product name} ${version}'], - ['PROCESSOR', 'HW: Processor${index}', '${manufacturer} ${version} (${id}), max freq. ${max clock}, ${core count} cores ${thread count} threads, L1=${L1 size}, L2=${L2 size}, L3=${L3 size}, virt? ${virtualization enabled}'], - ['RAM_STICK', 'HW: RAM${index}', '${type} ${size} @ ${actual clock} installed in ${location}'], - ['SCHED', 'OS: CPU sched.', '${policy}, CPUs=(installed=${cpu installed}, active=${cpu active}), affinity=${affinity} nice=${priority}'], - ['SOCKET_UNIX_CONNECT', 'OS: UNIX service ${fullpath}', 'exe_path=${server fullpath}, cmd=${server cmdline}, version=${provider}'], - ['THROTTLING', 'HW: Throttling events', 'package=${package}, CPUs=[${cpu0}, ${cpu1}, ${cpu2}, ${cpu3}, ${cpu4}, ${cpu5}, ${cpu6}, ${cpu7}, ${cpu8}, ${cpu9}, ${cpu10}, ${cpu11}]'], - ['XORG_CLOSE', 'OS: X display closed', '${display}'], - ['XORG_DISPLAY', 'OS: X display', 'Screen id ${screen id} (${width}x${height}x${depth}) with compositor ${compositor}'], - ['XORG_SESSION_OPENED', 'OS: X display opened', '${display name}'], - ['XORG_WINDOW_CREATE', 'OS: X window created', '${width}x${height}x${depth}, id=${window id} (parent=${parent window id})'], - ['XORG_WINDOW_RESIZE', 'OS: X window resized', 'id=${window id} to ${width}x${height}'], - ] - - def __createkey__(self, category, vals): - # Try to find a key - for key in self.keys: - if key[0] == category: - m = re.search(key[2], vals[key[1]]) - if m is not None and len(m.groups()) > 0: - return m.groups()[0] - else: - return vals[key[1]] - - # We failed, use a number instead - return "{0}".format(len(self.values[category])) - - def __patternresolve__(self, pattern, fields): - out = pattern - for key in fields: - if key == "extensions": - value = ' '.join(str(e) for e in fields[key]) - else: - value = fields[key] - out = out.replace("${" + key + "}", value) - out = re.sub('\$\{[^}]*\}', '', out) - return out - - def __humanoutput__(self, category, fields): - # look for a human entry for those fields - for human_line in self.human_v1: - if human_line[0] == category: - key = self.__patternresolve__(human_line[1], fields) - values = self.__patternresolve__(human_line[2], fields) - if key in self.values: - index=1 - while "{}#{}".format(key, index) in self.values: - index = index + 1 - key = "{}#{}".format(key, index) - self.values[key] = values - return True - return False - - def __init__(self, report_path, human=False): - try: - f = open(report_path) - except Exception as e: - print("Cannot open the file {0}: {1}".format(report_path, str(e))) - return - - # Create the report - self.version = -1 - self.complete = False - self.values = dict() - head_re = re.compile('^-- Env dump start \(version (\d+)\) --$') - for line in f: - fields = line.rstrip('\n').split(',') - - # Parse the header and footer - if len(fields) == 1: - head_m = head_re.match(fields[0]) - if head_m is not None: - self.version = int(head_m.groups()[0]) - elif fields[0] == '-- Env dump end --': - self.complete = True - - # Look for the right line in the csv layout - for layout_line in self.csv_layout_v1: - if layout_line[0] == fields[0]: - # Copy each entry - vals = dict() - for f in range(1, len(layout_line)): - if len(fields) > f: - if layout_line[f] == 'extensions': - vals[layout_line[f]] = set(fields[f].strip().split(' ')) - else: - vals[layout_line[f]] = fields[f] - - # create the entry - cat = layout_line[0] - if human: - self.__humanoutput__(cat, vals) - else: - if cat not in self.values: - self.values[cat] = vals - else: - if type(self.values[cat]) is dict: - orig = self.values[cat] - self.values[cat] = collections.OrderedDict() - entry_key = self.__createkey__(cat, orig) - self.values[cat][entry_key] = orig - entry_key = self.__createkey__(cat, vals) - self.values[cat][entry_key] = vals - - def __to_set__(self, head, key, ignore_list): - if type(head) is str: - return set([(key, head)]) - - out = set() - for entry in head: - if len(key) > 0: - entrykey = key + "." + entry - else: - entrykey = entry - - ignore = False - for ignoreentry in ignore_list: - if ignoreentry.search(entrykey) is not None: - ignore = True - if ignore == True: - continue - - if type(head) is not set: - out.update(self.__to_set__(head[entry], entrykey, ignore_list)) - else: - out.update(set([(entrykey, True)])) - return out - - def to_set(self, ignore_list=[]): - ignore_list_re = [] - # pre-compile the ignore_list - for ignoreentry in ignore_list: - ignore_list_re.append(re.compile(ignoreentry)) - - return self.__to_set__(self.values, "", ignore_list_re) diff --git a/utils/env_dump/fd.c b/utils/env_dump/fd.c deleted file mode 100644 index 9fa6501..0000000 --- a/utils/env_dump/fd.c +++ /dev/null @@ -1,205 +0,0 @@ -/* Copyright (c) 2015, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define _GNU_SOURCE - -#include "env_dump.h" - -#include <sys/types.h> -#include <pthread.h> -#include <unistd.h> -#include <stdarg.h> -#include <stdlib.h> -#include <dlfcn.h> -#include <link.h> - -/* Have a small DB of booleans that will store if we already accounted the - * fd (1) or not yet (0). This DB can hold up to 2048, which is twice the usual - * limit found on Linux. - */ -static pthread_mutex_t fd_mp = PTHREAD_MUTEX_INITIALIZER; -static unsigned long fds[64] = { 0 }; - -/* get the possibility to call hooks when closing an fd */ -static struct fd_close_cb_t { - fd_callback cb; - int fd; - void *user; -} *fd_close_cb; -static size_t fd_close_cb_len; - -static inline int -bit_read(int bit) -{ - int val; - - /* If we go out of the expected range, just give up and say it has been - * reported already! - */ - if (unlikely(bit > sizeof(fds) * 8)) - return 1; - - val = (fds[bit >> 5] >> (bit & 0x1f)) & 1; - - return val; -} - -static inline void -bit_write(int bit, int value) -{ - int idxh, idxl; - - if (unlikely(bit > sizeof(fds) * 8)) - return; - - idxh = bit >> 5; - idxl = bit & 0x1f; - fds[idxh] = (fds[idxh] & ~(1 << idxl)) | (value << idxl); -} - -static ssize_t -get_path_from_fd(int fd, char *buf, size_t bufsiz) -{ - /* longest fd path is /proc/4194303/fd/1024 --> 21 chars */ - char proc_path[22]; - sprintf(proc_path, "/proc/%u/fd/%u", getpid(), fd); - - return readlink(proc_path, buf, bufsiz); -} - -int -ioctl(int fd, unsigned long int request, ...) -{ - int (*orig_ioctl)(int, unsigned long int, ...); - void *arg; - va_list ap; - - va_start(ap, request); - arg = va_arg(ap, void *); - - /* If it is the first time we see an ioctl on this fd */ - pthread_mutex_lock(&fd_mp); - - orig_ioctl = _env_dump_resolve_symbol_by_id(SYMB_IOCTL); - - if (!bit_read(fd)) { - char path[101]; - size_t len = get_path_from_fd(fd, path, sizeof(path)); - path[len] = '\0'; - if (path[0] == '/') - fprintf(env_file, "IOCTL,%s\n", path); - bit_write(fd, 1); - - pthread_mutex_unlock(&fd_mp); - - _env_dump_drm_dump_info(path, fd); - } else - pthread_mutex_unlock(&fd_mp); - - return orig_ioctl(fd, request, arg); -} - -void -_env_dump_close_callback(int fd, fd_callback cb, void *user) -{ - int idx = -1, i; - - pthread_mutex_lock(&fd_mp); - for (i = 0; i < fd_close_cb_len; i++) { - /* re-use a slot if available */ - if (fd_close_cb[i].cb == NULL) - idx = i; - } - - if (idx < 0) { - fd_close_cb = realloc(fd_close_cb, sizeof(struct fd_close_cb_t) * (fd_close_cb_len + 1)); - /* XXX: just crash if we do not have enough RAM ... */ - idx = fd_close_cb_len; - fd_close_cb_len++; - } - - fd_close_cb[idx].fd = fd; - fd_close_cb[idx].cb = cb; - fd_close_cb[idx].user = user; - - pthread_mutex_unlock(&fd_mp); -} - -static void -call_fd_close_callbacks(int fd) -{ - int i; - - pthread_mutex_lock(&fd_mp); - - /* call the callbacks */ - for (i = 0; i < fd_close_cb_len; i++) { - /* re-use a slot if available */ - if (fd < 0 || fd_close_cb[i].fd == fd) { - fd_callback cb = fd_close_cb[i].cb; - int cb_fd = fd_close_cb[i].fd; - void *cb_user = fd_close_cb[i].user; - fd_close_cb[i].fd = -1; - fd_close_cb[i].cb = NULL; - fd_close_cb[i].user = NULL; - pthread_mutex_unlock(&fd_mp); - cb(cb_fd, cb_user); - pthread_mutex_lock(&fd_mp); - } - } - - pthread_mutex_unlock(&fd_mp); -} - -int -close(int fd) -{ - int (*orig_close)(int); - - orig_close = _env_dump_resolve_symbol_by_name("close"); - - /* call the callbacks */ - call_fd_close_callbacks(fd); - - pthread_mutex_lock(&fd_mp); - bit_write(fd, 0); - pthread_mutex_unlock(&fd_mp); - - return orig_close(fd); -} - -void -_env_dump_fd_init() -{ - -} - -void -_env_dump_fd_fini() -{ - /* call the callbacks */ - call_fd_close_callbacks(-1); -} diff --git a/utils/env_dump/gl.c b/utils/env_dump/gl.c deleted file mode 100644 index b4872f5..0000000 --- a/utils/env_dump/gl.c +++ /dev/null @@ -1,302 +0,0 @@ -/* Copyright (c) 2015, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define _GNU_SOURCE - -#include "env_dump.h" - -#include <sys/time.h> -#include <pthread.h> -#include <EGL/egl.h> -#include <stdlib.h> -#include <GL/glx.h> -#include <stdlib.h> -#include <string.h> -#include <link.h> - -static uint64_t print_period_ms = -1; - -static uint64_t -get_time_us() -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec * 1e6 + tv.tv_usec; -} - -static float -fps_clamp(uint64_t frametime_us) -{ - if (frametime_us > 0) - return 1.0e6 / ((float)frametime_us); - else - return 0.0; -} - -void -swap_buffer_stopwatch() -{ - static uint64_t first_frame, last_update, last_print; - static uint64_t min = -1, max, count; - uint64_t cur_time = get_time_us(); - - if (first_frame == 0) - first_frame = cur_time; - - if (last_update > 0) { - uint64_t diff = cur_time - last_update; - count++; - if (diff > max) - max = diff; - if (diff < min) - min = diff; - } - - if (last_print == 0) - last_print = cur_time; - else if (cur_time - last_print > print_period_ms * 1000) { - uint64_t diff = cur_time - last_print; - uint64_t frametime_avg = diff / count; - fprintf(stderr, "FPS,%lu,%.3f,%.3f,%.3f\n", cur_time - first_frame, - fps_clamp(frametime_avg), fps_clamp(max), - fps_clamp(min)); - - /* reset the state */ - last_print = cur_time; - count = 0; - min = -1; - max = 0; - } - - last_update = cur_time; -} - -void -glXSwapBuffers(Display *dpy, GLXDrawable drawable) -{ - void (*orig_glXSwapBuffers)(Display *, GLXDrawable); - - orig_glXSwapBuffers = _env_dump_resolve_symbol_by_id(SYMB_GLXSWAPBUFFERS); - - if (print_period_ms != -1) - swap_buffer_stopwatch(); - - orig_glXSwapBuffers(dpy, drawable); -} - -__GLXextFuncPtr glXGetProcAddressARB(const GLubyte *procName) -{ - __GLXextFuncPtr (*orig_glXGetProcAddressARB)(const GLubyte *); - void *external, *internal; - - orig_glXGetProcAddressARB = _env_dump_resolve_symbol_by_name("glXGetProcAddressARB"); - - /* First look up the right symbol */ - external = orig_glXGetProcAddressARB(procName); - if (!external) - return external; - - /* check if we have an internal version of it! */ - internal = _env_dump_resolve_local_symbol_by_name((const char*)procName); - if (!internal) - return external; - - /* add the right symbol to the list of known symbols */ - _env_dump_replace_symbol((const char*)procName, external); - - /* return the internal address */ - return internal; -} - -EGLBoolean -eglSwapBuffers(EGLDisplay display, EGLSurface surface) -{ - EGLBoolean (*orig_eglSwapBuffers)(EGLDisplay, EGLSurface); - - orig_eglSwapBuffers = _env_dump_resolve_symbol_by_id(SYMB_EGLSWAPBUFFERS); - - if (print_period_ms != -1) - swap_buffer_stopwatch(); - - return orig_eglSwapBuffers(display, surface); -} - -static void -dump_gl_info() -{ - void (*orig_glGetIntegerv)(GLenum, GLint *); - const GLubyte* (*orig_glGetString)(GLenum); - const GLubyte* (*orig_glGetStringi)(GLenum, GLuint); - GLint num_extension = 0, major, minor, i; - - /* get the pointers to the functions we will use */ - orig_glGetIntegerv = _env_dump_resolve_symbol_by_name("glGetIntegerv"); - orig_glGetString = _env_dump_resolve_symbol_by_name("glGetString"); - orig_glGetStringi = _env_dump_resolve_symbol_by_name("glGetStringi"); - - /* exit early if the context is invalid */ - if (orig_glGetString(GL_VENDOR) == NULL) - return; - - /* give informations about the context */ - orig_glGetIntegerv(GL_NUM_EXTENSIONS, &num_extension); - orig_glGetIntegerv(GL_MAJOR_VERSION, &major); - orig_glGetIntegerv(GL_MINOR_VERSION, &minor); - - fprintf(env_file, "GL_NEWCONTEXTUSED,%s,%s,%i.%i,%s,%s,%i,", - orig_glGetString(GL_VENDOR), orig_glGetString(GL_RENDERER), - major, minor, orig_glGetString(GL_VERSION), - orig_glGetString(GL_SHADING_LANGUAGE_VERSION), num_extension); - - if (major > 3 || (major == 3 && minor >= 1)) { - for (i = 0; i < num_extension && orig_glGetStringi; i++) - fprintf(env_file, "%s ", orig_glGetStringi(GL_EXTENSIONS, i)); - fprintf(env_file, "\n"); - } else - fprintf(env_file, "%s\n", glGetString(GL_EXTENSIONS)); -} - -Bool -glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx) -{ - static pthread_mutex_t dumped_contexts_mp = PTHREAD_MUTEX_INITIALIZER; - static size_t dumped_glxcontexts_count = 0; - static GLXContext *dumped_glxcontexts; - - Bool (*orig_glXMakeCurrent)(Display *, GLXDrawable, GLXContext); - const char *(*orig_glXGetClientString)(Display *, int); - Bool ret = False; - int entry_count, i; - - pthread_mutex_lock(&dumped_contexts_mp); - - orig_glXMakeCurrent = _env_dump_resolve_symbol_by_id(SYMB_GLXMAKECURRENT); - orig_glXGetClientString = _env_dump_resolve_symbol_by_name("glXGetClientString"); - - ret = orig_glXMakeCurrent(dpy, drawable, ctx); - if (ret == False) - goto done; - - /* check if the context is in the list */ - for(i = 0; i < dumped_glxcontexts_count; i++) { - if (dumped_glxcontexts[i] == ctx) - goto done; - } - - /* we did not find it, add it to the list before dumping all the - * informations. Allocate 10 contexts at a time to avoid copying every - * time. - */ - entry_count = (((dumped_glxcontexts_count + 1) / 10) + 1) * 10; - dumped_glxcontexts = realloc(dumped_glxcontexts, - entry_count * sizeof(GLXContext)); - dumped_glxcontexts[dumped_glxcontexts_count] = ctx; - dumped_glxcontexts_count++; - - /* dump the egl-related informations */ - if (orig_glXGetClientString) { - fprintf(env_file, "GLX_NEWCONTEXTUSED,%s,%s,%s\n", - orig_glXGetClientString(dpy, GLX_VENDOR), - orig_glXGetClientString(dpy, GLX_VERSION), - orig_glXGetClientString(dpy, GLX_EXTENSIONS)); - } - - dump_gl_info(); - -done: - pthread_mutex_unlock(&dumped_contexts_mp); - return ret; -} - -EGLBoolean -eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSurface read, - EGLContext context) -{ - static pthread_mutex_t dumped_contexts_mp = PTHREAD_MUTEX_INITIALIZER; - static size_t dumped_eglcontexts_count = 0; - static EGLContext *dumped_eglcontexts; - EGLBoolean (*orig_eglMakeCurrent)(Display *, EGLSurface, - EGLSurface, EGLContext); - char const *(*orig_eglQueryString)(EGLDisplay, EGLint); - EGLBoolean ret = False; - EGLenum api; - int entry_count, i; - - pthread_mutex_lock(&dumped_contexts_mp); - - orig_eglMakeCurrent = _env_dump_resolve_symbol_by_id(SYMB_EGLMAKECURRENT); - orig_eglQueryString = _env_dump_resolve_symbol_by_name("eglQueryString"); - - ret = orig_eglMakeCurrent(display, draw, read, context); - if (ret == False) - goto done; - - /* check if the context is in the list */ - for(i = 0; i < dumped_eglcontexts_count; i++) { - if (dumped_eglcontexts[i] == context) - goto done; - } - - /* we did not find it, add it to the list before dumping all the - * informations. Allocate 10 contexts at a time to avoid copying every - * time. - */ - entry_count = (((dumped_eglcontexts_count + 1) / 10) + 1) * 10; - dumped_eglcontexts = realloc(dumped_eglcontexts, - entry_count * sizeof(EGLContext)); - dumped_eglcontexts[dumped_eglcontexts_count] = context; - dumped_eglcontexts_count++; - - /* dump the egl-related informations */ - fprintf(env_file, "EGL_NEWCONTEXTUSED,%s,%s,%s,%s\n", - orig_eglQueryString(display, EGL_VENDOR), - orig_eglQueryString(display, EGL_VERSION), - orig_eglQueryString(display, EGL_CLIENT_APIS), - orig_eglQueryString(display, EGL_EXTENSIONS)); - - /* dump the gl-related informations */ - api = eglQueryAPI(); - if (api == EGL_OPENGL_API || api == EGL_OPENGL_ES_API) - dump_gl_info(); - -done: - pthread_mutex_unlock(&dumped_contexts_mp); - return ret; -} - -void -_env_dump_gl_init() -{ - const char *frametime_period = getenv("ENV_DUMP_FPS_PRINT_PERIOD_MS"); - if (frametime_period != NULL) - print_period_ms = strtoll(frametime_period, NULL, 10); -} - -void -_env_dump_gl_fini() -{ - -}
\ No newline at end of file diff --git a/utils/env_dump/libs.c b/utils/env_dump/libs.c deleted file mode 100644 index 92025d7..0000000 --- a/utils/env_dump/libs.c +++ /dev/null @@ -1,451 +0,0 @@ -/* Copyright (c) 2015, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define _GNU_SOURCE - -#include "env_dump.h" - -#include <openssl/sha.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <pthread.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <link.h> - -static pthread_mutex_t found_so_list_mp = PTHREAD_MUTEX_INITIALIZER; -size_t shared_object_count = 0; -struct shared_object { - char *full_path; - /* more here? */ -} *found_so_list = NULL; - -void *handle_libcrypto = NULL; -unsigned char *(*SHA1_local)(const unsigned char *d, size_t n, unsigned char *md); - - -struct fll_data { - const char *name; - size_t len_name; - char *ret; -}; - -static int -find_Linked_library_callback(struct dl_phdr_info *info, size_t size, void *data) -{ - struct fll_data *p = (struct fll_data *) data; - size_t len = strlen(info->dlpi_name); - size_t offset = len - p->len_name; - - if (len < p->len_name) - return 0; - - if (strcmp(info->dlpi_name + offset, p->name) == 0) { - p->ret = strdup(info->dlpi_name); - return 1; - } - - return 0; -} - -static char * -find_Linked_library(const char *name) -{ - struct fll_data data = {name, strlen(name), NULL}; - - dl_iterate_phdr(find_Linked_library_callback, &data); - - return data.ret; -} - -static int -libcrypto_resolve_symbols() -{ - void *(*orig_dlopen)(const char *, int); - - if (handle_libcrypto == NULL) { - orig_dlopen = _env_dump_resolve_symbol_by_name("dlopen"); - - /* Open a local version of the libcrypto */ - handle_libcrypto = orig_dlopen("libcrypto.so", - RTLD_LOCAL | RTLD_LAZY); - if (handle_libcrypto) - SHA1_local = dlsym(handle_libcrypto, "SHA1"); - } - - return !handle_libcrypto && !SHA1_local; -} - -void -_env_dump_compute_and_print_sha1(const char *full_path) -{ - unsigned char hash[SHA_DIGEST_LENGTH]; - unsigned char *data; - off_t size; - int fd, i; - - /* this function can be called before init(), so let's check if the - * libcrypto has been loaded or not yet. - */ - if (libcrypto_resolve_symbols()) { - fprintf(env_file, "ERR_MISSING_LIBCRYPTO"); - } else { - fd = open(full_path, O_RDONLY); - size = lseek(fd, 0, SEEK_END); - data = mmap (0, size, PROT_READ, MAP_PRIVATE, fd, 0); - if (data == MAP_FAILED) { - fprintf(env_file, "UNK"); - return; - } - - SHA1_local(data, size, hash); - - for (i = 0; i < 20; i++) { - fprintf(env_file, "%02x", hash[i]); - } - - munmap(data, size); - close(fd); - } -} - -static int -add_so_to_found_list(const char *full_path, const char *when) -{ - int ret = 0, i; - - pthread_mutex_lock(&found_so_list_mp); - found_so_list = realloc(found_so_list, - sizeof(struct shared_object) * (shared_object_count + 1)); - if (found_so_list) { - /* look for already-existing entries */ - for (i = 0; i < shared_object_count; i++) { - if (strcmp(found_so_list[i].full_path, full_path) == 0) { - ret = -1; - goto done; - } - } - - /* we could not find an already-existing entry, add a new one */ - found_so_list[shared_object_count].full_path = strdup(full_path); - shared_object_count++; - - /* report the finding */ - fprintf(env_file, "%s,%s,", when, full_path); - _env_dump_compute_and_print_sha1(full_path); - fprintf(env_file, "\n"); - } else - fprintf(env_file, "ERROR,add_so_to_found_list,realloc\n"); - -done: - pthread_mutex_unlock(&found_so_list_mp); - return ret; -} - -static int -ldd_callback(struct dl_phdr_info *info, size_t size, void *data) -{ - if (strlen(info->dlpi_name) == 0) - return 0; - - add_so_to_found_list(info->dlpi_name, "BOOTLINK"); - - return 0; -} - -static int -new_deps_callback(struct dl_phdr_info *info, size_t size, void *data) -{ - if (strlen(info->dlpi_name) == 0) - return 0; - - add_so_to_found_list(info->dlpi_name, "DYNLINK"); - - return 0; -} - -static void -_dlopen_check_result(void *handle, const char *filename, int flag) -{ - char *full_path; - struct link_map *lm; - - if (!handle || !filename) - return; - - dlinfo(handle, RTLD_DI_LINKMAP, &lm); - full_path = realpath(lm->l_name, NULL); - - add_so_to_found_list(full_path, "DYNLINK"); - - free(full_path); - - /* check if we pulled-in more deps */ - dl_iterate_phdr(new_deps_callback, NULL); -} - -void * -dlopen(const char *filename, int flags) -{ - void *(*orig_dlopen)(const char *, int); - void *handle = NULL; - - orig_dlopen = _env_dump_resolve_symbol_by_name("dlopen"); - - handle = orig_dlopen(filename, flags); - _dlopen_check_result(handle, filename, flags); - - return handle; -} - -void * -dlmopen(Lmid_t lmid, const char *filename, int flags) -{ - void *(*orig_dlmopen)(Lmid_t, const char *, int); - void *handle; - - orig_dlmopen = _env_dump_resolve_symbol_by_name("dlmopen"); - - handle = orig_dlmopen(lmid, filename, flags); - _dlopen_check_result(handle, filename, flags); - - return handle; -} - -static pthread_mutex_t symbols_mp = PTHREAD_MUTEX_INITIALIZER; -size_t symbols_count = 0; -size_t symbols_len = 0; -struct symbol_t { - const char *name; - void *ptr; -} *symbols; - -const char *symbol_key_str[SYMB_END] = { - "ioctl", - "glXSwapBuffers", - "eglSwapBuffers", - "glXMakeCurrent", - "eglMakeCurrent", -}; - -extern void *_dl_sym(void *, const char *, void *); -void * -_env_dump_resolve_symbol_by_name(const char *symbol) -{ - void *ret = NULL; - int i; - - pthread_mutex_lock(&symbols_mp); - - /* first check in our internal DB */ - for (i = 0; i < symbols_count; i++) { - if (symbols[i].name && strcmp(symbols[i].name, symbol) == 0) { - ret = symbols[i].ptr; - break; - } - } - - pthread_mutex_unlock(&symbols_mp); - - /* Then try to see if there is another version somewhere else */ - if (ret == NULL) - ret = _dl_sym(RTLD_NEXT, symbol, _env_dump_resolve_symbol_by_name); - - return ret; -} - -void * -_env_dump_resolve_symbol_by_id(enum symbol_key_t symbol) -{ - void *ret = NULL; - - pthread_mutex_lock(&symbols_mp); - if (symbol < SYMB_END && symbols_len > symbol && symbols[symbol].name) - ret = symbols[symbol].ptr; - pthread_mutex_unlock(&symbols_mp); - - /* Then try to see if there is another version somewhere else */ - if (ret == NULL) { - ret = _dl_sym(RTLD_NEXT, symbol_key_str[symbol], _env_dump_resolve_symbol_by_name); - _env_dump_replace_symbol(symbol_key_str[symbol], ret); - } - - return ret; -} - -void -_env_dump_replace_symbol(const char *symbol, void *ptr) -{ - int size, offset = -1, i; - - pthread_mutex_lock(&symbols_mp); - - /* first check if the symbol is known */ - for (i = 0; i < SYMB_END; i++) { - if (strcmp(symbol_key_str[i], symbol) == 0) { - offset = i; - goto write_offset; - } - } - - /* check if the symbol is already in the list */ - for (i = SYMB_END; i < symbols_count; i++) { - if (strcmp(symbols[i].name, symbol) == 0) { - offset = i; - goto write_offset; - } - } - - /* we need to add the symbol, compute its offset */ - offset = (symbols_count < SYMB_END) ? SYMB_END : symbols_count; - -write_offset: - /* make sure we have enough space allocated */ - if (offset >= symbols_len) { - void *prev = symbols; - size_t start, len; - int bs = 100; - - if (symbols_len == 0) - size = SYMB_END + bs; - else - size = symbols_len + bs; - - symbols = realloc(symbols, size * sizeof(struct symbol_t)); - symbols_len = size; - - if (!prev) { - start = 0; - len = size; - } else { - start = size - bs; - len = bs; - } - - memset(symbols + start, '\0', len * sizeof(struct symbol_t)); - - } - - /* if we are not merely updating an entry */ - if (!symbols[offset].name) - symbols[offset].name = strdup(symbol); - symbols[offset].ptr = ptr; - - /* increase the symbol count after adding an entry */ - if (offset >= symbols_count) - symbols_count = offset + 1; - - pthread_mutex_unlock(&symbols_mp); -} - -void * -_env_dump_resolve_local_symbol_by_name(const char *symbol) -{ - static void *(*orig_dlsym)(void *, const char *); - static void *handle_env_dump; - - if (orig_dlsym == NULL) - orig_dlsym = _dl_sym(RTLD_NEXT, "dlsym", dlsym); - - if (handle_env_dump == NULL ) { - void *(*orig_dlopen)(const char *, int); - char *fullpath = find_Linked_library("env_dump.so"); - orig_dlopen = _dl_sym(RTLD_NEXT, "dlopen", dlsym); - handle_env_dump = orig_dlopen(fullpath, RTLD_LAZY); - free(fullpath); - } - - return orig_dlsym(handle_env_dump, symbol); -} - -/* check which symbols the program looks up */ -void * -dlsym(void *handle, const char *symbol) -{ - static void *(*orig_dlsym)(void *, const char *); - void *orig_ptr, *ptr; - - if (orig_dlsym == NULL) - orig_dlsym = _dl_sym(RTLD_NEXT, "dlsym", dlsym); - - /* try to resolve the symbol to an internal one first to avoid issues - * with dlerror(). - */ - ptr = _env_dump_resolve_local_symbol_by_name(symbol); - - /* resolve the symbol as expected by the client */ - orig_ptr = orig_dlsym(handle, symbol); - if (!orig_ptr) - return orig_ptr; - - /* add the symbol to our DB */ - _env_dump_replace_symbol(symbol, orig_ptr); - - if (ptr) - return ptr; - else - return orig_ptr; -} - -/*int dlclose(void *handle) -{ - int(*orig_dlclose)(void *); - orig_dlclose = _env_dump_resolve_symbol_by_name("dlclose"); - - return orig_dlclose(handle); -}*/ - -void -_env_dump_libs_init() -{ - /* Show what we are currently linking against */ - dl_iterate_phdr(ldd_callback, NULL); -} - -void -_env_dump_libs_fini() -{ - size_t i; - - /* free the memory we do not need anymore */ - pthread_mutex_lock(&found_so_list_mp); - for (i = 0; i < shared_object_count; i++) - free(found_so_list[i].full_path); - shared_object_count = 0; - free(found_so_list); - pthread_mutex_unlock(&found_so_list_mp); - - /* free the symbols */ - pthread_mutex_lock(&symbols_mp); - symbols_count = 0; - free(symbols); - pthread_mutex_unlock(&symbols_mp); - - if (handle_libcrypto) - dlclose(handle_libcrypto); -} diff --git a/utils/env_dump/linux.c b/utils/env_dump/linux.c deleted file mode 100644 index 224ee01..0000000 --- a/utils/env_dump/linux.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2015, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define _GNU_SOURCE - -#include "env_dump.h" - -#include <sys/utsname.h> - -void -_env_dump_linux_init() -{ - struct utsname buf; - - if (!uname(&buf)) { - fprintf(env_file, "KERNEL,%s,%s,%s,%s,%s,%s\n", buf.sysname, - buf.nodename, buf.release, buf.version, buf.machine, - buf.domainname); - } -} - -void -_env_dump_linux_fini() -{ - -}
\ No newline at end of file diff --git a/utils/env_dump/net.c b/utils/env_dump/net.c deleted file mode 100644 index 0599a05..0000000 --- a/utils/env_dump/net.c +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (c) 2015, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define _GNU_SOURCE - -#include "env_dump.h" - -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/un.h> -#include <errno.h> -#include <link.h> - -int -connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) -{ - int(*orig_connect)(int, const struct sockaddr *, socklen_t); - struct sockaddr_un *addr_unix; - socklen_t len; - int ret; - - orig_connect = _env_dump_resolve_symbol_by_name("connect"); - - ret = orig_connect(sockfd, addr, addrlen); - if (!ret && addr->sa_family == AF_UNIX) { - struct ucred ucred; - const char *filepath = NULL; - - addr_unix = (struct sockaddr_un *)addr; - filepath = addr_unix->sun_path; - if (filepath[0] == '\0') - filepath++; - - len = sizeof(struct ucred); - if(getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) < 0){ - fprintf(env_file, "SOCKET_UNIX_CONNECT,%s,,%s\n", filepath, strerror(errno)); - return ret; - } - - /* display a lot more information about the process! */ - fprintf(env_file, "SOCKET_UNIX_CONNECT,%s,", filepath); - env_var_dump_binary_information(ucred.pid); - fprintf(env_file, "\n"); - } - - return ret; -} - -void _env_dump_net_init() -{ - -} - -void _env_dump_net_fini() -{ - -} diff --git a/utils/env_dump/posix_env.c b/utils/env_dump/posix_env.c deleted file mode 100644 index c2633c8..0000000 --- a/utils/env_dump/posix_env.c +++ /dev/null @@ -1,201 +0,0 @@ -/* Copyright (c) 2015, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define _GNU_SOURCE - -#include "env_dump.h" - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <link.h> - -void -env_var_dump_binary_information(int pid) -{ - size_t buflen = 4096, size; - char *buf = malloc(buflen), *cur; - char proc_path[22]; /* longest fd path is /proc/4194303/cmdline */ - FILE *cmd_file; - - if (!buf) { - fprintf(stderr, "Error, no memory left. Exit!"); - exit(1); - } - - if (pid == 0) - pid = getpid(); - - /* first read the url of the program */ - snprintf(proc_path, sizeof(proc_path), "/proc/%i/exe", pid); - size = readlink(proc_path, buf, buflen); - if (size == -1) { - fprintf(env_file, "ERROR(%s),", strerror(errno)); - } else { - buf[size] = '\0'; - fprintf(env_file, "%s,", buf); - } - - /* then read the arguments */ - snprintf(proc_path, sizeof(proc_path), "/proc/%i/cmdline", pid); - cmd_file = fopen(proc_path, "r"); - if (cmd_file) { - size = fread(buf, 1, buflen, cmd_file); - - /* the fields are separated by \0 characters, replace them by - * spaces and add '' arounds them. The last field has two null - * characters. - */ - cur = buf; - while (*cur && (cur - buf) < size) { - if (cur == buf) - fprintf(env_file, "'"); - else if (*(cur - 1) == '\0') - fprintf(env_file, " '"); - fprintf(env_file, "%c", *cur); - - cur++; - - if (*cur == '\0') { - fprintf(env_file, "'"); - cur++; - } - } - fprintf(env_file, ","); - - } else - fprintf(env_file, "ERROR,"); - - snprintf(proc_path, sizeof(proc_path), "/proc/%i/exe", pid); - _env_dump_compute_and_print_sha1(proc_path); - - free(buf); -} - -static void -dump_env_var(const char *header, const char *string) -{ - char *key, *val, *pos = strstr(string, "="); - if (pos) { - key = strndup(string, pos - string); - val = strdup(pos + 1); - fprintf(env_file, "%s,%s,%s\n", header, key, val); - free(key); free(val); - } else - fprintf(env_file, "%s,%s,\n", header, string); -} - -static void -dump_env_vars() -{ - char **env = environ; - - while (*env) { - dump_env_var("ENV", *env); - env++; - } -} - -int -putenv(char *string) -{ - int(*orig_putenv)(char *); - int ret; - - orig_putenv = _env_dump_resolve_symbol_by_name("putenv"); - - ret = orig_putenv(string); - if (!ret) - dump_env_var("ENV_SET", string); - - return ret; -} - -int -setenv(const char *name, const char *value, int replace) -{ - int(*orig_setenv)(const char *, const char *, int); - char *orig_value = NULL; - int ret; - - orig_setenv = _env_dump_resolve_symbol_by_name("setenv"); - - if (!replace) - orig_value = getenv(name); - - ret = orig_setenv(name, value, replace); - if (!ret && !(!replace && orig_value)) // do not print the message if nothing changed - fprintf(env_file, "ENV_SET,%s,%s\n", name, value); - - return ret; -} - -int -unsetenv(const char *name) -{ - int(*orig_unsetenv)(const char *); - int ret; - - orig_unsetenv = _env_dump_resolve_symbol_by_name("unsetenv"); - - ret = orig_unsetenv(name); - if (!ret) - fprintf(env_file, "ENV_UNSET,%s\n", name); - - return ret; -} - -int -clearenv(void) -{ - int(*orig_clearenv)(void); - int ret; - - orig_clearenv = _env_dump_resolve_symbol_by_name("clearenv"); - - ret = orig_clearenv(); - if (!ret) - fprintf(env_file, "ENV_CLEAR\n"); - - return ret; -} - -void -_env_dump_posix_env_init() -{ - fprintf(env_file, "EXE,"); - env_var_dump_binary_information(0); - fprintf(env_file, "\n"); - - dump_env_vars(); -} - -void -_env_dump_posix_env_fini() -{ - -} diff --git a/utils/env_dump/scripts/intel-gpu-search-pci-id.sh b/utils/env_dump/scripts/intel-gpu-search-pci-id.sh deleted file mode 100755 index ce67e2f..0000000 --- a/utils/env_dump/scripts/intel-gpu-search-pci-id.sh +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/sh - -# Copyright 2015 Intel Corporation -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of the copyright holders nor the names of their contributors -# may be used to endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -set -eu - -: ${XDG_CACHE_HOME:=$HOME/.cache} - -prog_name=${0##*/} -cache_dir="$XDG_CACHE_HOME/intel-gpu-info" -cached_i965_pci_ids_h="$cache_dir/i965_pci_ids.h" -dri_dev="/sys/class/drm/card0/device/device" - - -print_help () -{ -cat <<EOF -USAGE - $prog_name [-u|--update] [--] [regex] - -DESCRIPTION - Print info about all Intel GPU's whose name or pci_id match the regex. If - no regex is given, then print info on the current machine's Intel GPU. - -OPTIONS - -u, --update - Update the cached copy of i965_pci_ids.h. - -EXAMPLES - Query the local device. - $ $prog_name - - Search for a specific PCI id. - $ $prog_name 0x1616 - - Search for all Broadwell GPUs. - $ $prog_name broadwell - - Search for all GT3 GPUs. - $ $prog_name gt3 - - Search for an Intel GPU by its marketing name. - $ $prog_name "Iris Pro 6200" -EOF -} - - -parse_args () -{ - arg_regex= - arg_update= - - for argnum in $(seq $#); do - case "$1" in - --) - shift - break - ;; - -h|--help) - print_help - exit 0 - ;; - -u|--update) - arg_update=1 - shift - ;; - -*) - usage_error "unknown option $1" - ;; - *) - break - ;; - esac - done - - if [ $# -gt 0 ]; then - arg_regex="$1" - shift - fi - - if [ $# -gt 0 ]; then - usage_error "trailing args: $@" - fi -} - -usage_error () -{ - echo >&2 "$prog_name: usage error: $@" - exit 2 -} - -die () -{ - echo >&2 "$prog_name: error: $@" - exit 2 -} - -update_cache () -{ - local src - local dst - mkdir -p "$cache_dir" - - if [ -r "$cached_i965_pci_ids_h" ] && [ -z "$arg_update" ]; then - return - fi - - src="http://cgit.freedesktop.org/mesa/mesa/tree/include/pci_ids/i965_pci_ids.h" - dst="$cached_i965_pci_ids_h" - - if [ -z "$(which curl)" ]; then - if [ -z "$(which wget)" ]; then - die "please install either 'curl' or 'wget' to fetch/update the PCI ID information" - fi - wget -O - "$src" > "${dst}.bak" - else - curl -s "$src" > "${dst}.bak" - fi - sed -n 's/.*CHIPSET(\(.*\))$/\1/p' < "${dst}.bak" > "$dst" - rm "${dst}.bak" -} - -main () -{ - local regex - - parse_args "$@" - - if [ "$arg_regex" ]; then - regex="$arg_regex" - elif ! regex="$(cat $dri_dev)"; then - die "failed to read $dri_dev" - fi - - update_cache - - grep -i -E "$regex" "$cached_i965_pci_ids_h" - if [ $? -ne 0 ]; then - die "failed to find '$regex' in i965_pci_ids.h" - fi -} - -main "$@" diff --git a/utils/env_dump/xorg.c b/utils/env_dump/xorg.c deleted file mode 100644 index 89aad5d..0000000 --- a/utils/env_dump/xorg.c +++ /dev/null @@ -1,205 +0,0 @@ -/* Copyright (c) 2015, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define _GNU_SOURCE - -#include "env_dump.h" - -#include <X11/Xlib.h> -#include <X11/Xatom.h> -#include <X11/extensions/Xrandr.h> -#include <stdlib.h> -#include <string.h> -#include <link.h> - -/* XLib functions, should only be called if the libxcb or libX11 is loaded */ -static char * -_env_dump_xlib_compositor(Display *dpy, int screen) -{ - Atom wmCheckAtom, wmName,stringType, typeRet; - unsigned long nitems, after; - unsigned char *name = 0; - Window root, *wm_window; - char *result = NULL; - int format; - - /* Retrieve the pointers to x-related functions */ - Atom (*orig_xinternatom)(Display *, char *, Bool); - int (*orig_xgetwindowproperty)(Display *, Window, Atom, long, long, Bool, - Atom, Atom *, int *, unsigned long *, - unsigned long *, unsigned char **); - int (*orig_xfree)(void *); - orig_xinternatom = _env_dump_resolve_symbol_by_name("XInternAtom"); - orig_xgetwindowproperty = _env_dump_resolve_symbol_by_name("XGetWindowProperty"); - orig_xfree = _env_dump_resolve_symbol_by_name("XFree"); - - wmCheckAtom = orig_xinternatom(dpy, "_NET_SUPPORTING_WM_CHECK", True); - wmName = orig_xinternatom(dpy, "_NET_WM_NAME", True); - stringType = orig_xinternatom(dpy, "UTF8_STRING", True); - - if (wmCheckAtom == None || wmName == None || stringType == None) - return strdup("UNKOWN"); - - root = RootWindow(dpy, screen); - if (!(orig_xgetwindowproperty(dpy, root, wmCheckAtom, 0, 1024, False, - XA_WINDOW, &typeRet, &format, &nitems, &after, - (unsigned char **) &wm_window))) - { - if (wm_window && !(orig_xgetwindowproperty(dpy, *wm_window, - wmName, 0, 1024, False, stringType, &typeRet, &format, - &nitems, &after, (unsigned char **) &name))) - { - result = strdup((char *)name); - orig_xfree(name); - } - } - - return result; -} - -Display * -XOpenDisplay(const char *display_name) -{ - Display *(*orig_xopendisplay)(const char *); - Display *dpy; - int i; - - orig_xopendisplay = _env_dump_resolve_symbol_by_name("XOpenDisplay"); - dpy = orig_xopendisplay(display_name); - if (dpy) { - fprintf(env_file, "XORG_SESSION_OPENED,%s\n", display_name); - for (i = 0; i < ScreenCount(dpy); i++) { - char *wm = _env_dump_xlib_compositor(dpy, i); - - fprintf(env_file, "XORG_DISPLAY,%i,%s,%i,%i,%i\n", i, - wm, DisplayWidth(dpy, i), DisplayHeight(dpy, i), - DefaultDepth(dpy, i)); - - free(wm); - } - } - - return dpy; -} - -int -XCloseDisplay(Display *display) -{ - int (*orig_xclosedisplay)(Display *); - int ret; - - orig_xclosedisplay = _env_dump_resolve_symbol_by_name("XCloseDisplay"); - - fprintf(env_file, "XORG_CLOSE,%s\n", DisplayString(display)); - ret = orig_xclosedisplay(display); - - return ret; -} - -Window -XCreateSimpleWindow(Display* display, Window parent, int x, int y, - unsigned int width, unsigned int height, - unsigned int border_width, unsigned long border, - unsigned long background) -{ - int (*orig_xcreatesimplewindow)(Display *, Window, int, int, - unsigned int, unsigned int, - unsigned int, unsigned long, - unsigned long); - Window ret; - - orig_xcreatesimplewindow = _env_dump_resolve_symbol_by_name("XCreateSimpleWindow"); - - ret = orig_xcreatesimplewindow(display, parent, x, y, width, height, - border_width, border, background); - fprintf(env_file, "XORG_WINDOW_CREATE,%lu,%lu,%i,%i,-1\n", parent, ret, - width, height); - - return ret; -} - -Window -XCreateWindow(Display* display, Window parent, int x, int y, - unsigned int width, unsigned int height, - unsigned int border_width, int depth, unsigned int class, - Visual* visual, unsigned long valuemask, - XSetWindowAttributes *attributes) -{ - int (*orig_xcreatewindow)(Display *, Window, int, int, - unsigned int, unsigned int, - unsigned int, int, unsigned int, - Visual *, unsigned long, - XSetWindowAttributes *); - Window ret; - - orig_xcreatewindow = _env_dump_resolve_symbol_by_name("XCreateWindow"); - - ret = orig_xcreatewindow(display, parent, x, y, width, height, - border_width, depth, class, visual, - valuemask, attributes); - fprintf(env_file, "XORG_WINDOW_CREATE,%lu,%lu,%i,%i,%i\n", parent, ret, - width, height, depth); - - return ret; -} - -int -XMoveResizeWindow(Display *display, Window w, int x, int y, unsigned int width, - unsigned int height) -{ - int (*orig_xmoveresizewindow)(Display *, Window, int, int, - unsigned int, unsigned int); - int ret; - - orig_xmoveresizewindow = _env_dump_resolve_symbol_by_name("XMoveResizeWindow"); - - ret = orig_xmoveresizewindow(display, w, x, y, width, height); - fprintf(env_file, "XORG_WINDOW_RESIZE,%lu,%i,%i\n", w, width, height); - - return ret; -} - -int -XResizeWindow(Display *display, Window w, unsigned int width, unsigned int height) -{ - int (*orig_xresizewindow)(Display *, Window, unsigned int, - unsigned int); - int ret; - - orig_xresizewindow = _env_dump_resolve_symbol_by_name("XResizeWindow"); - - ret = orig_xresizewindow(display, w, width, height); - fprintf(env_file, "XORG_WINDOW_RESIZE,%lu,%i,%i\n", w, width, height); - - return ret; -} - - -/* libxcb */ - -/* WARNING: No need to hook the connect close and createwindow functions because - * the libxcb calls the original xlib functions which are already hook! - */ diff --git a/utils/ezbench.py b/utils/ezbench.py deleted file mode 100644 index bd5d6ac..0000000 --- a/utils/ezbench.py +++ /dev/null @@ -1,1411 +0,0 @@ -""" -Copyright (c) 2015, Intel Corporation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -""" - -from email.utils import parsedate_tz, mktime_tz -from collections import namedtuple -from datetime import datetime -from dateutil import relativedelta -from array import array -from scipy import stats -from enum import Enum -from numpy import * -import subprocess -import atexit -import pprint -import fcntl -import time -import json -import glob -import copy -import csv -import sys -import os -import re - -# Ezbench runs -class EzbenchExitCode(Enum): - UNKNOWN = -1 - NO_ERROR = 0 - ARG_PROFILE_NAME_MISSING = 11 - ARG_PROFILE_INVALID = 12 - ARG_OPTARG_MISSING = 13 - ARG_GIT_REPO_MISSING = 14 - OS_SHELL_GLOBSTAT_MISSING = 30 - OS_LOG_FOLDER_CREATE_FAILED = 31 - OS_CD_GIT_REPO = 32 - GIT_STASH_FAILED = 50 - GIT_INVALID_COMMIT_ID = 50 - COMP_DEP_UNK_ERROR = 70 - COMPILATION_FAILED = 71 - DEPLOYMENT_FAILED = 72 - DEPLOYMENT_ERROR = 73 - REBOOT_NEEDED = 74 - TEST_INVALID_NAME = 100 - UNK_ERROR = 255 - -class EzbenchRun: - def __init__(self, commits, benchmarks, predicted_execution_time, repo_dir, repo_head, deployed_commit, exit_code): - self.commits = commits - self.benchmarks = benchmarks - self.predicted_execution_time = predicted_execution_time - self.repo_dir = repo_dir - self.repo_head = repo_head - self.deployed_commit = deployed_commit - self.exit_code = EzbenchExitCode(exit_code) - - def success(self): - return self.exit_code == EzbenchExitCode.NO_ERROR - -class Ezbench: - def __init__(self, ezbench_path, profile = None, repo_path = None, - make_command = None, report_name = None, tests_folder = None, - run_config_script = None): - self.ezbench_path = ezbench_path - self.profile = profile - self.repo_path = repo_path - self.make_command = make_command - self.report_name = report_name - self.tests_folder = tests_folder - self.run_config_script = run_config_script - - def __ezbench_cmd_base(self, benchmarks, benchmark_excludes = [], rounds = None, dry_run = False): - ezbench_cmd = [] - ezbench_cmd.append(self.ezbench_path) - - if self.profile is not None: - ezbench_cmd.append("-P"); ezbench_cmd.append(self.profile) - - if self.repo_path is not None: - ezbench_cmd.append("-p"); ezbench_cmd.append(self.repo_path) - - for benchmark in benchmarks: - ezbench_cmd.append("-b"); ezbench_cmd.append(benchmark) - - for benchmark_excl in benchmark_excludes: - ezbench_cmd.append("-B"); ezbench_cmd.append(benchmark_excl) - - if rounds is not None: - ezbench_cmd.append("-r"); ezbench_cmd.append(str(int(rounds))) - - if self.make_command is not None: - ezbench_cmd.append("-m"); ezbench_cmd.append(self.make_command) - if self.report_name is not None: - ezbench_cmd.append("-N"); ezbench_cmd.append(self.report_name) - if self.tests_folder is not None: - ezbench_cmd.append("-T"); ezbench_cmd.append(self.tests_folder) - if self.run_config_script is not None: - ezbench_cmd.append("-c"); ezbench_cmd.append(self.run_config_script) - - if dry_run: - ezbench_cmd.append("-k") - - return ezbench_cmd - - def __run_ezbench(self, cmd, dry_run = False, verbose = False): - exit_code = None - - if verbose: - print(cmd) - - try: - output = subprocess.check_output(cmd, stderr=subprocess.STDOUT).decode() - exit_code = EzbenchExitCode.NO_ERROR - except subprocess.CalledProcessError as e: - exit_code = EzbenchExitCode(e.returncode) - output = e.output.decode() - pass - - # we need to parse the output - commits= [] - benchmarks = [] - pred_exec_time = 0 - deployed_commit = "" - repo_dir = "" - head_commit = "" - re_commit_list = re.compile('^Testing \d+ commits: ') - re_repo = re.compile('^Repo = (.*), HEAD = (.*), deployed version = (.*)$') - for line in output.split("\n"): - m_commit_list = re_commit_list.match(line) - m_repo = re_repo.match(line) - if line.startswith("Tests that will be run:"): - benchmarks = line[24:].split(" ") - if benchmarks[-1] == '': - benchmarks.pop(-1) - elif line.find("estimated finish date:") >= 0: - pred_exec_time = "" - elif m_repo is not None: - repo_dir, head_commit, deployed_commit = m_repo.groups() - elif m_commit_list is not None: - commits = line[m_commit_list.end():].split(" ") - while '' in commits: - commits.remove('') - elif exit_code == EzbenchExitCode.TEST_INVALID_NAME and line.endswith("do not exist"): - print(line) - - if exit_code != EzbenchExitCode.NO_ERROR: - print("\n\nERROR: The following command '{}' failed with the error code {}. Here is its output:\n\n'{}'".format(" ".join(cmd), exit_code, output)) - - return EzbenchRun(commits, benchmarks, pred_exec_time, repo_dir, head_commit, deployed_commit, exit_code) - - def run_commits(self, commits, benchmarks, benchmark_excludes = [], - rounds = None, dry_run = False, verbose = False): - ezbench_cmd = self.__ezbench_cmd_base(benchmarks, benchmark_excludes, rounds, dry_run) - - for commit in commits: - ezbench_cmd.append(commit) - - return self.__run_ezbench(ezbench_cmd, dry_run, verbose) - - def run_commit_range(self, head, commit_count, benchmarks, benchmark_excludes = [], - rounds = None, dry_run = False, verbose = False): - ezbench_cmd = self.__ezbench_cmd_base(benchmarks, benchmark_excludes, rounds, dry_run) - - ezbench_cmd.append("-H"); ezbench_cmd.append(head) - ezbench_cmd.append("-n"); ezbench_cmd.append(commit_count) - - return self.__run_ezbench(ezbench_cmd, dry_run, verbose) - -# Smart-ezbench-related classes -class Criticality(Enum): - II = 0 - WW = 1 - EE = 2 - DD = 3 - -class RunningMode(Enum): - INITIAL = 0 - RUN = 1 - PAUSE = 2 - ERROR = 3 - ABORT = 4 - -def list_smart_ezbench_report_names(ezbench_dir, updatedSince = 0): - log_dir = ezbench_dir + '/logs' - state_files = glob.glob("{log_dir}/*/smartezbench.state".format(log_dir=log_dir)); - - reports = [] - for state_file in state_files: - if updatedSince > 0 and os.path.getmtime(state_file) < updatedSince: - continue - - start = len(log_dir) + 1 - stop = len(state_file) - 19 - reports.append(state_file[start:stop]) - - return reports - -class TaskEntry: - def __init__(self, commit, benchmark, rounds): - self.commit = commit - self.benchmark = benchmark - self.rounds = rounds - -class SmartEzbench: - def __init__(self, ezbench_dir, report_name, readonly = False): - self.readonly = readonly - self.ezbench_dir = ezbench_dir - self.log_folder = ezbench_dir + '/logs/' + report_name - self.smart_ezbench_state = self.log_folder + "/smartezbench.state" - self.smart_ezbench_lock = self.log_folder + "/smartezbench.lock" - self.smart_ezbench_log = self.log_folder + "/smartezbench.log" - - self.state = dict() - self.state['report_name'] = report_name - self.state['commits'] = dict() - self.state['mode'] = RunningMode.INITIAL.value - - # Create the log directory - first_run = False - if not readonly and not os.path.exists(self.log_folder): - os.makedirs(self.log_folder) - first_run = True - - # Open the log file as append - self.log_file = open(self.smart_ezbench_log, "a") - - # Add the welcome message - if first_run or not self.__reload_state(): - if readonly: - raise RuntimeError("The report {} does not exist".format(report_name)) - self.__save_state() - self.__log(Criticality.II, - "Created report '{report_name}' in {log_folder}".format(report_name=report_name, - log_folder=self.log_folder)) - - def __log(self, error, msg): - time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - log_msg = "{time}: ({error}) {msg}\n".format(time=time, error=error.name, msg=msg) - print(log_msg, end="") - if not self.readonly: - self.log_file.write(log_msg) - self.log_file.flush() - - def __grab_lock(self): - if self.readonly: - return - self.lock_fd = open(self.smart_ezbench_lock, 'w') - try: - fcntl.flock(self.lock_fd, fcntl.LOCK_EX) - return True - except IOError as e: - self.__log(Criticality.EE, "Could not lock the report: " + str(e)) - return False - - def __release_lock(self): - if self.readonly: - return - - try: - fcntl.flock(self.lock_fd, fcntl.LOCK_UN) - self.lock_fd.close() - except Exception as e: - self.__log(Criticality.EE, "Cannot release the lock: " + str(e)) - pass - - def __reload_state_unlocked(self): - # check if a report already exists - try: - with open(self.smart_ezbench_state, 'rt') as f: - self.state_read_time = time.time() - try: - self.state = json.loads(f.read()) - except Exception as e: - self.__log(Criticality.EE, "Exception while reading the state: " + str(e)) - pass - return True - except IOError as e: - self.__log(Criticality.WW, "Cannot open the state file: " + str(e)) - pass - return False - - def __reload_state(self, keep_lock = False): - self.__grab_lock() - ret = self.__reload_state_unlocked() - if not keep_lock: - self.__release_lock() - return ret - - def __save_state(self): - if self.readonly: - return - - try: - state_tmp = str(self.smart_ezbench_state) + ".tmp" - with open(state_tmp, 'wt') as f: - f.write(json.dumps(self.state, sort_keys=True, indent=4, separators=(',', ': '))) - f.close() - os.rename(state_tmp, self.smart_ezbench_state) - return True - except IOError: - self.__log(Criticality.EE, "Could not dump the current state to a file!") - return False - - def __create_ezbench(self, ezbench_path = None, profile = None, report_name = None): - if ezbench_path is None: - ezbench_path = self.ezbench_dir + "/core.sh" - if profile is None: - profile = self.profile() - if report_name is None: - report_name=self.state['report_name'] - - return Ezbench(ezbench_path = ezbench_path, profile = profile, - report_name = report_name) - - def running_mode(self): - self.__reload_state(keep_lock=False) - if 'mode' not in self.state: - return RunningMode.INITIAL - else: - return RunningMode(self.state['mode']) - - def set_running_mode(self, mode): - self.__reload_state(keep_lock=True) - if 'mode' not in self.state or self.state['mode'] != mode.value: - self.state['mode'] = mode.value - self.__log(Criticality.II, "Ezbench running mode set to '{mode}'".format(mode=mode.name)) - self.__save_state() - self.__release_lock() - - def profile(self): - self.__reload_state(keep_lock=False) - if "profile" in self.state: - return self.state['profile'] - else: - return None - - def set_profile(self, profile): - self.__reload_state(keep_lock=True) - if 'beenRunBefore' not in self.state or self.state['beenRunBefore'] == False: - # Check that the profile exists! - ezbench = self.__create_ezbench(profile = profile) - run_info = ezbench.run_commits(["HEAD"], [], [], dry_run=True) - if not run_info.success(): - if run_info.exit_code == EzbenchExitCode.ARG_PROFILE_INVALID: - self.__log(Criticality.EE, - "Invalid profile name '{profile}'.".format(profile=profile)) - else: - self.__log(Criticality.EE, - "The following error arose '{error}'.".format(error=run_info.exit_code.name)) - self.__release_lock() - return - - self.state['profile'] = profile - self.__log(Criticality.II, "Ezbench profile set to '{profile}'".format(profile=profile)) - self.__save_state() - else: - self.__log(Criticality.EE, "You cannot change the profile of a report that already has results. Start a new one.") - self.__release_lock() - - def conf_script(self): - self.__reload_state(keep_lock=True) - if "conf_script" in self.state: - conf_script = self.state['conf_script'] - self.__release_lock() - return conf_script - else: - self.__release_lock() - return None - - def set_conf_script(self, conf_script): - self.__reload_state(keep_lock=True) - if 'beenRunBefore' not in self.state or self.state['beenRunBefore'] == False: - self.state['conf_script'] = conf_script - self.__log(Criticality.II, "Ezbench profile configuration script set to '{0}'".format(conf_script)) - self.__save_state() - else: - self.__log(Criticality.EE, "You cannot change the configuration script of a report that already has results. Start a new one.") - self.__release_lock() - - def add_benchmark(self, commit, benchmark, rounds = None): - self.__reload_state(keep_lock=True) - if commit not in self.state['commits']: - self.state['commits'][commit] = dict() - self.state['commits'][commit]["benchmarks"] = dict() - - if rounds is None: - rounds = 3 - - if benchmark not in self.state['commits'][commit]['benchmarks']: - self.state['commits'][commit]['benchmarks'][benchmark] = dict() - self.state['commits'][commit]['benchmarks'][benchmark]['rounds'] = rounds - else: - self.state['commits'][commit]['benchmarks'][benchmark]['rounds'] += rounds - - # if the number of rounds is equal to 0 for a benchmark, delete it - if self.state['commits'][commit]['benchmarks'][benchmark]['rounds'] <= 0: - del self.state['commits'][commit]['benchmarks'][benchmark] - - # Delete a commit that has no benchmark - if len(self.state['commits'][commit]['benchmarks']) == 0: - del self.state['commits'][commit] - - self.__save_state() - self.__release_lock() - - def force_benchmark_rounds(self, commit, benchmark, at_least): - if at_least < 1: - return 0 - - self.__reload_state(keep_lock=True) - if commit not in self.state['commits']: - self.state['commits'][commit] = dict() - self.state['commits'][commit]["benchmarks"] = dict() - - if benchmark not in self.state['commits'][commit]['benchmarks']: - self.state['commits'][commit]['benchmarks'][benchmark] = dict() - self.state['commits'][commit]['benchmarks'][benchmark]['rounds'] = 0 - - to_add = at_least - self.state['commits'][commit]['benchmarks'][benchmark]['rounds'] - - if to_add > 0: - self.__log(Criticality.WW, - "Schedule {} more runs for the benchmark {} on commit {}".format(to_add, benchmark, commit)) - - self.state['commits'][commit]['benchmarks'][benchmark]['rounds'] += to_add - self.__save_state() - - self.__release_lock() - - if to_add > 0: - return to_add - else: - return 0 - - def __prioritize_runs(self, task_tree, deployed_version): - task_list = list() - - # Schedule the tests using the already-deployed version - if deployed_version is not None and deployed_version in task_tree: - for benchmark in task_tree[deployed_version]["benchmarks"]: - rounds = task_tree[deployed_version]["benchmarks"][benchmark]["rounds"] - task_list.append(TaskEntry(deployed_version, benchmark, rounds)) - del task_tree[deployed_version] - - # Add all the remaining tasks in whatever order! - for commit in task_tree: - for benchmark in task_tree[commit]["benchmarks"]: - rounds = task_tree[commit]["benchmarks"][benchmark]["rounds"] - task_list.append(TaskEntry(commit, benchmark, rounds)) - - return task_list - - def run(self): - self.__log(Criticality.II, "----------------------") - self.__log(Criticality.II, "Starting a run: {report} ({path})".format(report=self.state['report_name'], path=self.log_folder)) - - # Check the current state (FIXME: racy) - running_state=self.running_mode() - if running_state == RunningMode.INITIAL or running_state == RunningMode.RUN: - self.set_running_mode(RunningMode.RUN) - else: - self.__log(Criticality.II, - "We cannot run when the current running mode is {mode}.".format(mode=self.running_mode())) - self.__release_lock() - return False - - - self.__log(Criticality.II, "Checking the dependencies:") - - # check for dependencies - if 'profile' not in self.state: - self.__log(Criticality.EE, " - Ezbench profile: Not set. Abort...") - return False - else: - profile = self.state["profile"] - self.__log(Criticality.II, " - Ezbench profile: '{0}'".format(profile)) - - # Create the ezbench runner - ezbench = self.__create_ezbench() - run_info = ezbench.run_commits(["HEAD"], [], [], dry_run=True) - self.__log(Criticality.II, " - Deployed version: '{0}'".format(run_info.deployed_commit)) - self.__log(Criticality.II, "All the dependencies are met, generate a report...") - - # Generate a report to compare the goal with the current state - report = genPerformanceReport(self.log_folder, silentMode = True) - self.__log(Criticality.II, - "The report contains {count} commits".format(count=len(report.commits))) - - # Walk down the report and get rid of every run that has already been made! - task_tree = copy.deepcopy(self.state['commits']) - for commit in report.commits: - for result in commit.results: - self.__log(Criticality.DD, - "Found {count} runs for benchmark {benchmark} using commit {commit}".format(count=len(result.data), - commit=commit.sha1, - benchmark=result.benchmark.full_name)) - if commit.sha1 not in task_tree: - continue - if result.benchmark.full_name not in task_tree[commit.sha1]["benchmarks"]: - continue - - task_tree[commit.sha1]["benchmarks"][result.benchmark.full_name]['rounds'] -= len(result.data) - - if task_tree[commit.sha1]["benchmarks"][result.benchmark.full_name]['rounds'] <= 0: - del task_tree[commit.sha1]["benchmarks"][result.benchmark.full_name] - - if len(task_tree[commit.sha1]["benchmarks"]) == 0: - del task_tree[commit.sha1] - - # Delete the tests on commits that do not compile - for commit in report.commits: - if commit.build_broken() and commit.sha1 in task_tree: - self.__log(Criticality.II, - "Cancelling the following runs because commit {} does not compile:".format(commit.sha1)) - self.__log(Criticality.II, task_tree[commit.sha1]) - del task_tree[commit.sha1] - - if len(task_tree) == 0: - self.__log(Criticality.II, "Nothing left to do, exit") - return - - task_tree_str = pprint.pformat(task_tree) - self.__log(Criticality.II, "Task list: {tsk_str}".format(tsk_str=task_tree_str)) - - # Prioritize --> return a list of commits to do in order - task_list = self.__prioritize_runs(task_tree, run_info.deployed_commit) - - # Let's start! - self.state['beenRunBefore'] = True - - # Start generating ezbench calls - commit_broken = [] - for e in task_list: - running_mode = self.running_mode() - if running_mode != RunningMode.RUN: - self.__log(Criticality.II, - "Running mode changed from RUN to {mode}. Exit...".format(mode=running_mode.name)) - return False - - if e.commit in commit_broken: - msg = "Commit {commit} got marked as broken, cancel the {count} runs for benchmark {benchmark}" - self.__log(Criticality.WW, msg.format(count=e.rounds, commit=e.commit, benchmark=e.benchmark)) - continue - - self.__log(Criticality.DD, - "make {count} runs for benchmark {benchmark} using commit {commit}".format(count=e.rounds, - commit=e.commit, - benchmark=e.benchmark)) - run_info = ezbench.run_commits([e.commit], [e.benchmark + '$'], rounds=e.rounds) - if run_info.success(): - continue - - # We got an error, let's see what we can do about it! - if run_info.exit_code.value < 40: - # Error we cannot do anything about, probably a setup issue - # Let's mark the run as aborted until the user resets it! - self.set_running_mode(RunningMode.ERROR) - elif (run_info.exit_code == EzbenchExitCode.COMPILATION_FAILED or - run_info.exit_code == EzbenchExitCode.DEPLOYMENT_FAILED): - # Cancel any other test on this commit - commit_broken.append(e.commit) - - - - self.__log(Criticality.II, "Done") - - return True - - def git_history(self): - git_history = list() - - # Get the repo directory - ezbench = self.__create_ezbench() - run_info = ezbench.run_commits(["HEAD"], [], [], dry_run=True) - - if not run_info.success(): - return git_history - - # Get the list of commits and store their position in the list in a dict - output = subprocess.check_output(["/usr/bin/git", "log", "--format=%h %ct"], - cwd=run_info.repo_dir).decode().split('\n') - - GitCommit = namedtuple('GitCommit', 'sha1 timestamp') - for line in output: - fields = line.split(' ') - if len(fields) == 2: - git_history.append(GitCommit(fields[0], fields[1])) - - return git_history - - def report(self, git_history=list(), reorder_commits = True): - if reorder_commits and git_history is None: - git_history = self.git_history() - - # Generate the report, order commits based on the git history - r = genPerformanceReport(self.log_folder, silentMode = True) - r.enhance_report([c.sha1 for c in git_history]) - return r - - def __find_middle_commit__(self, git_history, old, new): - old_idx = git_history.index(old) - new_idx = git_history.index(new) - middle_idx = int(old_idx - ((old_idx - new_idx) / 2)) - if middle_idx != old_idx and middle_idx != new_idx: - middle = git_history[middle_idx] - return middle - else: - return None - - # WARNING: benchmark may be None! - def __score_event__(self, git_history, commit_sha1, benchmark, severity): - commit_weight = 1 - (git_history.index(commit_sha1) / len(git_history)) - - bench_weight = 1 - if benchmark is not None and hasattr(benchmark, 'score_weight'): - bench_weight = benchmark.score_weight - - return commit_weight * bench_weight * severity - - def schedule_enhancements(self, git_history=None, max_variance = 0.025, - perf_diff_confidence = 0.95, smallest_perf_change=0.005, - max_run_count = 100): - self.__log(Criticality.DD, "Start enhancing the report") - - # Generate the report, order commits based on the git history - if git_history is None: - git_history = self.git_history() - commits_rev_order = [c.sha1 for c in git_history] - r = genPerformanceReport(self.log_folder, silentMode = True) - r.enhance_report(commits_rev_order, max_variance, perf_diff_confidence, - smallest_perf_change) - - # Check all events - tasks = [] - for e in r.events: - commit_sha1 = None - benchmark = None - event_prio = 1 - severity = 0 # should be a value in [0, 1] - bench_name_to_run = "" - runs = 0 - if type(e) is EventBuildBroken: - if e.commit_range.old is None or e.commit_range.is_single_commit(): - continue - middle = self.__find_middle_commit__(commits_rev_order, - e.commit_range.old.sha1, - e.commit_range.new.sha1) - if middle is None: - continue - - # Schedule the work - commit_sha1 = middle - severity = 1 - event_prio = 0.5 - bench_name_to_run = "no-op" - runs = 1 - elif type(e) is EventBuildFixed: - if e.fixed_commit_range.is_single_commit(): - continue - middle = self.__find_middle_commit__(commits_rev_order, - e.fixed_commit_range.old.sha1, - e.fixed_commit_range.new.sha1) - if middle is None: - continue - - # Schedule the work - commit_sha1 = middle - severity = 1 - event_prio = 0.5 - bench_name_to_run = "no-op" - runs = 1 - elif type(e) is EventPerfChange: - if e.commit_range.is_single_commit(): - continue - - # ignore commits which have a big variance - result_new = r.find_result(e.commit_range.new, e.benchmark) - if result_new.margin() > max_variance: - continue - result_old = r.find_result(e.commit_range.old, e.benchmark) - if result_old.margin() > max_variance: - continue - - middle = self.__find_middle_commit__(commits_rev_order, - e.commit_range.old.sha1, - e.commit_range.new.sha1) - if middle is None: - continue - - # FIXME: handle the case where the middle commit refuses to build - - # Schedule the work - commit_sha1 = middle - benchmark = e.benchmark - severity = min(abs(e.diff()), 1) * e.confidence - event_prio = 0.75 - - bench_name_to_run = benchmark.full_name - runs = (len(result_old.data) + len(result_new.data)) / 2 - elif type(e) is EventInsufficientSignificance: - commit_sha1 = e.result.commit.sha1 - benchmark = e.result.benchmark - cur_runs = len(e.result.data) - wanted_runs = max(cur_runs + 2, e.wanted_n()) # schedule at least 2 more runs - missing_runs = wanted_runs - cur_runs - severity = min(missing_runs / cur_runs, 1) - event_prio = 1 - - bench_name_to_run = benchmark.full_name - runs = min(cur_runs + 20, wanted_runs) # cap the maximum amount of runs to play nice - - # Make sure we do not schedule more than the maximum amount of run - if runs > max_run_count: - runs = max_run_count - cur_runs - if runs == 0: - continue - - score = self.__score_event__(commits_rev_order, commit_sha1, benchmark, severity) - score *= event_prio - - tasks.append((score, commit_sha1, bench_name_to_run, runs, e)) - - # Only schedule the commit with the biggest score to speed up bisecting - # of the most important issues - tasks_sorted = sorted(tasks, key=lambda t: t[0]) - while len(tasks_sorted) > 0: - commit = tasks_sorted[-1][1] - self.__log(Criticality.DD, "Add all the tasks using commit {}".format(commit)) - added = 0 - for t in tasks_sorted: - if t[1] == commit: - added += self.force_benchmark_rounds(t[1], t[2], t[3]) - if added > 0: - self.__log(Criticality.II, "{}".format(t[4])) - break - del tasks_sorted[-1] - self.__log(Criticality.DD, "No work scheduled using commit {}, try another one".format(commit)) - - self.__log(Criticality.DD, "Done enhancing the report") - -# Report parsing -class Benchmark: - def __init__(self, full_name, unit="undefined"): - self.full_name = full_name - self.prevValue = -1 - self.unit_str = unit - -class BenchResult: - def __init__(self, commit, benchmark, data_raw_file): - self.commit = commit - self.benchmark = benchmark - self.data_raw_file = data_raw_file - self.data = [] - self.runs = [] - self.env_files = [] - self.unit_str = None - - # cached data - self._cache_result = None - self._cache_mean = None - self._cache_std = None - - def invalidate_cache(self): - self._cache_result = None - self._cache_mean = None - self._cache_std = None - - def result(self): - if self._cache_result is None: - self._cache_result = sum(self.data) / len(self.data) - return self._cache_result - - def __samples_needed__(self, sigma, margin, confidence=0.95): - # TODO: Find the function in scipy to get these values - if confidence <= 0.9: - z = 1.645 - elif confidence <= 0.95: - z = 1.960 - else: - z = 2.576 - return ((z * sigma) / margin)**2 - - def __compute_stats__(self): - if self._cache_mean is None or self._cache_std is None: - if len(self.data) > 1: - self._cache_mean, var, self._cache_std = stats.bayes_mvs(array(self.data), - alpha=0.95) - else: - if len(self.data) == 0: - value = 0 - else: - value = self.data[0] - self._cache_mean = (value, (value, value)) - self._cache_std = (float("inf"), (float("inf"), float("inf"))) - - def margin(self): - self.__compute_stats__() - return (self._cache_mean[1][1] - self._cache_mean[1][0]) / 2 / self._cache_mean[0] - - # wanted_margin is a number between 0 and 1 - def confidence_margin(self, wanted_margin = None, confidence=0.95): - data = array(self.data) - if len(data) < 2 or data.var() == 0: - return 0, 2 - - self.__compute_stats__() - margin = self.margin() - wanted_samples = 2 - - if wanted_margin is not None: - # TODO: Get sigma from the benchmark instead! - sigma = (self._cache_std[1][1] - self._cache_std[1][0]) / 2 - target_margin = self._cache_mean[0] * wanted_margin - wanted_samples = math.ceil(self.__samples_needed__(sigma, - target_margin, - confidence)) - - return margin, wanted_samples - - -class Commit: - def __init__(self, sha1, full_name, compile_log, patch, label): - self.sha1 = sha1 - self.full_name = full_name - self.compile_log = compile_log - self.patch = patch - self.results = [] - self.geom_mean_cache = -1 - self.label = label - - # Set default values then parse the patch - self.full_sha1 = sha1 - self.author = "UNKNOWN AUTHOR" - self.commiter = "UNKNOWN COMMITER" - self.author_date = datetime.min - self.commit_date = datetime.min - self.title = '' - self.commit_log = '' - self.signed_of_by = set() - self.reviewed_by = set() - self.tested_by = set() - self.bugs = set() - try: - with open(patch, 'r') as f: - log_started = False - fdo_bug_re = re.compile('fdo#(\d+)') - basefdourl = "https://bugs.freedesktop.org/show_bug.cgi?id=" - for line in f: - line = line.strip() - if line == "---": # Detect the end of the header - break - elif line.startswith('commit'): - self.full_sha1 = line.split(' ')[1] - elif line.startswith('Author:'): - self.author = line[12:] - elif line.startswith('AuthorDate: '): - self.author_date = datetime.fromtimestamp(mktime_tz(parsedate_tz(line[12:]))) - elif line.startswith('Commit:'): - self.commiter = line[12:] - elif line.startswith('CommitDate: '): - self.commit_date = datetime.fromtimestamp(mktime_tz(parsedate_tz(line[12:]))) - elif line == '': - # The commit log is about to start - log_started = True - elif log_started: - if self.title == '': - self.title = line - else: - self.commit_log += line + '\n' - if line.startswith('Reviewed-by: '): - self.reviewed_by |= {line[13:]} - elif line.startswith('Signed-off-by: '): - self.signed_of_by |= {line[15:]} - elif line.startswith('Tested-by: '): - self.tested_by |= {line[11:]} - elif line.startswith('Bugzilla: '): - self.bugs |= {line[10:]} - elif line.startswith('Fixes: '): - self.bugs |= {line[7:]} - else: - fdo_bug_m = fdo_bug_re.search(line) - if fdo_bug_m is not None: - bugid = fdo_bug_m.groups()[0] - self.bugs |= {basefdourl + bugid} - except IOError: - pass - - # Look for the exit code - self.compil_exit_code = EzbenchExitCode.UNKNOWN - try: - with open(compile_log, 'r') as f: - for line in f: - pass - # Line contains the last line of the report, parse it - if line.startswith("Exiting with error code "): - self.compil_exit_code = EzbenchExitCode(int(line[24:])) - except IOError: - pass - - def build_broken(self): - return (self.compil_exit_code.value >= EzbenchExitCode.COMP_DEP_UNK_ERROR.value and - self.compil_exit_code.value <= EzbenchExitCode.DEPLOYMENT_ERROR.value) - - def geom_mean(self): - if self.geom_mean_cache >= 0: - return self.geom_mean_cache - - # compute the variance - s = 1 - n = 0 - for result in self.results: - if len(result.data) > 0: - s *= array(result.data).mean() - n = n + 1 - if n > 0: - value = s ** (1 / n) - else: - value = 0 - - geom_mean_cache = value - return value - -class EventCommitRange: - def __init__(self, old, new = None): - self.old = old - if new is None: - self.new = old - else: - self.new = new - - def is_single_commit(self): - return self.distance() <= 1 - - def distance(self): - if self.old is not None: - return self.old.git_distance_head - self.new.git_distance_head - else: - return sys.maxsize - - def __str__(self): - if self.new == None: - return "commit {}".format(self.old.sha1) - - if self.is_single_commit(): - return "commit {}".format(self.new.sha1) - elif self.old is not None: - return "commit range {}:{}({})".format(self.old.sha1, self.new.sha1, - self.distance()) - else: - return "commit before {}".format(self.new.sha1) - - - float("inf") - -class EventBuildBroken: - def __init__(self, commit_range): - self.commit_range = commit_range - - def __str__(self): - return "{} broke the build".format(self.commit_range) - -class EventBuildFixed: - def __init__(self, broken_commit_range, fixed_commit_range): - self.broken_commit_range = broken_commit_range - self.fixed_commit_range = fixed_commit_range - - def broken_for_time(self): - if (self.broken_commit_range.new.commit_date > datetime.min and - self.fixed_commit_range.old.commit_date > datetime.min): - attrs = ['years', 'months', 'days', 'hours', 'minutes', 'seconds'] - human_readable = lambda delta: ['%d %s' % (getattr(delta, attr), - getattr(delta, attr) > 1 and attr or attr[:-1]) - for attr in attrs if getattr(delta, attr)] - res=', '.join(human_readable(relativedelta.relativedelta(self.fixed_commit_range.old.commit_date, - self.broken_commit_range.new.commit_date))) - if len(res) == 0: - return "0 seconds" - else: - return res - return None - - def broken_for_commit_count(self): - return (self.broken_commit_range.new.git_distance_head - - self.fixed_commit_range.new.git_distance_head) - - def __str__(self): - parenthesis = "" - if (not self.broken_commit_range.is_single_commit() or - not self.fixed_commit_range.is_single_commit()): - parenthesis = "at least " - parenthesis += "after " - - time = self.broken_for_time() - if time is not None and time != "": - parenthesis += time + " and " - parenthesis += "{} commits".format(self.broken_for_commit_count()) - - main = "{} fixed the build regression introduced by {}" - main = main.format(self.fixed_commit_range, self.broken_commit_range) - return "{} ({})".format(main, parenthesis) - -class EventPerfChange: - def __init__(self, benchmark, commit_range, old_perf, new_perf, confidence): - self.benchmark = benchmark - self.commit_range = commit_range - self.old_perf = old_perf - self.new_perf = new_perf - self.confidence = confidence - - def diff(self): - if self.old_perf != 0: - return (1 - (self.new_perf / self.old_perf)) * -1 - elif self.new_perf == 0 and self.old_perf == 0: - return 0 - else: - return float("inf") - - def __str__(self): - msg = "{} changed the performance of {} from {:.2f} to {:.2f} ({:+.2f}%) with confidence p={:.2f}" - return msg.format(self.commit_range, self.benchmark.full_name, - self.old_perf, self.new_perf, self.diff() * 100, - self.confidence) - -class EventInsufficientSignificance: - def __init__(self, result, wanted_margin): - self.result = result - self.wanted_margin = wanted_margin - - def margin(self): - return self.result.confidence_margin(self.wanted_margin)[0] - - def wanted_n(self): - return self.result.confidence_margin(self.wanted_margin)[1] - - def __str__(self): - margin, wanted_n = self.result.confidence_margin(self.wanted_margin) - msg = "Benchmark {} on commit {} requires more runs to reach the wanted margin ({:.2f}% vs {:.2f}%), proposes n = {}." - return msg.format(self.result.benchmark.full_name, self.result.commit.sha1, - margin * 100, self.wanted_margin * 100, wanted_n) - -class Report: - def __init__(self, benchmarks, commits, notes): - self.benchmarks = benchmarks - self.commits = commits - self.notes = notes - self.events = list() - - def find_commit(self, sha1): - for commit in self.commits: - if commit.sha1 == sha1: - return commit - return None - - def find_result(self, commit, benchmark): - for result in commit.results: - if result.benchmark == benchmark: - return result - return None - - def enhance_report(self, commits_rev_order, max_variance = 0.025, - perf_diff_confidence = 0.95, smallest_perf_change=0.005): - if len(commits_rev_order) == 0: - return - - # Get rid of the commits that are not in the commits list - to_del = list() - for c in range(0, len(self.commits)): - if self.commits[c].sha1 not in commits_rev_order: - to_del.append(c) - for v in reversed(to_del): - del self.commits[v] - - # Add the index inside the commit - for commit in self.commits: - commit.git_distance_head = commits_rev_order.index(commit.sha1) - - # Sort the remaining commits - self.commits.sort(key=lambda commit: len(commits_rev_order) - commit.git_distance_head) - - # Generate events - commit_prev = None - bench_prev = dict() - build_broken_since = None - for commit in self.commits: - commit_range = EventCommitRange(commit_prev, commit) - - # Look for compilation errors - if commit.build_broken() and build_broken_since is None: - self.events.append(EventBuildBroken(commit_range)) - build_broken_since = EventCommitRange(commit_prev, commit) - elif not commit.build_broken() and build_broken_since is not None: - self.events.append(EventBuildFixed(build_broken_since, commit_range)) - build_broken_since = None - - # Look for performance regressions - for result in commit.results: - perf = result.result() - bench = result.benchmark.full_name - bench_unit = result.benchmark.unit_str - - if result.margin() > max_variance: - self.events.append(EventInsufficientSignificance(result, max_variance)) - - if bench in bench_prev: - # We got previous perf results, compare! - t, p = stats.ttest_ind(bench_prev[bench].data, result.data, equal_var=True) - perf = result.result() - old_perf = bench_prev[bench].result() - diff = abs(perf - old_perf) / old_perf - - # If we are not $perf_diff_confidence sure that this is the - # same normal distribution, say that the performance changed - if p < perf_diff_confidence and diff >= smallest_perf_change: - commit_range = EventCommitRange(bench_prev[bench].commit, commit) - self.events.append(EventPerfChange(result.benchmark, - commit_range, - old_perf, perf, 1 - p)) - bench_prev[bench] = result - - commit_prev = commit - -def readCsv(filepath): - data = [] - - h1 = re.compile('^# (.*) of \'(.*)\' using commit (.*)$') - h2 = re.compile('^# (.*) \\((.*) is better\\) of \'(.*)\' using commit (.*)$') - - with open(filepath, 'rt') as f: - reader = csv.reader(f) - unit = None - more_is_better = True - try: - for row in reader: - if row is None or len(row) == 0: - continue - - # try to extract information from the header - m1 = h1.match(row[0]) - m2 = h2.match(row[0]) - if m2 is not None: - # groups: unit type, more|less qualifier, benchmark, commit_sha1 - unit = m2.groups()[0] - more_is_better = m2.groups()[1].lower() == "more" - elif m1 is not None: - # groups: unit type, benchmark, commit_sha1 - unit = m1.groups()[0] - - # Read the actual data - if len(row) > 0 and not row[0].startswith("# "): - try: - data.append(float(row[0])) - except ValueError as e: - sys.stderr.write('Error in file %s, line %d: %s\n' % (filepath, reader.line_num, e)) - except csv.Error as e: - sys.stderr.write('file %s, line %d: %s\n' % (filepath, reader.line_num, e)) - return [], "none" - - return data, unit, more_is_better - -def readCommitLabels(): - labels = dict() - try: - f = open( "commit_labels", "r") - try: - labelLines = f.readlines() - finally: - f.close() - except IOError: - return labels - - for labelLine in labelLines: - fields = labelLine.split(" ") - sha1 = fields[0] - label = fields[1].split("\n")[0] - labels[sha1] = label - - return labels - -def readNotes(): - try: - with open("notes", 'rt') as f: - return f.readlines() - except: - return [] - -def genPerformanceReport(log_folder, silentMode = False): - benchmarks = [] - commits = [] - labels = dict() - notes = [] - - # Save the current working directory and switch to the log folder - cwd = os.getcwd() - os.chdir(log_folder) - - # Look for the commit_list file - try: - f = open( "commit_list", "r") - try: - commitsLines = f.readlines() - finally: - f.close() - except IOError: - if not silentMode: - sys.stderr.write("The log folder '{0}' does not contain a commit_list file\n".format(log_folder)) - return Report(benchmarks, commits, notes) - - # Read all the commits' labels - labels = readCommitLabels() - - # Check that there are commits - if (len(commitsLines) == 0): - if not silentMode: - sys.stderr.write("The commit_list file is empty\n") - return Report(benchmarks, commits, notes) - - # Gather all the information from the commits - if not silentMode: - print ("Reading the results for {0} commits".format(len(commitsLines))) - commits_txt = "" - table_entries_txt = "" - for commitLine in commitsLines: - full_name = commitLine.strip(' \t\n\r') - sha1 = commitLine.split()[0] - compile_log = sha1 + "_compile_log" - patch = sha1 + ".patch" - label = labels.get(sha1, sha1) - commit = Commit(sha1, full_name, compile_log, patch, label) - - # find all the benchmarks - files_list = os.listdir() - pattern = "{sha1}_bench".format(sha1=commit.sha1) - benchFiles = [f for f in files_list if f.startswith(pattern)] - benchs_txt = "" - for benchFile in benchFiles: - # Skip when the file is a run file (finishes by #XX) - if re.search(r'#\d+$', benchFile) is not None: - continue - - # Skip on unrelated files - if "." in benchFile: - continue - - # Get the bench name - bench_name = benchFile.replace("{sha1}_bench_".format(sha1=commit.sha1), "") - - # Find the right Benchmark or create one if none are found - try: - benchmark = next(b for b in benchmarks if b.full_name == bench_name) - except StopIteration: - benchmark = Benchmark(bench_name) - benchmarks.append(benchmark) - - # Create the result object - result = BenchResult(commit, benchmark, benchFile) - - # Read the data and abort if there is no data - result.data, result.unit_str, result.more_is_better = readCsv(benchFile) - if len(result.data) == 0: - continue - - # Check that the result file has the same default v - if benchmark.unit_str != result.unit_str: - if benchmark.unit_str != "undefined": - msg = "The unit used by the benchmark '{bench}' changed from '{unit_old}' to '{unit_new}' in commit {commit}" - print(msg.format(bench=bench_name, - unit_old=benchmark.unit_str, - unit_new=result.unit_str, - commit=commit.sha1)) - benchmark.unit_str = result.unit_str - - # Look for the runs - run_re = re.compile(r'^{benchFile}#[0-9]+$'.format(benchFile=benchFile)) - runsFiles = [f for f in benchFiles if run_re.search(f)] - runsFiles.sort(key=lambda x: '{0:0>100}'.format(x).lower()) # Sort the runs in natural order - for runFile in runsFiles: - data, unit, more_is_better = readCsv(runFile) - if len(data) > 0: - # Add the FPS readings of the run - result.runs.append(data) - - # Add the environment file - envFile = runFile + ".env_dump" - if not os.path.isfile(envFile): - envFile = None - result.env_files.append(envFile) - - # Add the result to the commit's results - commit.results.append(result) - commit.compil_exit_code = EzbenchExitCode.NO_ERROR # The deployment must have been successful if there is data - - # Add the commit to the list of commits - commit.results = sorted(commit.results, key=lambda res: res.benchmark.full_name) - commits.append(commit) - - # Sort the list of benchmarks - benchmarks = sorted(benchmarks, key=lambda bench: bench.full_name) - - # Read the notes before going back to the original folder - notes = readNotes() - - # Go back to the original folder - os.chdir(cwd) - - return Report(benchmarks, commits, notes) - -def getPerformanceResultsCommitBenchmark(commit, benchmark): - for result in commit.results: - if result.benchmark != benchmark: - continue - - return array(result.data) - - return array([]) - -def getResultsBenchmarkDiffs(commits, benchmark): - results = [] - - # Compute a report per application - i = 0 - origValue = -1 - for commit in commits: - resultFound = False - for result in commit.results: - if result.benchmark != benchmark: - continue - - value = array(result.data).mean() - if origValue > -1: - diff = (value * 100.0 / origValue) - 100.0 - else: - origValue = value - diff = 0 - - results.append([i, diff]) - resultFound = True - - if not resultFound: - results.append([i, NaN]) - i = i + 1 - - return results - -def getResultsGeomDiffs(commits): - results = [] - - # Compute a report per application - i = 0 - origValue = -1 - for commit in commits: - value = commit.geom_mean() - if origValue > -1: - diff = (value * 100.0 / origValue) - 100.0 - else: - origValue = value - diff = 0 - - results.append([i, diff]) - i = i + 1 - - return results - -def convert_unit(value, input_unit, output_type): - ir_fps = -1.0 - - if input_unit == output_type: - return value - - if input_unit == "ms": - ir_fps = 1.0e3 / value - elif input_unit == "us": - ir_fps = 1.0e6 / value - elif input_unit.lower() == "fps": - ir_fps = value - - if ir_fps == -1: - print("convert_unit: Unknown input type " + input_type) - return value - - if output_type == "ms": - return 1.0e3 / ir_fps - elif output_type == "us": - return 1.0e6 / ir_fps - elif output_type.lower() == "fps": - return ir_fps - - print("convert_unit: Unknown output type " + output_type) - return value diff --git a/utils/ezbenchd.py b/utils/ezbenchd.py deleted file mode 100755 index ea97ba8..0000000 --- a/utils/ezbenchd.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python3 - -""" -Copyright (c) 2015, Intel Corporation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -""" - -from ezbench import * -import argparse -import signal -import time -import os - -ezbench_dir = os.path.abspath(sys.path[0] + "/../") -stop_requested = False - -def stop_handler(signum, frame): - global stop_requested - stop_requested = True - print("-- The user requested to abort! --") - # TODO: Abort faster than after every run - return - -def reload_conf_handler(signum, frame): - # TODO - return - - -# parse the options -parser = argparse.ArgumentParser() -args = parser.parse_args() - -# handle the signals systemd asks us to -signal.signal(signal.SIGTERM, stop_handler) -signal.signal(signal.SIGHUP, reload_conf_handler) - -reportStateModDate = dict() - -lastPoll = 0 -while not stop_requested: - futureLastPoll = time.time() - reports = list_smart_ezbench_report_names(ezbench_dir, lastPoll) - lastPoll = futureLastPoll - for report_name in reports: - sbench = SmartEzbench(ezbench_dir, report_name) - if sbench.running_mode() == RunningMode.RUN: - sbench.run() - sbench.schedule_enhancements() - - # TODO: Replace this by inotify - time.sleep(1)
\ No newline at end of file diff --git a/utils/gen_date_labels.py b/utils/gen_date_labels.py deleted file mode 100755 index 6df3c6b..0000000 --- a/utils/gen_date_labels.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python3 - -""" -Copyright (c) 2015, Intel Corporation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -""" - -from ezbench import * -import subprocess -import argparse -import sys -import os - -# Start by checking what the user wants to monitor! -parser = argparse.ArgumentParser() -parser.add_argument("--path", "-p", help="Repository path") -parser.add_argument("log_folder") -args = parser.parse_args() - -if len(args.path) == 0: - print ("You need to specify a path to the git repo using -p.") - exit(1) - -labels_path = os.path.abspath(args.log_folder + "/commit_labels") -if os.path.exists(labels_path): - shouldAbort = input("The commit labels file '{}' already exists and will be deleted.\nAbort? (y/N)".format(labels_path)).lower() == 'y' - if shouldAbort: - exit(0) - print() -f = open(labels_path, 'w') - -report = genPerformanceReport(args.log_folder) - -# Move to the repo's list -os.chdir(args.path) - -for commit in report.commits: - gitCommandLine = ["/usr/bin/git", "show", "--format=%ci", "--date=local", "-s", commit.sha1] - date = subprocess.check_output(gitCommandLine).decode().split(' ')[0] - val = "{commit_sha1} {label}\n".format(commit_sha1=commit.sha1, label=date) - f.write(val) - print(val, end="") -print("Output written to '{}'".format(labels_path))
\ No newline at end of file diff --git a/utils/get_commit_list.py b/utils/get_commit_list.py deleted file mode 100755 index 5404618..0000000 --- a/utils/get_commit_list.py +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env python3 - -""" -Copyright (c) 2015, Intel Corporation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -""" - -import subprocess -import optparse -import sys -import os - -# Start by checking what the user wants to monitor! -p = optparse.OptionParser() -p.add_option('--path', '-p', action='store', type="string", default="", help="Repository path") -p.add_option('--since', '-s', action='store', type="string", default="", help="Starting point of interest") -p.add_option('--until', '-u', action='store', type="string", default="", help="Until which date") -p.add_option('--range', '-r', action='store', type="string", default="", help="Range of commits") -p.add_option('--count', '-c', action='store', type="int", default="-1", help="Select n commits in this commit range") -p.add_option('--interval', '-i', action='store', type="string", default="", help="Interval between commits") -options, arguments = p.parse_args() - -if len(options.path) == 0: - print ("You need to specify a path to the git repo using -p.") - exit(1) - -# Move to the repo's list -os.chdir(options.path) - -# Generate the call to git! -range_str = "" -if len(options.range): - range_str = options.range -elif len(options.since): - range_str += "--since " + options.since - -gitCommandLine = ["/usr/bin/git", "log", "--oneline", "--date=short"] - -if len(options.range) > 0: - gitCommandLine.extend([options.range]) -if len(options.until): - gitCommandLine.extend(["--until", options.until]) - -result = [] -if options.count >= 0: - if len(options.since) > 0: - gitCommandLine.extend(["--since ", options.since]) - commitList = subprocess.check_output(gitCommandLine).decode().split(sep='\n') - step = len(commitList) / options.count - for i in range(0, options.count): - result.append(commitList[int(i * step)].split()[0]) -elif options.interval: - gitCommandLine.extend(["--reverse"]) - date = options.since - sys.stderr.write('Gathering commits: ') - while True: - gitCommandLineRound = list(gitCommandLine) - gitCommandLineRound.extend(["--since", date]) - commitList = subprocess.check_output(gitCommandLineRound) - if len(commitList) == 0: - break - commitList = commitList.decode().split(sep='\n') - result.append(commitList[0].split()[0]) - - sys.stderr.write('.'); sys.stderr.flush() - date = subprocess.check_output(["date", "+%Y-%m-%d", "-d", date + " +" + options.interval]).decode().split(sep='\n')[0] - -sys.stderr.write('\n'); sys.stderr.flush() -print (" ".join(result)) diff --git a/utils/perf_bisect.py b/utils/perf_bisect.py deleted file mode 100755 index 7edcc48..0000000 --- a/utils/perf_bisect.py +++ /dev/null @@ -1,155 +0,0 @@ -#!/usr/bin/env python3 - -""" -Copyright (c) 2015, Intel Corporation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -""" - -from subprocess import call,check_output -from numpy import * -import subprocess -import argparse -import shutil -import sys -import os - -ezbench_dir = os.path.abspath(sys.path[0]+'/../') + '/' - -# Import ezbench from the utils/ folder -sys.path.append(ezbench_dir + 'utils/') -from ezbench import * - -# function that tests the performance of one commit -def check_commit_perf(ezbench, commit, benchmark, rounds, logs_dir): - # Run ezbench - if not ezbench.run_commits([commit], [benchmark + '$'], rounds = rounds).success(): - return 0.0 - - # parse the logs, read the perf of the last entry! - r = genPerformanceReport(logs_dir, silentMode = True) - - if len(r.benchmarks) != 1: - print ("Error: Expected one benchmark result for commit {} but got !".format(commit, len(r.benchmarks))) - sys.exit(1) - - # read the perf report of the last entry! - return getPerformanceResultsCommitBenchmark(r.commits[-1], r.benchmarks[0]).mean() - -def checkPerformance(beforePerf, afterPerf, threshold, perf): - if beforePerf > afterPerf: - if (perf > threshold): - res = "good" - else: - res = "bad" - else: - if (perf > threshold): - res = "bad" - else: - res = "good" - return res - -def isEndOfBisect(git_output): - return "first bad commit" in git_output.split('\n')[0] - -# parse the options -parser = argparse.ArgumentParser() -parser.add_argument("-p", dest='repo_path', help="Git repository's path", - action="store", required=True) -parser.add_argument("-b", dest='benchmark', help="Benchmark to run", - action="store", required=True) -parser.add_argument("-r", dest='rounds', help="Number of execution rounds", - action="store", type=int, nargs='?', const=3) -parser.add_argument("-m", dest='make_cmd', help="Compilation command", - action="store") -parser.add_argument("BEFORE_COMMIT") -parser.add_argument("AFTER_COMMIT") -args = parser.parse_args() - -# compute the report name -reportName = "bisect_{benchmark}_{BEFORE_COMMIT}_{AFTER_COMMIT}".format(benchmark=args.benchmark, - BEFORE_COMMIT=args.BEFORE_COMMIT, - AFTER_COMMIT=args.AFTER_COMMIT) -logs_dir = os.path.abspath(ezbench_dir + '/logs/' + reportName) + '/' - -# Check if the report dir already exists and ask for deletion -if os.path.exists(logs_dir): - shouldAbort = input("The log directory '{}' already exists and will be deleted.\nAbort? (y/N)".format(logs_dir)).lower() == 'y' - if shouldAbort: - exit(0) - shutil.rmtree(logs_dir, ignore_errors=True) - print() - -ezbench = Ezbench(ezbench_path=ezbench_dir + "core.sh", - repo_path=args.repo_path, - make_command = args.make_cmd, - report_name=reportName) - -print("Checking the performance of:") - -# First, try the before and after commits -print("\tBEFORE_COMMIT: ", end="",flush=True) -before_perf = check_commit_perf(ezbench, args.BEFORE_COMMIT, args.benchmark, args.rounds, logs_dir) -print("Performance index {before_perf}".format(before_perf=before_perf)) - -print("\tAFTER_COMMIT: ", end="",flush=True) -after_perf = check_commit_perf(ezbench, args.AFTER_COMMIT, args.benchmark, args.rounds, logs_dir) -print("Performance index {after_perf}".format(after_perf=after_perf)) -print() - -# Find the threshold -threshold = (before_perf + after_perf) / 2 -overThreshold = checkPerformance(before_perf, after_perf, threshold, threshold + 1).upper() -underThreshold = checkPerformance(before_perf, after_perf, threshold, threshold - 1).upper() - -print("Setting the performance threshold to {threshold}.".format(threshold=threshold)) -print("\tIf a commit's perf is > {threshold}, then the commit is {res}".format(threshold=threshold, - res=overThreshold)) -print("\tIf a commit's perf is < {threshold}, then the commit is {res}".format(threshold=threshold, - res=underThreshold)) -print() - -print("Starting the bisecting process.") -print() - -# Start the bisecting feature -os.chdir(args.repo_path) -check_output(['git', 'bisect', 'start'], stderr=subprocess.STDOUT) -check_output(['git', 'bisect', 'good', args.BEFORE_COMMIT], stderr=subprocess.STDOUT) -output = check_output(['git', 'bisect', 'bad', args.AFTER_COMMIT], stderr=subprocess.STDOUT).decode() -print(output, end="") - -while not isEndOfBisect(output): - perf = check_commit_perf(ezbench, "HEAD", args.benchmark, args.rounds, logs_dir) - res = checkPerformance(before_perf, after_perf, threshold, perf) - print("Performance index = {perf} (diffThreshold = {diff}). Marking as {res}\n".format(perf=perf, - diff=perf - threshold, - res=res.upper())) - output = check_output(['git', 'bisect', res]).decode() - print(output, end="") - -firstBad = output.split(" ")[0] -print ("Change introduced by commit {}".format(firstBad)) - -check_output(['git', 'bisect', 'reset'], stderr=subprocess.STDOUT) diff --git a/utils/reorder_commits_by_date.py b/utils/reorder_commits_by_date.py deleted file mode 100755 index bc72f6a..0000000 --- a/utils/reorder_commits_by_date.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python3 - -""" -Copyright (c) 2015, Intel Corporation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -""" - -from ezbench import * -import subprocess -import argparse -import shutil -import sys -import os - -# Start by checking what the user wants to monitor! -parser = argparse.ArgumentParser() -parser.add_argument("--path", "-p", help="Repository path", required=True) -parser.add_argument("log_folder") -args = parser.parse_args() - -if args.path is None or len(args.path) == 0: - print ("You need to specify a path to the git repo using -p.") - exit(1) - -commits_path = os.path.abspath(args.log_folder + "/commit_list") -commits_sav_path = commits_path + ".sav" - -if os.path.exists(commits_sav_path): - shouldAbort = input("The backup commit list file '{}' already exists and will be deleted.\nAbort? (y/N)".format(commits_sav_path)).lower() == 'y' - if shouldAbort: - exit(0) - print() -shutil.copyfile(commits_path, commits_sav_path) - -report = genPerformanceReport(args.log_folder, False) - -f = open(commits_path, 'w') - -# Move to the repo's list -os.chdir(args.path) - -for commit in report.commits: - gitCommandLine = ["/usr/bin/git", "show", "--format=%ct", "--date=local", "-s", commit.sha1] - commit.date = subprocess.check_output(gitCommandLine).decode().split(' ')[0] - -commits = sorted(report.commits, key=lambda commit: commit.date) - -for commit in commits: - val = "{full_name}\n".format(full_name=commit.full_name) - f.write(val) - print(val, end="") |