#!/bin/bash # Copyright (c) 2012 The Native Client Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. set -o xtrace set -o nounset set -o errexit ###################################################################### # SCRIPT CONFIG ###################################################################### readonly CLOBBER=${CLOBBER:-yes} readonly SCONS_TRUSTED="./scons --mode=opt-host -j8" readonly SCONS_NACL="./scons --mode=opt-host,nacl -j8" readonly SPEC_HARNESS=${SPEC_HARNESS:-$(pwd)/out/cpu2000}/ readonly TRYBOT_TESTS="176.gcc 179.art 181.mcf 197.parser 252.eon 254.gap" readonly TRYBOT_X86_64_ZERO_BASED_SANDBOX_TESTS="176.gcc" readonly BUILDBOT_PNACL="buildbot/buildbot_pnacl.sh" readonly UP_DOWN_LOAD="buildbot/file_up_down_load.sh" readonly SPEC_BASE="tests/spec2k" readonly ARCHIVE_NAME=$(${SPEC_BASE}/run_all.sh GetTestArchiveName) readonly NAME_ARM_TRY_UPLOAD=$(${BUILDBOT_PNACL} NAME_ARM_TRY_UPLOAD) readonly NAME_ARM_TRY_DOWNLOAD=$(${BUILDBOT_PNACL} NAME_ARM_TRY_DOWNLOAD) readonly NAME_ARM_UPLOAD=$(${BUILDBOT_PNACL} NAME_ARM_UPLOAD) readonly NAME_ARM_DOWNLOAD=$(${BUILDBOT_PNACL} NAME_ARM_DOWNLOAD) readonly QEMU_TOOL="$(pwd)/toolchain/linux_x86/arm_trusted/run_under_qemu_arm" # Note: the tool for updating the canned nexes lives at: # tools/canned_nexe_tool.sh readonly CANNED_NEXE_REV=1002 # If true, terminate script when first error is encountered. readonly FAIL_FAST=${FAIL_FAST:-false} RETCODE=0 # Print the number of tests being run for the buildbot status output testcount() { local tests="$1" if [[ ${tests} == "all" ]]; then echo "all" else echo ${tests} | wc -w fi } # called when a commands invocation fails handle-error() { RETCODE=1 echo "@@@STEP_FAILURE@@@" if ${FAIL_FAST} ; then echo "FAIL_FAST enabled" exit 1 fi } ###################################################################### # SCRIPT ACTION ###################################################################### clobber-scons() { if [ "${CLOBBER}" == "yes" ] ; then rm -rf scons-out fi } clobber-harness() { if [ "${CLOBBER}" == "yes" ] ; then rm -rf out fi } clobber() { clobber-scons clobber-harness } download-spec2k-harness() { echo "@@@BUILD_STEP Download spec2k harness@@@" mkdir -p out ${NATIVE_PYTHON} ${GSUTIL} cp -a public-read \ gs://nativeclient-private/cpu2000.tar.bz2 out/cpu2000.tar.bz2 tar xvj -C out -f out/cpu2000.tar.bz2 } # Make up for the toolchain tarballs not quite being a full SDK # Also clean the SPEC dir (that step is here because it should # not be run on hw bots which download rather than build binaries) build-prerequisites() { echo "@@@BUILD_STEP build prerequisites [$*] @@@" pushd ${SPEC_BASE} ./run_all.sh BuildPrerequisites "$@" ./run_all.sh CleanBenchmarks ./run_all.sh PopulateFromSpecHarness "${SPEC_HARNESS}" popd } build-tests() { local setups="$1" local tests="$2" local timed="$3" # Do timing and size measurements local compile_repetitions="$4" local count=$(testcount "${tests}") pushd ${SPEC_BASE} for setup in ${setups}; do echo "@@@BUILD_STEP spec2k build [${setup}] [${count} tests]@@@" MAKEOPTS=-j8 \ SPEC_COMPILE_REPETITIONS=${compile_repetitions} \ ./run_all.sh BuildBenchmarks ${timed} ${setup} train ${tests} || \ handle-error done popd } run-tests() { local setups="$1" local tests="$2" local timed="$3" local run_repetitions="$4" local count=$(testcount "${tests}") pushd ${SPEC_BASE} for setup in ${setups}; do echo "@@@BUILD_STEP spec2k run [${setup}] [${count} tests]@@@" if [ ${timed} == "1" ]; then SPEC_RUN_REPETITIONS=${run_repetitions} \ ./run_all.sh RunTimedBenchmarks ${setup} train ${tests} || \ handle-error else ./run_all.sh RunBenchmarks ${setup} train ${tests} || \ handle-error fi done popd } upload-test-binaries() { local tests="$1" local try="$2" # set to "try" if this is a try run pushd ${SPEC_BASE} echo "@@@BUILD_STEP spec2k archive@@@" ./run_all.sh PackageArmBinaries ${tests} popd echo "@@@BUILD_STEP spec2k upload@@@" if [[ ${try} == "try" ]]; then ${UP_DOWN_LOAD} UploadArmBinariesForHWBotsTry ${NAME_ARM_TRY_UPLOAD} \ ${ARCHIVE_NAME} else ${UP_DOWN_LOAD} UploadArmBinariesForHWBots ${NAME_ARM_UPLOAD} \ ${ARCHIVE_NAME} fi } download-test-binaries() { local try="$1" echo "@@@BUILD_STEP spec2k download@@@" if [[ ${try} == "try" ]]; then ${UP_DOWN_LOAD} DownloadArmBinariesForHWBotsTry ${NAME_ARM_TRY_DOWNLOAD} \ ${ARCHIVE_NAME} else ${UP_DOWN_LOAD} DownloadArmBinariesForHWBots ${NAME_ARM_DOWNLOAD} \ ${ARCHIVE_NAME} fi echo "@@@BUILD_STEP spec2k untar@@@" pushd ${SPEC_BASE} ./run_all.sh UnpackArmBinaries popd } download-validator-test-nexes() { local arch="$1" echo "@@@BUILD_STEP validator test download@@@" ${UP_DOWN_LOAD} DownloadArchivedNexes ${CANNED_NEXE_REV} \ "${arch}_giant" giant_nexe.tar.bz2 # This generates "CannedNexes/" in the current directory rm -rf CannedNexes tar jxf giant_nexe.tar.bz2 } get-validator() { local arch="$1" if [[ ${arch} == "x86-32" ]] ; then echo "$(pwd)/scons-out/opt-linux-x86-32/staging/ncval_new" elif [[ ${arch} == "x86-64" ]] ; then echo "$(pwd)/scons-out/opt-linux-x86-64/staging/ncval_new" elif [[ ${arch} == "arm" ]] ; then echo "$(pwd)/scons-out/opt-linux-arm/staging/arm-ncval-core" else echo "ERROR: unknown arch" exit 1 fi } LogTimeHelper() { # This format is recognized by the buildbot system echo "RESULT $1_$2: $3= $(bc) seconds" } LogTimedRun() { local graph=$1 local benchmark=$2 local variant=$3 shift 3 # S: system mode CPU-seconds used by the process # U: user mode CPU-seconds used by the process # We add a plus sign inbetween so that we can pipe the output to "bc" # Note: the >() magic creates a "fake" file (think named pipe) # which passes the output of time to LogTimeHelper /usr/bin/time -f "%U + %S" \ --output >(LogTimeHelper ${graph} ${benchmark} ${variant}) \ "$@" } build-validator() { local arch="$1" echo "@@@BUILD_STEP build validator [${arch}]@@@" if [[ ${arch} == "arm" ]] ; then # TODO(robertm): build the validator echo "NYI" elif [[ ${arch} == "x86-32" ]] ; then ${SCONS_NACL} platform=${arch} ncval_new elif [[ ${arch} == "x86-64" ]] ; then ${SCONS_NACL} platform=${arch} ncval_new else echo "ERROR: unknown arch" exit 1 fi } measure-validator-speed() { local arch="$1" local validator=$(get-validator ${arch}) echo "@@@BUILD_STEP validator speed test [${arch}]@@@" if [[ ! -e ${validator} ]] ; then echo "ERROR: missing validator executable: ${validator}" handle-error return fi if [[ ${arch} == "arm" && $(uname -p) != arm* ]] ; then # TODO(robertm): build the validator validator="${QEMU_TOOL} ${validator}" fi for nexe in CannedNexes/* ; do echo "timing validation of ${nexe}" ls --size --block-size=1 ${nexe} LogTimedRun "validationtime" $(basename ${nexe}) "canned" \ ${validator} ${nexe} done } ###################################################################### # NOTE: trybots only runs a subset of the the spec2k tests pnacl-trybot-arm-buildonly() { clobber download-spec2k-harness build-prerequisites "arm" "bitcode" "arm-ncval-core" ${BUILDBOT_PNACL} archive-for-hw-bots "${NAME_ARM_TRY_UPLOAD}" try build-tests SetupPnaclPexeOpt "${TRYBOT_TESTS}" 0 1 upload-test-binaries "${TRYBOT_TESTS}" try } pnacl-trybot-arm-hw() { clobber ${BUILDBOT_PNACL} unarchive-for-hw-bots "${NAME_ARM_TRY_DOWNLOAD}" try download-test-binaries try build-tests SetupPnaclTranslatorArmOptHW "${TRYBOT_TESTS}" 1 1 run-tests SetupPnaclTranslatorArmOptHW "${TRYBOT_TESTS}" 1 1 build-tests SetupPnaclTranslator1ThreadArmOptHW "${TRYBOT_TESTS}" 1 1 run-tests SetupPnaclTranslator1ThreadArmOptHW "${TRYBOT_TESTS}" 1 1 pushd ${SPEC_BASE}; ./run_all.sh TimeValidation SetupPnaclTranslatorArmOptHW "${TRYBOT_TESTS}" ||\ handle-error popd build-tests SetupPnaclTranslatorFastArmOptHW "${TRYBOT_TESTS}" 1 1 run-tests SetupPnaclTranslatorFastArmOptHW "${TRYBOT_TESTS}" 1 1 build-tests SetupPnaclTranslatorFast1ThreadArmOptHW "${TRYBOT_TESTS}" 1 1 run-tests SetupPnaclTranslatorFast1ThreadArmOptHW "${TRYBOT_TESTS}" 1 1 } pnacl-trybot-x8632() { clobber download-spec2k-harness build-prerequisites "x86-32" "bitcode" build-tests SetupPnaclX8632Opt "${TRYBOT_TESTS}" 1 1 run-tests SetupPnaclX8632Opt "${TRYBOT_TESTS}" 1 1 build-tests SetupPnaclTranslatorX8632Opt "${TRYBOT_TESTS}" 1 1 run-tests SetupPnaclTranslatorX8632Opt "${TRYBOT_TESTS}" 1 1 build-tests SetupPnaclTranslator1ThreadX8632Opt "${TRYBOT_TESTS}" 1 1 run-tests SetupPnaclTranslator1ThreadX8632Opt "${TRYBOT_TESTS}" 1 1 build-tests SetupPnaclTranslatorFastX8632Opt "${TRYBOT_TESTS}" 1 1 run-tests SetupPnaclTranslatorFastX8632Opt "${TRYBOT_TESTS}" 1 1 build-tests SetupPnaclTranslatorFast1ThreadX8632Opt "${TRYBOT_TESTS}" 1 1 run-tests SetupPnaclTranslatorFast1ThreadX8632Opt "${TRYBOT_TESTS}" 1 1 build-validator x86-32 download-validator-test-nexes x86-32 measure-validator-speed x86-32 } pnacl-x86-64-zero-based-sandbox() { # Clobber scons and rebuild sel_ldr with zero-based sandbox support. # If sel_ldr was built to a different directory and the test # runner knew where to find that separate sel_ldr, then we wouldn't # need to clobber here. clobber-scons export NACL_ENABLE_INSECURE_ZERO_BASED_SANDBOX=1 build-prerequisites "x86-64" "bitcode" "x86_64_zero_based_sandbox=1" build-tests SetupPnaclX8664ZBSOpt \ "${TRYBOT_X86_64_ZERO_BASED_SANDBOX_TESTS}" 1 1 run-tests SetupPnaclX8664ZBSOpt \ "${TRYBOT_X86_64_ZERO_BASED_SANDBOX_TESTS}" 1 1 } pnacl-trybot-x8664() { clobber download-spec2k-harness build-prerequisites "x86-64" "bitcode" build-tests SetupPnaclX8664Opt "${TRYBOT_TESTS}" 1 1 run-tests SetupPnaclX8664Opt "${TRYBOT_TESTS}" 1 1 build-tests SetupPnaclTranslatorX8664Opt "${TRYBOT_TESTS}" 1 1 run-tests SetupPnaclTranslatorX8664Opt "${TRYBOT_TESTS}" 1 1 build-tests SetupPnaclTranslator1ThreadX8664Opt "${TRYBOT_TESTS}" 1 1 run-tests SetupPnaclTranslator1ThreadX8664Opt "${TRYBOT_TESTS}" 1 1 build-tests SetupPnaclTranslatorFastX8664Opt "${TRYBOT_TESTS}" 1 1 run-tests SetupPnaclTranslatorFastX8664Opt "${TRYBOT_TESTS}" 1 1 build-tests SetupPnaclTranslatorFast1ThreadX8664Opt "${TRYBOT_TESTS}" 1 1 run-tests SetupPnaclTranslatorFast1ThreadX8664Opt "${TRYBOT_TESTS}" 1 1 pnacl-x86-64-zero-based-sandbox build-validator x86-64 download-validator-test-nexes x86-64 measure-validator-speed x86-64 } pnacl-arm-buildonly() { clobber download-spec2k-harness build-prerequisites "arm" "bitcode" ${BUILDBOT_PNACL} archive-for-hw-bots "${NAME_ARM_UPLOAD}" regular build-tests SetupPnaclPexeOpt all 0 1 upload-test-binaries all regular } pnacl-arm-hw() { clobber ${BUILDBOT_PNACL} unarchive-for-hw-bots "${NAME_ARM_DOWNLOAD}" regular download-test-binaries regular build-tests SetupPnaclTranslatorArmOptHW all 1 1 run-tests SetupPnaclTranslatorArmOptHW all 1 2 # Only run 1 thread ARM tests 1x to save some time for now. # Hopefully perf infrastructure will smooth out flakes. # Otherwise, we'll bump the runs up to 2x as well. build-tests SetupPnaclTranslator1ThreadArmOptHW all 1 1 run-tests SetupPnaclTranslator1ThreadArmOptHW all 1 1 build-tests SetupPnaclTranslatorFastArmOptHW all 1 1 run-tests SetupPnaclTranslatorFastArmOptHW all 1 2 # Only run 1 thread ARM tests 1x to save some time for now. # Hopefully perf infrastructure will smooth out flakes. # Otherwise, we'll bump the runs up to 2x as well. build-tests SetupPnaclTranslatorFast1ThreadArmOptHW all 1 1 run-tests SetupPnaclTranslatorFast1ThreadArmOptHW all 1 1 } pnacl-x8664() { clobber download-spec2k-harness build-prerequisites "x86-64" "bitcode" local setups="SetupPnaclX8664Opt \ SetupPnaclTranslatorX8664Opt \ SetupPnaclTranslator1ThreadX8664Opt \ SetupPnaclTranslatorFastX8664Opt \ SetupPnaclTranslatorFast1ThreadX8664Opt" build-tests "${setups}" all 1 3 run-tests "${setups}" all 1 3 pnacl-x86-64-zero-based-sandbox build-validator x86-64 download-validator-test-nexes x86-64 measure-validator-speed x86-64 } pnacl-x8632() { clobber download-spec2k-harness build-prerequisites "x86-32" "bitcode" local setups="SetupPnaclX8632Opt \ SetupPnaclTranslatorX8632Opt \ SetupPnaclTranslator1ThreadX8632Opt \ SetupPnaclTranslatorFastX8632Opt \ SetupPnaclTranslatorFast1ThreadX8632Opt" build-tests "${setups}" all 1 3 run-tests "${setups}" all 1 3 build-validator x86-32 download-validator-test-nexes x86-32 measure-validator-speed x86-32 } nacl-x8632() { clobber download-spec2k-harness build-prerequisites "x86-32" "" local setups="SetupNaclX8632 \ SetupNaclX8632Opt" build-tests "${setups}" all 1 3 run-tests "${setups}" all 1 3 build-validator x86-32 download-validator-test-nexes x86-32 measure-validator-speed x86-32 } nacl-x8664() { clobber download-spec2k-harness build-prerequisites "x86-64" "" local setups="SetupNaclX8664 \ SetupNaclX8664Opt" build-tests "${setups}" all 1 3 run-tests "${setups}" all 1 3 build-validator x86-64 download-validator-test-nexes x86-64 measure-validator-speed x86-64 } ###################################################################### # Script assumed to be run in native_client/ if [[ $(pwd) != */native_client ]]; then echo "ERROR: must be run in native_client!" exit 1 fi if [[ $# -eq 0 ]] ; then echo "you must specify a mode on the commandline:" exit 1 fi if [ "$(type -t $1)" != "function" ]; then Usage echo "ERROR: unknown mode '$1'." >&2 exit 1 fi "$@" if [[ ${RETCODE} != 0 ]]; then echo "@@@BUILD_STEP summary@@@" echo There were failed stages. exit ${RETCODE} fi