From eeaef3c232ce4945dc1009d8325ceca7ec1c90ae Mon Sep 17 00:00:00 2001 From: Filipp Mikoian Date: Sat, 17 Oct 2020 13:32:19 -0400 Subject: [PATCH 1/2] Refactor run.sh script in a backward-compatible manner First of all, I would leave all the building/cleaning to Make, because there is no need to reinvent building mechanics. But since run.sh is already used for building/cleaning/testing, I decided not to disrespect things as they are and just refactor the code, allowing usage in the original way. What are the enhancements? 1. Extra caution is used to make sure we do not do some unintended stuff: current directory is compared against script source directory; EUID is also checked to make sure we are not root. Usage of -f option makes following these conditional optional. 2. Verbose option is added, but for now it is pretty dumb and just prints full files' paths. I believe however this option will prove itself useful once some custom debug-printing lines are added. 3. Code redundancy is minimized: main part of run.sh is put in the shared directory. 4. Code is refactored, (hopefully) improving general readability. Since we do not use Make, let's at least have our own targets with blackjack and... --- CheckENV/run.sh | 68 ++------------------- OpenMP2/run.sh | 68 ++------------------- OpenMP3/run.sh | 68 ++------------------- OpenMP4/run.sh | 68 ++------------------- OpenMP5/run.sh | 68 ++------------------- openmp_run.inc | 156 ++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 181 insertions(+), 315 deletions(-) create mode 100644 openmp_run.inc diff --git a/CheckENV/run.sh b/CheckENV/run.sh index 6b269de..c9ee69b 100755 --- a/CheckENV/run.sh +++ b/CheckENV/run.sh @@ -1,67 +1,9 @@ #! /bin/bash -# run.sh -compiler="g++" -flags="-fopenmp -std=c++11 -Wall -Wextra -Werror" -src="./src/main.cpp" -build="./build" -exe="$build/task" -tests_dir="./tests" -echo "[CLEAR]" -echo " rm $build -r" -rm $build -rf +# Set script directory for the check performed in openmp_run.inc +SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -echo "[BUILD]" -echo " mkdir $build" -mkdir $build -echo " $compiler $src -o $exe $flags" -$compiler $src -o $exe $flags +# Set a variable to ensure that openmp_run.inc is not ran directly +RUN=1 -if [ ! $? -eq 0 ]; then - echo "[ERROR] Can't compile $src" - exit 1 -fi - -SUCCESS_TESTS=() -FAIL_TESTS=() - -for test_dir in $tests_dir/*; do - test=$(basename $test_dir) - printf "\n[TEST $test]\n" - echo " $exe $test_dir/input.txt $build/$test.txt" - START=$(date +%s%N) - $exe $test_dir/input.txt $build/$test.txt - END=$(date +%s%N) - DIFF=$((($END - $START)/1000000)) - if [ ! $? -eq 0 ]; then - echo "[TEST $test] RUNTIME FAIL" - continue; - fi - if cmp -s $build/$test.txt $test_dir/output.txt; then - echo "[TEST $test] OK ($DIFF ms)" - RES="OK" - if [ -n "$1" ]; then - for ((i=1; i < $1; i++)); do - START=$(date +%s%N) - $exe $test_dir/input.txt $build/${test}_$i.txt - END=$(date +%s%N) - DIFF=$(($DIFF + ($END - $START)/1000000)) - if ! cmp -s $build/${test}_$i.txt $test_dir/output.txt; then - RES="FAIL" - echo "DIFF FAIL: vimdiff $build/${test}_$i.txt $test_dir/output.txt" - FAIL_TESTS+=($test) - fi - done - echo "[TEST ${test}x$1] $RES ($DIFF ms)" - fi - if [[ $RES=="OK" ]]; then - SUCCESS_TESTS+=($test) - fi - else - echo "[TEST $test] DIFF FAIL($DIFF ms): vimdiff $build/$test.txt $test_dir/output.txt" - FAIL_TESTS+=($test) - fi -done -echo "===========" -echo "SUCCESSFUL: ${SUCCESS_TESTS[@]}" -echo "FAIL: ${FAIL_TESTS[@]}" +. $SCRIPTDIR/../openmp_run.inc diff --git a/OpenMP2/run.sh b/OpenMP2/run.sh index 6b269de..c9ee69b 100755 --- a/OpenMP2/run.sh +++ b/OpenMP2/run.sh @@ -1,67 +1,9 @@ #! /bin/bash -# run.sh -compiler="g++" -flags="-fopenmp -std=c++11 -Wall -Wextra -Werror" -src="./src/main.cpp" -build="./build" -exe="$build/task" -tests_dir="./tests" -echo "[CLEAR]" -echo " rm $build -r" -rm $build -rf +# Set script directory for the check performed in openmp_run.inc +SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -echo "[BUILD]" -echo " mkdir $build" -mkdir $build -echo " $compiler $src -o $exe $flags" -$compiler $src -o $exe $flags +# Set a variable to ensure that openmp_run.inc is not ran directly +RUN=1 -if [ ! $? -eq 0 ]; then - echo "[ERROR] Can't compile $src" - exit 1 -fi - -SUCCESS_TESTS=() -FAIL_TESTS=() - -for test_dir in $tests_dir/*; do - test=$(basename $test_dir) - printf "\n[TEST $test]\n" - echo " $exe $test_dir/input.txt $build/$test.txt" - START=$(date +%s%N) - $exe $test_dir/input.txt $build/$test.txt - END=$(date +%s%N) - DIFF=$((($END - $START)/1000000)) - if [ ! $? -eq 0 ]; then - echo "[TEST $test] RUNTIME FAIL" - continue; - fi - if cmp -s $build/$test.txt $test_dir/output.txt; then - echo "[TEST $test] OK ($DIFF ms)" - RES="OK" - if [ -n "$1" ]; then - for ((i=1; i < $1; i++)); do - START=$(date +%s%N) - $exe $test_dir/input.txt $build/${test}_$i.txt - END=$(date +%s%N) - DIFF=$(($DIFF + ($END - $START)/1000000)) - if ! cmp -s $build/${test}_$i.txt $test_dir/output.txt; then - RES="FAIL" - echo "DIFF FAIL: vimdiff $build/${test}_$i.txt $test_dir/output.txt" - FAIL_TESTS+=($test) - fi - done - echo "[TEST ${test}x$1] $RES ($DIFF ms)" - fi - if [[ $RES=="OK" ]]; then - SUCCESS_TESTS+=($test) - fi - else - echo "[TEST $test] DIFF FAIL($DIFF ms): vimdiff $build/$test.txt $test_dir/output.txt" - FAIL_TESTS+=($test) - fi -done -echo "===========" -echo "SUCCESSFUL: ${SUCCESS_TESTS[@]}" -echo "FAIL: ${FAIL_TESTS[@]}" +. $SCRIPTDIR/../openmp_run.inc diff --git a/OpenMP3/run.sh b/OpenMP3/run.sh index 6b269de..c9ee69b 100755 --- a/OpenMP3/run.sh +++ b/OpenMP3/run.sh @@ -1,67 +1,9 @@ #! /bin/bash -# run.sh -compiler="g++" -flags="-fopenmp -std=c++11 -Wall -Wextra -Werror" -src="./src/main.cpp" -build="./build" -exe="$build/task" -tests_dir="./tests" -echo "[CLEAR]" -echo " rm $build -r" -rm $build -rf +# Set script directory for the check performed in openmp_run.inc +SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -echo "[BUILD]" -echo " mkdir $build" -mkdir $build -echo " $compiler $src -o $exe $flags" -$compiler $src -o $exe $flags +# Set a variable to ensure that openmp_run.inc is not ran directly +RUN=1 -if [ ! $? -eq 0 ]; then - echo "[ERROR] Can't compile $src" - exit 1 -fi - -SUCCESS_TESTS=() -FAIL_TESTS=() - -for test_dir in $tests_dir/*; do - test=$(basename $test_dir) - printf "\n[TEST $test]\n" - echo " $exe $test_dir/input.txt $build/$test.txt" - START=$(date +%s%N) - $exe $test_dir/input.txt $build/$test.txt - END=$(date +%s%N) - DIFF=$((($END - $START)/1000000)) - if [ ! $? -eq 0 ]; then - echo "[TEST $test] RUNTIME FAIL" - continue; - fi - if cmp -s $build/$test.txt $test_dir/output.txt; then - echo "[TEST $test] OK ($DIFF ms)" - RES="OK" - if [ -n "$1" ]; then - for ((i=1; i < $1; i++)); do - START=$(date +%s%N) - $exe $test_dir/input.txt $build/${test}_$i.txt - END=$(date +%s%N) - DIFF=$(($DIFF + ($END - $START)/1000000)) - if ! cmp -s $build/${test}_$i.txt $test_dir/output.txt; then - RES="FAIL" - echo "DIFF FAIL: vimdiff $build/${test}_$i.txt $test_dir/output.txt" - FAIL_TESTS+=($test) - fi - done - echo "[TEST ${test}x$1] $RES ($DIFF ms)" - fi - if [[ $RES=="OK" ]]; then - SUCCESS_TESTS+=($test) - fi - else - echo "[TEST $test] DIFF FAIL($DIFF ms): vimdiff $build/$test.txt $test_dir/output.txt" - FAIL_TESTS+=($test) - fi -done -echo "===========" -echo "SUCCESSFUL: ${SUCCESS_TESTS[@]}" -echo "FAIL: ${FAIL_TESTS[@]}" +. $SCRIPTDIR/../openmp_run.inc diff --git a/OpenMP4/run.sh b/OpenMP4/run.sh index 6b269de..c9ee69b 100755 --- a/OpenMP4/run.sh +++ b/OpenMP4/run.sh @@ -1,67 +1,9 @@ #! /bin/bash -# run.sh -compiler="g++" -flags="-fopenmp -std=c++11 -Wall -Wextra -Werror" -src="./src/main.cpp" -build="./build" -exe="$build/task" -tests_dir="./tests" -echo "[CLEAR]" -echo " rm $build -r" -rm $build -rf +# Set script directory for the check performed in openmp_run.inc +SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -echo "[BUILD]" -echo " mkdir $build" -mkdir $build -echo " $compiler $src -o $exe $flags" -$compiler $src -o $exe $flags +# Set a variable to ensure that openmp_run.inc is not ran directly +RUN=1 -if [ ! $? -eq 0 ]; then - echo "[ERROR] Can't compile $src" - exit 1 -fi - -SUCCESS_TESTS=() -FAIL_TESTS=() - -for test_dir in $tests_dir/*; do - test=$(basename $test_dir) - printf "\n[TEST $test]\n" - echo " $exe $test_dir/input.txt $build/$test.txt" - START=$(date +%s%N) - $exe $test_dir/input.txt $build/$test.txt - END=$(date +%s%N) - DIFF=$((($END - $START)/1000000)) - if [ ! $? -eq 0 ]; then - echo "[TEST $test] RUNTIME FAIL" - continue; - fi - if cmp -s $build/$test.txt $test_dir/output.txt; then - echo "[TEST $test] OK ($DIFF ms)" - RES="OK" - if [ -n "$1" ]; then - for ((i=1; i < $1; i++)); do - START=$(date +%s%N) - $exe $test_dir/input.txt $build/${test}_$i.txt - END=$(date +%s%N) - DIFF=$(($DIFF + ($END - $START)/1000000)) - if ! cmp -s $build/${test}_$i.txt $test_dir/output.txt; then - RES="FAIL" - echo "DIFF FAIL: vimdiff $build/${test}_$i.txt $test_dir/output.txt" - FAIL_TESTS+=($test) - fi - done - echo "[TEST ${test}x$1] $RES ($DIFF ms)" - fi - if [[ $RES=="OK" ]]; then - SUCCESS_TESTS+=($test) - fi - else - echo "[TEST $test] DIFF FAIL($DIFF ms): vimdiff $build/$test.txt $test_dir/output.txt" - FAIL_TESTS+=($test) - fi -done -echo "===========" -echo "SUCCESSFUL: ${SUCCESS_TESTS[@]}" -echo "FAIL: ${FAIL_TESTS[@]}" +. $SCRIPTDIR/../openmp_run.inc diff --git a/OpenMP5/run.sh b/OpenMP5/run.sh index 6b269de..c9ee69b 100755 --- a/OpenMP5/run.sh +++ b/OpenMP5/run.sh @@ -1,67 +1,9 @@ #! /bin/bash -# run.sh -compiler="g++" -flags="-fopenmp -std=c++11 -Wall -Wextra -Werror" -src="./src/main.cpp" -build="./build" -exe="$build/task" -tests_dir="./tests" -echo "[CLEAR]" -echo " rm $build -r" -rm $build -rf +# Set script directory for the check performed in openmp_run.inc +SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -echo "[BUILD]" -echo " mkdir $build" -mkdir $build -echo " $compiler $src -o $exe $flags" -$compiler $src -o $exe $flags +# Set a variable to ensure that openmp_run.inc is not ran directly +RUN=1 -if [ ! $? -eq 0 ]; then - echo "[ERROR] Can't compile $src" - exit 1 -fi - -SUCCESS_TESTS=() -FAIL_TESTS=() - -for test_dir in $tests_dir/*; do - test=$(basename $test_dir) - printf "\n[TEST $test]\n" - echo " $exe $test_dir/input.txt $build/$test.txt" - START=$(date +%s%N) - $exe $test_dir/input.txt $build/$test.txt - END=$(date +%s%N) - DIFF=$((($END - $START)/1000000)) - if [ ! $? -eq 0 ]; then - echo "[TEST $test] RUNTIME FAIL" - continue; - fi - if cmp -s $build/$test.txt $test_dir/output.txt; then - echo "[TEST $test] OK ($DIFF ms)" - RES="OK" - if [ -n "$1" ]; then - for ((i=1; i < $1; i++)); do - START=$(date +%s%N) - $exe $test_dir/input.txt $build/${test}_$i.txt - END=$(date +%s%N) - DIFF=$(($DIFF + ($END - $START)/1000000)) - if ! cmp -s $build/${test}_$i.txt $test_dir/output.txt; then - RES="FAIL" - echo "DIFF FAIL: vimdiff $build/${test}_$i.txt $test_dir/output.txt" - FAIL_TESTS+=($test) - fi - done - echo "[TEST ${test}x$1] $RES ($DIFF ms)" - fi - if [[ $RES=="OK" ]]; then - SUCCESS_TESTS+=($test) - fi - else - echo "[TEST $test] DIFF FAIL($DIFF ms): vimdiff $build/$test.txt $test_dir/output.txt" - FAIL_TESTS+=($test) - fi -done -echo "===========" -echo "SUCCESSFUL: ${SUCCESS_TESTS[@]}" -echo "FAIL: ${FAIL_TESTS[@]}" +. $SCRIPTDIR/../openmp_run.inc diff --git a/openmp_run.inc b/openmp_run.inc new file mode 100644 index 0000000..45bad25 --- /dev/null +++ b/openmp_run.inc @@ -0,0 +1,156 @@ +#! /bin/bash + +# DO NOT RUN THIS FILE DIRECTLY, USE run.sh FILES IN CORRESPONDING DIRECTORIES +# Special check to ensure that +if [[ $RUN != 1 ]]; then + exit 1 +fi + +# Abort when error occurs + + set -e + +# Declare helper functions + + function pre_target() { + TARGET=$1 + echo "[$TARGET]" + trap '{ set +x; } 2>/dev/null; echo "[$TARGET] FAIL"' EXIT + } + + function post_target() { + printf "[$TARGET] $1\n\n" + trap - EXIT + } + +# Process options and check for some errors + + while getopts ":fv" opt; do + case ${opt} in + f ) FORCE=1 + ;; + v ) VERBOSE=1 + ;; + \? ) echo "Usage: run.sh [-f] [-v] [iternum]" + echo " -f: disable paranoid errors" + echo " -v: verbose" + echo " iternum: number of times to run test" + echo " attempting to find a race" + exit 0 + ;; + esac + done + shift $((OPTIND-1)) + + if [ -z $VERBOSE ]; then + # Use relative paths + CURDIR="." + else + # Use absolute paths + # Note that this will force failure if current user + # does not have appropriate permissions for parent directories + CURDIR="`pwd`" + fi + + # Compare directory of the bash script source to current + # Bash script's directory is set in the including script + MESSAGE="Script source path is not equal to current directory path" + if [ $SCRIPTDIR != `pwd` ]; then + if [ -z $FORCE ]; then + echo "[ERROR] $MESSAGE" + exit 1 + else + echo "[FORCED][WARNING] $MESSAGE" + fi + fi + + # Find out if we are root + if [[ $EUID -eq 0 ]]; then + if [ -z $FORCE ]; then + echo "[ERROR] Attempt to run as root" + exit 1 + else + echo "[FORCED][WARNING] Running as root" + fi + fi + + # Check if ITERNUM argument is passed, default to 1 + ITERNUM="$1" + if [ -z "$ITERNUM" ]; then + ITERNUM=1 + fi + # Check if passed argument is number + MESSAGE="Argument \"$ITERNUM\" is not a number" + if ! [[ "$ITERNUM" =~ ^[0-9]+$ ]]; then + if [ -z $FORCE ]; then + echo "[ERROR] $MESSAGE" + exit 1 + else + echo "[FORCED][WARNING] $MESSAGE, defaulting to 1" + fi + fi + +# CLEAR and BUILD targets + + CC="g++" + FLAGS="-fopenmp -std=c++11 -Wall -Wextra -Werror" + BUILDDIR="$CURDIR/build" + EXEC="$BUILDDIR/task" + TESTSDIR="$CURDIR/tests" + SRC="$CURDIR/src/main.cpp" + + pre_target "CLEAR"; set -x + rm $BUILDDIR -rf + { set +x; } 2>/dev/null; post_target "OK" + + pre_target "BUILD"; set -x + mkdir $BUILDDIR + $CC $SRC -o $EXEC $FLAGS + { set +x; } 2>/dev/null; post_target "OK" + +# TESTING + + SUCCESS_TESTS=() + FAIL_TESTS=() + + for CURTESTDIR in $TESTSDIR/*; do + CURTEST="$(basename $CURTESTDIR)" + + pre_target "TEST $CURTEST" + + TIMESUM=0 + TEST_FAILED=0 + for ((i=0; i < $ITERNUM; i++)); do + printf "\rRunning iteration $(($i+1))/$ITERNUM" + + # Run test, measure execution time + START=$(date +%s%N) + $EXEC $CURTESTDIR/input.txt $BUILDDIR/${CURTEST}_$i.txt + END=$(date +%s%N) + TIMESUM=$(($TIMESUM + ($END - $START)/1000000)) + + # Check output validity + set +e + cmp -s $BUILDDIR/${CURTEST}_$i.txt $CURTESTDIR/output.txt + CMPRET=$? + set -e + if [[ $CMPRET -ne 0 ]]; then + RESULT="Wrong output, check with 'vimdiff $BUILDDIR/${CURTEST}_$i.txt $CURTESTDIR/output.txt'" + FAIL_TESTS+=($CURTEST) + TEST_FAILED=1 + break + fi + done + if [[ $TEST_FAILED -eq 0 ]]; then + RESULT="OK (average $(($TIMESUM/$ITERNUM)) ms)" + SUCCESS_TESTS+=($CURTEST) + fi + + echo; { post_target "$RESULT"; } 2>/dev/null + done + +# Outro + + echo "===========" + echo "SUCCESSFUL: ${SUCCESS_TESTS[@]}" + echo "FAIL: ${FAIL_TESTS[@]}" From 00b82e6fa68d0a2053f4ce26b053f6a12fd6d336 Mon Sep 17 00:00:00 2001 From: Filipp Mikoian Date: Fri, 23 Oct 2020 10:48:45 -0400 Subject: [PATCH 2/2] openmp_run.sh: add -t option to run specific tests --- openmp_run.inc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/openmp_run.inc b/openmp_run.inc index 45bad25..ecb26e9 100644 --- a/openmp_run.inc +++ b/openmp_run.inc @@ -25,15 +25,20 @@ fi # Process options and check for some errors - while getopts ":fv" opt; do + while getopts ":fvt:" opt; do case ${opt} in f ) FORCE=1 ;; v ) VERBOSE=1 ;; - \? ) echo "Usage: run.sh [-f] [-v] [iternum]" + t ) TESTS+="tests/$OPTARG " + echo "TESTS= '$TESTS'" + ;; + \? ) echo "Usage: run.sh [-f] [-v] [-t TESTNAME] [iternum]" echo " -f: disable paranoid errors" echo " -v: verbose" + echo " -t: only run specific test. This " + echo " option can be specified multiple times" echo " iternum: number of times to run test" echo " attempting to find a race" exit 0 @@ -113,7 +118,10 @@ fi SUCCESS_TESTS=() FAIL_TESTS=() - for CURTESTDIR in $TESTSDIR/*; do + if [ -z "$TESTS" ]; then + TESTS=$TESTSDIR/* + fi + for CURTESTDIR in $TESTS; do CURTEST="$(basename $CURTESTDIR)" pre_target "TEST $CURTEST"