274 lines
10 KiB
Bash
Executable File
274 lines
10 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Use this Bash script to test RT processing speed.
|
|
# Written by DrSlony
|
|
# v1 2012-02-10
|
|
# v2 2013-02-15
|
|
# v3 2013-03-04
|
|
# v4 2013-03-07
|
|
# v5 2013-03-23
|
|
# v6 2017-07-03
|
|
# v7 2017-07-04
|
|
# www.rawtherapee.com
|
|
|
|
inFile='http://rawtherapee.com/shared/test_images/colorspace_flowers.pef'
|
|
rtExe="rawtherapee-cli"
|
|
OPTIND=1 # Reset in case getopts has been used previously in the shell.
|
|
tmpDir="/tmp/rawtherapee-benchmark"
|
|
runs=5
|
|
echo
|
|
|
|
die () {
|
|
printf '%s\n' "Cleaning up."
|
|
rm -rv "${tmpDir}"
|
|
exit 1
|
|
}
|
|
|
|
trap die HUP INT QUIT ABRT TERM
|
|
|
|
download () {
|
|
local retries=3
|
|
while [[ $retries -ne 0 ]]; do
|
|
wget --progress=dot:binary --continue --trust-server-names --tries=1 --timestamping "$1" 2>&1 | sed "s/^/\t/"
|
|
return=${PIPESTATUS[0]}
|
|
((retries--))
|
|
if [[ $return -eq 0 ]]; then # I don't trust wget to only exit with 0 if it downloaded the file successfully, so I check.
|
|
if [[ -f "$(basename "$1")" ]]; then
|
|
break
|
|
fi
|
|
fi
|
|
printf "%s\n\n" "Failed to download \"$1\"" "Retrying: "
|
|
sleep 1s
|
|
done
|
|
if [[ $retries -eq 0 ]]; then
|
|
printf "%s\n" "Tried to download \"$1\" 3 times but failed. Exiting."
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
howto() {
|
|
cat<<END
|
|
Introduction
|
|
------------
|
|
Benchmark the time it takes for RawTherapee to process an image.
|
|
The designated file will be processed ${runs} times in a row, and
|
|
the average time of those ${runs} runs will be calculated.
|
|
|
|
All options are optional.
|
|
|
|
Make sure you have no unnecessary background activity - no programs
|
|
intensively using the CPU. Turn off all P2P, multimedia, graphics
|
|
editing, games, database, server and other "heavy" software,
|
|
otherwise the timings will be skewed. You can use the "top" and
|
|
"ps ux" commands to see a list of running processes and their CPU usage.
|
|
|
|
Usage
|
|
-----
|
|
./benchmarkRT [OPTIONS]
|
|
|
|
Options
|
|
-------
|
|
-a - Run a benchmark for all the tools available in RT.
|
|
|
|
-e - Absolute path to but excluding the "${rtExe}" executable.
|
|
e.g. "-e ${HOME}/programs/code-rawtherapee/build/release"
|
|
|
|
-h - Print this help screen.
|
|
|
|
-i <file> - Absolute path to image file. This can be a file on your
|
|
hard drive or a url. The url must start with "http". The default
|
|
behavior if you do not specify -i is to download a raw image from
|
|
${inFile}
|
|
|
|
-s <PP3-1> -s <PP3-2> -s <PP3-#> - Absolute path to sidecar file.
|
|
You can specify multiple sidecar files, use -s each time.
|
|
The processing profile can be a file on your hard drive or a url.
|
|
The default behaviour if you do not specify -s is to use the
|
|
"Neutral" profile.
|
|
|
|
Examples
|
|
--------
|
|
Run the default benchmark (recommended)
|
|
./benchmarkRT
|
|
|
|
Run a benchmark using your own image file, a RawTherpee executable in a
|
|
custom directory, and multiple processing profiles:
|
|
./benchmarkRT -i /tmp/kittens.raw -s /tmp/noise_reduction.pp3 -s /tmp/tonemapping.pp3 -s /tmp/retinex.pp3
|
|
|
|
Further Help
|
|
------------
|
|
If you need further help, discover bugs or want to request new
|
|
functionality, then tell us in the forum or on IRC:
|
|
https://discuss.pixls.us/t/welcome-to-the-rawtherapee-forum-read-this-first/473
|
|
http://webchat.freenode.net/?randomnick=1&channels=rawtherapee&prompt=1
|
|
|
|
END
|
|
}
|
|
|
|
OPTIND=1
|
|
while getopts "ae:i:s:h?" opt; do
|
|
case "$opt" in
|
|
a) testAllTools=1
|
|
;;
|
|
e) customExeDir="${OPTARG%/}"
|
|
;;
|
|
i) inFile="$OPTARG"
|
|
;;
|
|
s) sidecarCustom+=("$OPTARG")
|
|
;;
|
|
h|\?|*)
|
|
howto
|
|
exit 0
|
|
;;
|
|
esac
|
|
done
|
|
shift $((OPTIND-1))
|
|
[ "$1" = "--" ] && shift
|
|
|
|
inFileName="$(basename "${inFile}")"
|
|
if [[ ! -e "${tmpDir}" ]]; then
|
|
if [[ ! -w /tmp ]]; then
|
|
printf "Error: /tmp is not writable.\n"
|
|
exit 1
|
|
fi
|
|
mkdir "$tmpDir"
|
|
fi
|
|
|
|
cd "$tmpDir"
|
|
|
|
if [[ ${inFile} = http* ]]; then # if inFile is a url and if we haven't downloaded it already, then download it
|
|
[[ ! -e "${tmpDir}/${inFileName}" ]] && {
|
|
printf "%s\n\n" "${inFileName} not found in ${tmpDir}, downloading it."
|
|
[[ ! -w /tmp ]] && { printf "Error: /tmp is not writable.\n"; exit 1; }
|
|
[[ ! -e "$tmpDir" ]] && mkdir "$tmpDir"
|
|
cd "$tmpDir"
|
|
download "$inFile"
|
|
echo
|
|
}
|
|
else # otherwise if inFile is not a url, check if it exists
|
|
[[ ! -e "${inFile}" ]] && { # if it doesn't exist, choke
|
|
printf "%s\n" "You specified" "-i ${inFile}" "but that file does not exist."
|
|
exit 1
|
|
}
|
|
cp "${inFile}" "${tmpDir}/${inFileName}"
|
|
fi
|
|
|
|
rtExeDirs=("${customExeDir}" "${HOME}/rt" "${HOME}/programs/code-rawtherapee/build/release" "${HOME}/rt_${branch}_${buildType}" "${HOME}/rawtherapee/")
|
|
found="false"
|
|
for rtExeDir in "${rtExeDirs[@]}"; do
|
|
if [[ -x "${rtExeDir}/${rtExe}" ]]; then
|
|
found="true"
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [[ $found = false ]]; then
|
|
printf "%s\n" "Could not find the RawTherapee executable." "Re-run this script using the -e flag."
|
|
exit 0
|
|
fi
|
|
|
|
if [[ $testAllTools -ne 1 ]]; then
|
|
if [[ -n "${sidecarCustom}" ]]; then # if sidecarCustom was specified
|
|
for sidecarFile in "${sidecarCustom[@]}"; do
|
|
if [[ ${sidecarFile} = http* ]]; then # and if sidecarCustom starts with an http
|
|
if [[ ! -e "${tmpDir}/$/{sidecarFile##*/}" ]]; then # and if sidecarCustom hasn't been previously downloaded, then download it
|
|
printf "${sidecarCustom} not found in ${tmpDir}, downloading it.\n"
|
|
download "$sidecarCustom"
|
|
fi
|
|
fi
|
|
if [[ -e "${sidecarFile}" ]]; then # then check if it exists
|
|
sidecarFinal+=("${sidecarFile}")
|
|
else
|
|
printf '%s\n' "You specified \"-s ${sidecarFile}\" but it does not exist. Make sure you wrote a full, absolute path, e.g.:" " -s /tmp/custom.pp3"
|
|
exit 1
|
|
fi
|
|
done
|
|
unset sidecarFiles
|
|
sidecarFiles=("${sidecarCustom[@]}")
|
|
else
|
|
# if sidecarCustom was not specified, use neutral. Since neutral is not a file,
|
|
# we take advantage of the fact that when RawTherapee does not find a processing profile, it uses neutral values.
|
|
sidecarFinal=("Neutral")
|
|
fi
|
|
else
|
|
unset sidecarFiles avgTable sidecarDir
|
|
sidecarDir="${tmpDir}/"
|
|
tools=("Auto Exposure;Exposure;Auto=true" "Sharpening - Unsharp Mask;Sharpening;Enabled=true;Method=usm" "Sharpening - RL Deconvolution;Sharpening;Enabled=true;Method=rld" "Vibrance;Vibrance;Enabled=true" "Edges;SharpenEdge;Enabled=true" "Microcontrast;SharpenMicro;Enabled=true" "CIECAM02;Color appearance;Enabled=true" "Impulse Noise Reduction;Impulse Denoising;Enabled=true" "Defringe;Defringing;Enabled=true" "Noise Reduction;Directional Pyramid Denoising;Enabled=true" "Tone Mapping;EPD;Enabled=true" "Shadows/Highlights;Shadows & Highlights;Enabled=true" "Contrast by Detail Levels;Directional Pyramid Equalizer;Enabled=true" "Raw Chromatic Aberration;RAW;CA=true")
|
|
for i in "${!tools[@]}"; do
|
|
IFS=";" read toolNameHuman tool key1 key2 key3 <<< "${tools[$i]}"
|
|
i=$(printf "%02d\n" "$i")
|
|
printf "%s\n" "[${tool}]" "$key1" "$key2" "$key3" > "${sidecarDir}/${i} - ${tool}.pp3"
|
|
sidecarFinal+=("${i} - ${tool}.pp3;${toolNameHuman}")
|
|
done
|
|
fi
|
|
|
|
printf "%s\n" "$(uname -srvmpio)" ""
|
|
hash cpufreq-info 2>/dev/null && { cpufreq-info -mo; printf "%s\n" ""; }
|
|
|
|
printf "%s\n" "RawTherapee executable: ${rtExeDir}/${rtExe}"
|
|
|
|
if [[ ! -f "${rtExeDir}/AboutThisBuild.txt" ]]; then
|
|
printf "%s\n" "[Could not find ${rtExeDir}/AboutThisBuild.txt]" ""
|
|
else
|
|
cat "${rtExeDir}/AboutThisBuild.txt"
|
|
fi
|
|
|
|
printf "%s\n" "Photo: ${tmpDir}/${inFileName}"
|
|
for sidecar in "${sidecarFinal[@]}"; do
|
|
if [[ $testAllTools -eq 1 ]]; then
|
|
IFS=";" read sidecar toolNameHuman <<< "${sidecar}"
|
|
fi
|
|
printf "%s\n" "Sidecar: ${sidecarDir}${sidecar}"
|
|
done
|
|
echo
|
|
|
|
declare -A avgTable
|
|
unset benchmark total sidecar sorted
|
|
|
|
# Unfudge numbers to make sed/PE possible without spaghetti.
|
|
export LC_ALL=C
|
|
|
|
for s in "${!sidecarFinal[@]}"; do
|
|
IFS=";" read sidecar toolNameHuman <<< "${sidecarFinal[s]}"
|
|
unset benchmark
|
|
for (( i=1; i<=${runs}; i++ )); do
|
|
runTime="$( { time "${rtExeDir}/${rtExe}" -o /dev/null/ -p "${sidecarDir}${sidecar}" -t -Y -c "${tmpDir}/${inFileName}"; } 2>&1 | grep ^real; )"
|
|
# runTime=real 0m4.751s
|
|
runTime=${runTime#*[[:blank:]]}
|
|
# runTime=0m4.751s
|
|
minOnly=${runTime%m*}
|
|
secOnly=${runTime#*m}; secOnly=${secOnly%s*}
|
|
t="$( printf "%s\n" "scale=3; $secOnly+$minOnly*60" | bc )"
|
|
# t=4.751
|
|
## t="$(( $RANDOM %20 )).$(( $RANDOM %999 ))"
|
|
# benchmark stores time array of each run, gets reset after each PP3
|
|
benchmark+=("$t")
|
|
# total stores time array of each run, doesn't get reset, adds up total afterwards
|
|
total+=("$t")
|
|
i="$(printf "%02d\n" "$i")"
|
|
if [[ $testAllTools -eq 1 ]]; then
|
|
printf "%*b" "-50" "Benchmark ${i} \"${toolNameHuman}\"" "7" "${benchmark[$i - 1]}" "" "\n" | sed 's/ /../g'
|
|
else
|
|
printf "%*b" "-50" "Benchmark ${i} \"${sidecar##*/}\"" "7" "${benchmark[$i - 1]}" "" "\n" | sed 's/ /../g'
|
|
fi
|
|
done
|
|
|
|
avg=$( { printf "%s" "scale=3; ("; IFS="+"; printf "%s" "${benchmark[*]}"; printf "%s\n" ") / ${#benchmark[@]}"; } | bc );
|
|
if [[ $testAllTools -eq 1 ]]; then
|
|
printf "%*b" "-50" "Benchmark \"${toolNameHuman}\" average" "7" "${avg}" "" "\n\n" | sed 's/ /../g'
|
|
avgTable+=(["${toolNameHuman}"]="$avg")
|
|
else
|
|
printf "%*b" "-50" "Benchmark \"${sidecar##*/}\" average" "7" "${avg}" "" "\n\n" | sed 's/ /../g'
|
|
avgTable+=(["${sidecar}"]="$avg")
|
|
fi
|
|
done
|
|
|
|
printf "%*b" "-50" "Benchmark total" "7" "$(IFS=+; bc -l <<< "${total[*]}")" "" "\n\n" | sed 's/ /../g'
|
|
|
|
# Associative arrays don't return in alphanumerical order, must be sorted manually
|
|
IFS=$'\n' sorted=($(sort <<<"${!avgTable[*]}"));
|
|
|
|
printf "%s\n" "Average times for each set:"
|
|
for x in "${sorted[@]}"; do
|
|
printf "%*b" "-50" "${x}" "7" "${avgTable[$x]}" "" "\n" | sed 's/ /../g'
|
|
done
|