diff --git a/.gitignore b/.gitignore index 609777ae3ae95ca9fbb815beab4a9f2bbab562aa..cbef0f1540b7e0af86f51284794eb78cab722a0a 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,6 @@ srcGen/ main *.txt __pycache__/ -expr_*.c \ No newline at end of file +expr_*.c +run.log +includeTEST/mine.h \ No newline at end of file diff --git a/benchMark.txt b/benchMark.txt index c897202ed7ab71d7f66a1d7d1440525644c30bd2..6c2914aa6292350f861db7cc96dc18d9a226901d 100644 --- a/benchMark.txt +++ b/benchMark.txt @@ -13,11 +13,11 @@ NMSEexample38 (x+1)*log(x+1) - x*log(x) - 1 NMSEexample39 1/x - 1/tan(x) NMSEproblem331 1/(x+1) - 1/x NMSEproblem333 1/(1+x) - 2/x + 1/(x - 1) -NMSEproblem334 pow((x+1),1/3) - pow(x,1/3) +NMSEproblem334 pow((x+1.0),1.0/3.0) - pow(x,1.0/3.0) NMSEproblem336 log(x+1) - log(x) NMSEproblem337 exp(x) - 2+exp(-x) NMSEproblem341 (1 - cos(x))/(x*x) -NMSEproblem343 log((1 - eps)/(1+eps)) +NMSEproblem343 log((1 - x)/(1 + x)) NMSEproblem344 sqrt((exp(2*x) - 1)/(exp(x) - 1)) NMSEproblem345 (x - sin(x))/(x - tan(x)) NMSEsection311 exp(x)/(exp(x) - 1) diff --git a/benchMarkThreshold.txt b/benchMarkThreshold.txt deleted file mode 100644 index cd0b7e420a5c923ace6a3b89eae6d2e62100a5a4..0000000000000000000000000000000000000000 --- a/benchMarkThreshold.txt +++ /dev/null @@ -1,44 +0,0 @@ -0.8 -1 -1 -1 -10 -2 -2 -2.1 -1 -2 -0.5 -10 -5 -1 -1.5 -200 -1 -1 -2 -1 -2 -2 -2 -2 -1 -3 -0.6 -1.5 -1.2 -1.2 -2 -350,4 -1 -2.6 -2.5 -2.8 -3 -3 -3.2 -2.6 -2.6 -2.6 -2 -2 diff --git a/detectErrorOneFPEDParallel.sh b/detectErrorOneFPEDParallel.sh index 5d69f167d7392863f81c2ec572b67f043f8a44d4..d799fb35d8028bc89f600d7a9ca6e64dc273eb1d 100755 --- a/detectErrorOneFPEDParallel.sh +++ b/detectErrorOneFPEDParallel.sh @@ -1,4 +1,4 @@ -# Usage: ./detectErrorOneFPEDParallel.sh ${uniqueLabel} ${x0Start} ${x0End} ${x0Size} ${prefix} ${middle} ${suffix} +# Usage: ./detectErrorOneFPEDParallel.sh ${uniqueLabel} ${x0Start} ${x0End} ${x0Size} ${prefix} ${middle} ${suffix} ${errfile} # set -x path=`pwd` @@ -8,40 +8,54 @@ CC=mpicc uniqueLabel=${1} # unique number x0Start=${2} x0End=${3} -if [ $# -eq 7 ]; then +if [ $# -eq 8 ]; then x0Size=${4} prefix=${5} # expr_${uniqueLabel}. Eg: expr_20221030155958 middle=${6} # intervalsInfo_sizes. Eg: 3.8_7.8_500000 suffix=${7} # different version. Eg: herbie daisy origin temp_0_3 final + errfile=${8} # 1 or 0: TRUE or False +elif [ $# -eq 7 ]; then + x0Size=${4} + prefix=${5} # expr_${uniqueLabel}. Eg: expr_20221030155958 + middle=${6} # intervalsInfo_sizes. Eg: 3.8_7.8_500000 + suffix=${7} # different version. Eg: herbie daisy origin temp_0_3 final + errfile=0 elif [ $# -eq 6 ]; then x0Size=500000 prefix=${4} middle=${5} suffix=${6} + errfile=0 else echo "detectErrorOneFPEDParallel: Invalid input parameters" exit fi + testFileName=test1paramFPEDParallel numProcs=32 -# echo "Detecting error: ${uniqueLabel} ${x0Start} ${x0End} ${x0Size} ${prefix} ${middle} ${suffix}" +# echo "Detecting error: ${uniqueLabel} ${x0Start} ${x0End} ${x0Size} ${prefix} ${middle} ${suffix} ${errfile}" directory="./srcTest"/${uniqueLabel} -# echo "${CC} ${testFileName}.c ${prefix}_${suffix}.c ${prefix}_mpfr.c computeULP.c -IincludeTEST -DEXPRESSION=${prefix}_ -DSUFFIX=${suffix} -lmpfr -lm -O3 -o ${testFileName}.exe" -${CC} ./srcTest/${testFileName}.c ${directory}/${prefix}_${suffix}.c ${directory}/${prefix}_mpfr.c ./srcTest/computeULP.c -IincludeTEST -IincludeDD -DEXPRESSION=${prefix}_ -DSUFFIX=${suffix} -Llibs -lTGen -lmpfr -lm -lqd -o ${testFileName}.exe -# echo "mpirun -n ${numProcs} ./${testFileName}.exe ${x0Start} ${x0End} ${x0Size} ${prefix}__${middle}_${suffix}" -mpirun -n ${numProcs} ./${testFileName}.exe ${x0Start} ${x0End} ${x0Size} ${prefix}__${middle}_${suffix} ${uniqueLabel} -# mv outputs/${prefix}__${middle}_${suffix}_error.txt ./outputs/${uniqueLabel}/${prefix}__${middle}_${suffix}_error.txt +sourceFile=${prefix}_${suffix} +fileNameKernel=${prefix}__${middle}_${suffix} + +# echo "${CC} ${testFileName}.c ${sourceFile}.c ${prefix}_mpfr.c computeULP.c -IincludeTEST -DEXPRESSION=${prefix}_ -DSUFFIX=${suffix} -lmpfr -lm -O3 -o ${testFileName}.exe" +${CC} ./srcTest/${testFileName}.c ${directory}/${sourceFile}.c ${directory}/${prefix}_mpfr.c ./srcTest/computeULP.c -IincludeTEST -IincludeDD -DEXPRESSION=${prefix}_ -DSUFFIX=${suffix} -DERRFILE=${errfile} -Llibs -lTGen -lmpfr -lm -lqd -o ${testFileName}.exe +# echo "mpirun -n ${numProcs} ./${testFileName}.exe ${x0Start} ${x0End} ${x0Size} ${fileNameKernel}" +mpirun -n ${numProcs} ./${testFileName}.exe ${x0Start} ${x0End} ${x0Size} ${fileNameKernel} ${uniqueLabel} +# mv outputs/${fileNameKernel}_error.txt ./outputs/${uniqueLabel}/${fileNameKernel}_error.txt rm ${testFileName}.exe # combine files -cd ./outputs/${uniqueLabel} -findWord="${prefix}__${middle}_${suffix}_sample_*.txt" -# echo "For suffix = ${suffix}, Find and combine by shell command cat: ${findWord}" -find . -name "${findWord}" | sort -h | xargs cat > sample_${uniqueLabel}_${suffix}.txt -# echo "sample file: `pwd`/sample_${uniqueLabel}_${suffix}.txt" -rm ${findWord} -cd - > /dev/null +if [ ${errfile} -eq 1 ]; then + cd ./outputs/${uniqueLabel} + findWord="${fileNameKernel}_sample_*.txt" + # echo "For suffix = ${suffix}, Find and combine by shell command cat: ${findWord}" + find . -name "${findWord}" | sort -h | xargs cat > sample_${uniqueLabel}_${suffix}.txt + # echo "sample file: `pwd`/sample_${uniqueLabel}_${suffix}.txt" + rm ${findWord} + cd - > /dev/null +fi echo "end detecting error ${uniqueLabel}" echo diff --git a/detectErrorThreeFPEDParallel.sh b/detectErrorThreeFPEDParallel.sh index d90d24615bb6bfb981b19cc4652b70ac1507e2a3..acf2e5bfe77b05e7e6e4735096b66e4070be8f2c 100755 --- a/detectErrorThreeFPEDParallel.sh +++ b/detectErrorThreeFPEDParallel.sh @@ -1,4 +1,4 @@ -# Usage: ./detectErrorThreeParallel.sh ${uniqueLabel} ${x0Start} ${x0End} ${x1Start} ${x1End} ${x2Start} ${x2End} ${x0Size} ${x1Size} ${x2Size} ${prefix} ${middle} ${suffix} +# Usage: ./detectErrorThreeParallel.sh ${uniqueLabel} ${x0Start} ${x0End} ${x1Start} ${x1End} ${x2Start} ${x2End} ${x0Size} ${x1Size} ${x2Size} ${prefix} ${middle} ${suffix} ${errfile} # set -x path=`pwd` @@ -12,13 +12,22 @@ x1Start=${4} x1End=${5} x2Start=${6} x2End=${7} -if [ $# -eq 13 ]; then +if [ $# -eq 14 ]; then x0Size=${8} x1Size=${9} x2Size=${10} prefix=${11} # expr_${uniqueLabel}. Eg: expr_20221030155958 middle=${12} # intervalsInfo_sizes. Eg: 3.8_7.8_-4.5_-0.3_0.4_0.9_256_256_256 suffix=${13} # different version. Eg: herbie daisy origin temp_0_3 final + errfile=${14} # 1 or 0: TRUE or False +elif [ $# -eq 13 ]; then + x0Size=${8} + x1Size=${9} + x2Size=${10} + prefix=${11} # expr_${uniqueLabel}. Eg: expr_20221030155958 + middle=${12} # intervalsInfo_sizes. Eg: 3.8_7.8_-4.5_-0.3_0.4_0.9_256_256_256 + suffix=${13} # different version. Eg: herbie daisy origin temp_0_3 final + errfile=0 # 1 or 0: TRUE or False elif [ $# -eq 10 ]; then x0Size=256 x1Size=256 @@ -26,6 +35,7 @@ elif [ $# -eq 10 ]; then prefix=${8} middle=${9} suffix=${10} + errfile=0 # 1 or 0: TRUE or False else echo "detectErrorThreeParallel: Invalid input parameters" exit @@ -33,12 +43,27 @@ fi testFileName=test3paramFPEDParallel numProcs=32 -echo "Detecting error: ${uniqueLabel} ${x0Start} ${x0End} ${x1Start} ${x1End} ${x2Start} ${x2End} ${x0Size} ${x1Size} ${x2Size} ${prefix} ${middle} ${suffix}" +echo "Detecting error: ${uniqueLabel} ${x0Start} ${x0End} ${x1Start} ${x1End} ${x2Start} ${x2End} ${x0Size} ${x1Size} ${x2Size} ${prefix} ${middle} ${suffix} ${errfile}" directory="./srcTest"/${uniqueLabel} -# echo "${CC} ${testFileName}.c ${prefix}_${suffix}.c ${prefix}_mpfr.c computeULP.c -IincludeTEST -DEXPRESSION=${prefix}_ -DSUFFIX=${suffix} -lmpfr -lm -O3 -o ${testFileName}.exe" -${CC} ./srcTest/${testFileName}.c ${directory}/${prefix}_${suffix}.c ${directory}/${prefix}_mpfr.c ./srcTest/computeULP.c -IincludeTEST -IincludeDD -DEXPRESSION=${prefix}_ -DSUFFIX=${suffix} -lmpfr -lm -lqd -o ${testFileName}.exe -# echo "mpirun -n ${numProcs} ./${testFileName}.exe ${x0Start} ${x0End} ${x1Start} ${x1End} ${x2Start} ${x2End} ${x0Size} ${x1Size} ${x2Size} ${prefix}__${middle}_${suffix}" -mpirun -n ${numProcs} ./${testFileName}.exe ${x0Start} ${x0End} ${x1Start} ${x1End} ${x2Start} ${x2End} ${x0Size} ${x1Size} ${x2Size} ${prefix}__${middle}_${suffix} ${uniqueLabel} +sourceFile=${prefix}_${suffix} +fileNameKernel=${prefix}__${middle}_${suffix} + +# echo "${CC} ${testFileName}.c ${sourceFile}.c ${prefix}_mpfr.c computeULP.c -IincludeTEST -DEXPRESSION=${prefix}_ -DSUFFIX=${suffix} -lmpfr -lm -O3 -o ${testFileName}.exe" +${CC} ./srcTest/${testFileName}.c ${directory}/${sourceFile}.c ${directory}/${prefix}_mpfr.c ./srcTest/computeULP.c -IincludeTEST -IincludeDD -DEXPRESSION=${prefix}_ -DSUFFIX=${suffix} -DERRFILE=${errfile} -Llibs -lTGen -lmpfr -lm -lqd -o ${testFileName}.exe +# echo "mpirun -n ${numProcs} ./${testFileName}.exe ${x0Start} ${x0End} ${x1Start} ${x1End} ${x2Start} ${x2End} ${x0Size} ${x1Size} ${x2Size} ${fileNameKernel}" +mpirun -n ${numProcs} ./${testFileName}.exe ${x0Start} ${x0End} ${x1Start} ${x1End} ${x2Start} ${x2End} ${x0Size} ${x1Size} ${x2Size} ${fileNameKernel} ${uniqueLabel} rm ${testFileName}.exe + +# combine files +if [ ${errfile} -eq 1 ]; then + cd ./outputs/${uniqueLabel} + findWord="${fileNameKernel}_sample_*.txt" + # echo "For suffix = ${suffix}, Find and combine by shell command cat: ${findWord}" + find . -name "${findWord}" | sort -h | xargs cat > sample_${uniqueLabel}_${suffix}.txt + # echo "sample file: `pwd`/sample_${uniqueLabel}_${suffix}.txt" + rm ${findWord} + cd - > /dev/null +fi + echo "end detecting ${uniqueLabel}" echo diff --git a/detectErrorTwoFPEDParallel.sh b/detectErrorTwoFPEDParallel.sh index dcb50691049e8411c0aeacca75ff33bd32fe5d06..29ee6cbdf4396dfc8d48a906adab144838a57949 100755 --- a/detectErrorTwoFPEDParallel.sh +++ b/detectErrorTwoFPEDParallel.sh @@ -1,4 +1,4 @@ -# Usage: ./detectErrorTwoFPEDParallel.sh ${uniqueLabel} ${x0Start} ${x0End} ${x1Start} ${x1End} ${x0Size} ${x1Size} ${prefix} ${middle} ${suffix} +# Usage: ./detectErrorTwoFPEDParallel.sh ${uniqueLabel} ${x0Start} ${x0End} ${x1Start} ${x1End} ${x0Size} ${x1Size} ${prefix} ${middle} ${suffix} ${errfile} # set -x path=`pwd` @@ -11,18 +11,27 @@ x0End=${3} x1Start=${4} x1End=${5} -if [ $# -eq 10 ]; then +if [ $# -eq 11 ]; then x0Size=${6} x1Size=${7} prefix=${8} # expr_${uniqueLabel}. Eg: expr_20221030155958 middle=${9} # intervalsInfo_sizes. Eg: 3.8_7.8_-4.5_-0.3_0.4_0.9_256_256_256 suffix=${10} # different version. Eg: herbie daisy origin temp_0_3 final + errfile=${11} # 1 or 0: TRUE or False +elif [ $# -eq 10 ]; then + x0Size=${6} + x1Size=${7} + prefix=${8} # expr_${uniqueLabel}. Eg: expr_20221030155958 + middle=${9} # intervalsInfo_sizes. Eg: 3.8_7.8_-4.5_-0.3_0.4_0.9_256_256_256 + suffix=${10} # different version. Eg: herbie daisy origin temp_0_3 final + errfile=0 # 1 or 0: TRUE or False elif [ $# -eq 8 ]; then x0Size=1024 x1Size=1024 prefix=${6} middle=${7} suffix=${8} + errfile=0 # 1 or 0: TRUE or False else echo "detectErrorTwoFPEDParallel: Invalid input parameters" exit @@ -31,13 +40,29 @@ fi testFileName=test2paramFPEDParallel numProcs=32 -echo "Detecting error: ${uniqueLabel} ${x0Start} ${x0End} ${x1Start} ${x1End} ${x0Size} ${x1Size} ${prefix} ${middle} ${suffix}" +echo "Detecting error: ${uniqueLabel} ${x0Start} ${x0End} ${x1Start} ${x1End} ${x0Size} ${x1Size} ${prefix} ${middle} ${suffix} ${errfile}" directory="./srcTest"/${uniqueLabel} -# echo "${CC} ${testFileName}.c ${prefix}_${suffix}.c ${prefix}_mpfr.c computeULP.c -IincludeTEST -DEXPRESSION=${prefix}_ -DSUFFIX=${suffix} -lmpfr -lm -O3 -o ${testFileName}.exe" -${CC} ./srcTest/${testFileName}.c ${directory}/${prefix}_${suffix}.c ${directory}/${prefix}_mpfr.c ./srcTest/computeULP.c -IincludeTEST -IincludeDD -DEXPRESSION=${prefix}_ -DSUFFIX=${suffix} -lmpfr -lm -lqd -o ${testFileName}.exe -# echo "mpirun -n ${numProcs} ./${testFileName}.exe ${x0Start} ${x0End} ${x1Start} ${x1End} ${x2Start} ${x2End} ${x0Size} ${x1Size} ${x2Size} ${prefix}__${middle}_${suffix}" -mpirun -n ${numProcs} ./${testFileName}.exe ${x0Start} ${x0End} ${x1Start} ${x1End} ${x0Size} ${x1Size} ${prefix}__${middle}_${suffix} ${uniqueLabel} +suffixClean=`echo ${suffix} | sed 's@_x\|_y\|_z@@g'` +sourceFile=${prefix}_${suffixClean} +fileNameKernel=${prefix}__${middle}_${suffix} +# echo "${CC} ${testFileName}.c ${sourceFile}.c ${prefix}_mpfr.c computeULP.c -IincludeTEST -DEXPRESSION=${prefix}_ -DSUFFIX=${suffix} -lmpfr -lm -O3 -o ${testFileName}.exe" +${CC} ./srcTest/${testFileName}.c ${directory}/${sourceFile}.c ${directory}/${prefix}_mpfr.c ./srcTest/computeULP.c -IincludeTEST -IincludeDD -DEXPRESSION=${prefix}_ -DSUFFIX=${suffixClean} -DERRFILE=${errfile} -Llibs -lTGen -lmpfr -lm -lqd -o ${testFileName}.exe +# echo "mpirun -n ${numProcs} ./${testFileName}.exe ${x0Start} ${x0End} ${x1Start} ${x1End} ${x2Start} ${x2End} ${x0Size} ${x1Size} ${x2Size} ${fileNameKernel}" +mpirun -n ${numProcs} ./${testFileName}.exe ${x0Start} ${x0End} ${x1Start} ${x1End} ${x0Size} ${x1Size} ${fileNameKernel} ${uniqueLabel} rm ${testFileName}.exe + +# TODO: 进一步配适多参采样测试 +# combine files +if [ ${errfile} -eq 1 ]; then + cd ./outputs/${uniqueLabel} + findWord="${fileNameKernel}_sample_*.txt" + # echo "For suffix = ${suffix}, Find and combine by shell command cat: ${findWord}" + find . -name "${findWord}" | sort -h | xargs cat > sample_${uniqueLabel}_${suffix}.txt + # echo "sample file: `pwd`/sample_${uniqueLabel}_${suffix}.txt" + rm ${findWord} + cd - > /dev/null +fi + echo "end detecting ${uniqueLabel}" echo diff --git a/include/basic.hpp b/include/basic.hpp index e665a42ba82480882a77dfa8a89d39590c01972d..430e465514a2f27fe1f20555c7707f8154b01a45 100644 --- a/include/basic.hpp +++ b/include/basic.hpp @@ -244,6 +244,8 @@ vector> combination(const int num, const vector& indexs); size_t combination(size_t k, size_t n); +void write_to_file(const string &uniqueLabel, const std::vector &data, const std::string &filename); + // } // end anonymous namespace #endif \ No newline at end of file diff --git a/include/tools.hpp b/include/tools.hpp index e71a315df5449ad50c4ad1a284b2cfe7298cb81e..3b7355ee5afa3c8d982934984da6b6f22b794aa9 100644 --- a/include/tools.hpp +++ b/include/tools.hpp @@ -28,7 +28,9 @@ vector getIntervals(string interval, const char *split); vector getScales(string scale, const char *split); -exprInfo testError(string uniqueLabel, string suffix, const vector &intervals, const vector &scales); +void sampleError(string uniqueLabel, string suffix, const vector &intervals, const vector &scales); + +exprInfo testError(string uniqueLabel, string suffix, const vector &intervals, const vector &scales, bool errfile = false); exprInfo testError(string uniqueLabel, string suffix, double x0Start, double x0End, int scale); @@ -38,15 +40,17 @@ exprInfo testError(string uniqueLabel, string suffix, double x0Start, double x0E double testPerformance(string uniqueLabel, string suffix, const vector &intervals); -string geneBoundaryData(string uniqueLabel, string suffix); +string geneBoundaryData(string uniqueLabel, string suffix, double &costTime); + +vector geneBoundaryData(string uniqueLabel, string suffix, vector suffixes, double &costTime); vector geneIntervalData(vector upEdgeFileNames, string uniqueLabel, vector &thresholds); vector> getIntervalData(string filename); -vector> getIntervalData(vector upEdgeFileNames, vector &thresholds); +vector> getIntervalData(vector upEdgeFileNames, vector &thresholds, vector &intervals); -vector rewrite(string exprStr, string uniqueLabel, vector> &intervalData); +vector rewrite(string exprStr, string uniqueLabel, vector> &intervalData, int &numOfExprs); vector> permuteMultiVec(vector> vec); diff --git a/sampleErrorThree.sh b/sampleErrorThree.sh new file mode 100755 index 0000000000000000000000000000000000000000..6ccf3a17aa3f40d1fa754f4ee670484d1ade51ec --- /dev/null +++ b/sampleErrorThree.sh @@ -0,0 +1,66 @@ +#!/bin/bash +# Usage: ./sampleTwoFPEDParallel.sh ${uniqueLabel} ${x0Start} ${x0End} ${x1Start} ${x1End} ${x0Size} ${x1Size} ${prefix} ${middle} ${suffix} +# set -x + +path=`pwd` +cd ${path} +CC=mpicc + +uniqueLabel=${1} # unique number +x0Start=${2} +x0End=${3} +x1Start=${4} +x1End=${5} +x2Start=${6} +x2End=${7} + +if [ $# -eq 12 ]; then + drawNum=${8} + findMaxNum=${9} + prefix=${10} # expr_${uniqueLabel}. Eg: expr_20221030155958 + middle=${11} # intervalsInfo_sizes. Eg: 3.8_7.8_-4.5_-0.3_0.4_0.9_256_256_256 + suffix=${12} # different version. Eg: herbie daisy origin temp_0_3 final +elif [ $# -eq 10 ]; then + drawNum=512 + findMaxNum=128 + prefix=${8} + middle=${9} + suffix=${10} +else + echo "sampleThreeFPEDParallel: Invalid input parameters" + exit +fi + +testFileName=sample3paramFPEDParallel +numProcs=32 + +# echo "sampling: ${uniqueLabel} ${x0Start} ${x0End} ${x1Start} ${x1End} ${x2Start} ${x2End} ${drawNum} ${findMaxNum} ${prefix} ${middle} ${suffix} ${errfile}" +directory="./srcTest"/${uniqueLabel} +sourceFile=${prefix}_${suffix} +fileNameKernel=${prefix}__${middle}_${suffix} + +${CC} ./srcTest/${testFileName}.c ${directory}/${sourceFile}.c ${directory}/${prefix}_mpfr.c ./srcTest/computeULP.c -IincludeTEST -IincludeDD -DEXPRESSION=${prefix}_ -DSUFFIX=${suffix} -Llibs -lTGen -lmpfr -lm -lqd -o ${testFileName}.exe +mpirun -n ${numProcs} ./${testFileName}.exe ${x0Start} ${x0End} ${x1Start} ${x1End} ${x2Start} ${x2End} ${drawNum} ${findMaxNum} ${fileNameKernel} ${uniqueLabel} +rm ${testFileName}.exe + +# combine files +cd ./outputs/${uniqueLabel} +## for sample_X +findWord="${fileNameKernel}_sample_X_*.txt" +# echo "For suffix = ${suffix}, Find and combine by shell command cat: ${findWord}" +find . -name "${findWord}" | sort -h | xargs cat > sample_${uniqueLabel}_${suffix}_X.txt +rm ${findWord} +## for sample_Y +findWord="${fileNameKernel}_sample_Y_*.txt" +# echo "For suffix = ${suffix}, Find and combine by shell command cat: ${findWord}" +find . -name "${findWord}" | sort -h | xargs cat > sample_${uniqueLabel}_${suffix}_Y.txt +rm ${findWord} +## for sample_Z +findWord="${fileNameKernel}_sample_Z_*.txt" +# echo "For suffix = ${suffix}, Find and combine by shell command cat: ${findWord}" +find . -name "${findWord}" | sort -h | xargs cat > sample_${uniqueLabel}_${suffix}_Z.txt +rm ${findWord} +cd - > /dev/null + +# echo "end sampling ${uniqueLabel}" +echo diff --git a/sampleErrorTwo.sh b/sampleErrorTwo.sh new file mode 100755 index 0000000000000000000000000000000000000000..ee45efa31d835404c747dc0ee34d9797bca8a19b --- /dev/null +++ b/sampleErrorTwo.sh @@ -0,0 +1,59 @@ +#!/bin/bash +# Usage: ./sampleTwoFPEDParallel.sh ${uniqueLabel} ${x0Start} ${x0End} ${x1Start} ${x1End} ${x0Size} ${x1Size} ${prefix} ${middle} ${suffix} +# set -x + +path=`pwd` +cd ${path} +CC=mpicc + +uniqueLabel=${1} # unique number +x0Start=${2} +x0End=${3} +x1Start=${4} +x1End=${5} + +if [ $# -eq 10 ]; then + drawNum=${6} + findMaxNum=${7} + prefix=${8} # expr_${uniqueLabel}. Eg: expr_20221030155958 + middle=${9} # intervalsInfo_sizes. Eg: 3.8_7.8_-4.5_-0.3_0.4_0.9_256_256_256 + suffix=${10} # different version. Eg: herbie daisy origin temp_0_3 final +elif [ $# -eq 8 ]; then + drawNum=8192 + findMaxNum=2048 + prefix=${6} + middle=${7} + suffix=${8} +else + echo "sampleTwoFPEDParallel: Invalid input parameters" + exit +fi + +testFileName=sample2paramFPEDParallel +numProcs=32 + +# echo "sampling: ${uniqueLabel} ${x0Start} ${x0End} ${x1Start} ${x1End} ${drawNum} ${findMaxNum} ${prefix} ${middle} ${suffix} ${errfile}" +directory="./srcTest"/${uniqueLabel} +sourceFile=${prefix}_${suffix} +fileNameKernel=${prefix}__${middle}_${suffix} + +${CC} ./srcTest/${testFileName}.c ${directory}/${sourceFile}.c ${directory}/${prefix}_mpfr.c ./srcTest/computeULP.c -IincludeTEST -IincludeDD -DEXPRESSION=${prefix}_ -DSUFFIX=${suffix} -Llibs -lTGen -lmpfr -lm -lqd -o ${testFileName}.exe +mpirun -n ${numProcs} ./${testFileName}.exe ${x0Start} ${x0End} ${x1Start} ${x1End} ${drawNum} ${findMaxNum} ${fileNameKernel} ${uniqueLabel} +rm ${testFileName}.exe + +# combine files +cd ./outputs/${uniqueLabel} +## for sample_X +findWord="${fileNameKernel}_sample_X_*.txt" +# echo "For suffix = ${suffix}, Find and combine by shell command cat: ${findWord}" +find . -name "${findWord}" | sort -h | xargs cat > sample_${uniqueLabel}_${suffix}_X.txt +rm ${findWord} +## for sample_Y +findWord="${fileNameKernel}_sample_Y_*.txt" +# echo "For suffix = ${suffix}, Find and combine by shell command cat: ${findWord}" +find . -name "${findWord}" | sort -h | xargs cat > sample_${uniqueLabel}_${suffix}_Y.txt +rm ${findWord} +cd - > /dev/null + +# echo "end sampling ${uniqueLabel}" +echo diff --git a/src/basic.cpp b/src/basic.cpp index 6b7a408de8aa686d643269ba61bc03d152c215dc..8149d6d18888331c3fbbaf87294fd3ac24a76ee1 100644 --- a/src/basic.cpp +++ b/src/basic.cpp @@ -739,4 +739,27 @@ size_t combination(size_t k, size_t n) return 0; } return factorial(n) / (factorial(k) * factorial(n - k)); -} \ No newline at end of file +} + +void write_to_file(const string &uniqueLabel, const std::vector &data, const std::string &filename) +{ + std::ofstream outputFile; + outputFile.open(filename, std::ios::out | std::ios::app); + + if (outputFile.is_open()) + { + outputFile << uniqueLabel << ", "; + for (const auto &val : data) + { + outputFile << val << ", "; + } + outputFile << std::endl; + outputFile.close(); + + // std::cout << "Successfully written data to file!" << std::endl; + } + // else + // { + // std::cout << "Failed to open file!" << std::endl; + // } +} diff --git a/src/devideUpEdgeData.cpp b/src/devideUpEdgeData.cpp index 2e5827a9d0023aa9966588358ffa3668776ee872..0f0cd829503e57ae828310a18305d8f0f38ffc06 100644 --- a/src/devideUpEdgeData.cpp +++ b/src/devideUpEdgeData.cpp @@ -18,7 +18,7 @@ int read_scanf(const string &filename, const int &cols, vector &_vecto bool flag = true; double tmp; if (!fp) { - cout << "File open error!\n"; + cout << "ERROR: read_scanf: File " << filename << " open error!\n"; return 0; } while (flag) { diff --git a/src/exprAuto.cpp b/src/exprAuto.cpp index b38e4cf14d3220a98cfeae9db1808e4a8996e36c..2a43619c9f94eadeee5849b5244f191f7b13511c 100644 --- a/src/exprAuto.cpp +++ b/src/exprAuto.cpp @@ -1014,13 +1014,18 @@ exprInfo pickTheBest(string uniqueLabel, vector testSet, vector string bestExpr = "origin"; double maxError = INFINITY; double aveError = INFINITY; + bool isSingleParam = true; + if (scales.size() > 1) + { + isSingleParam = false; + } for (size_t i = 0; i < testSet.size(); i++) { string suffixTmp = testSet.at(i); cout << "*-*-*-pickTheBest: for item No." << i << ": type = " << suffixTmp << endl; // generate function code and test error - auto tempError = testError(uniqueLabel, suffixTmp, intervals, scales); + auto tempError = testError(uniqueLabel, suffixTmp, intervals, scales, isSingleParam); // cout << "pickTheBest: for item No." << i << ": maxError: " << tempError.maxError << "\n"; // cout << "pickTheBest: for item No." << i << ": aveError: " << tempError.aveError << "\n"; @@ -1332,16 +1337,16 @@ vector exprAutoNew(const ast_ptr &expr, bool addSelf) } else { - ast_ptr one = makePtr(1.0); + // ast_ptr one = makePtr(1.0); NumberExprAST *numberPtr = dynamic_cast(denominators.at(0).get()); ast_ptr denominatorTmp = makePtr(numberPtr->getNumber()); - auto coefficient = divExpr(one, denominatorTmp); + // auto coefficient = divExpr(one, denominatorTmp); for(const auto& numerator : numerators) { - auto tmp1 = mulExpr(coefficient, numerator); + // auto tmp1 = mulExpr(coefficient, numerator); auto tmp2 = divExpr(numerator, denominatorTmp); - results.push_back(std::move(tmp1)); + // results.push_back(std::move(tmp1)); results.push_back(std::move(tmp2)); } } @@ -1448,6 +1453,7 @@ vector exprAutoWrapper(ast_ptr &expr, const std::vector &interv { sortExpr(result); } + results.push_back(expr->Clone()); deleteTheSame(results); cout << YELLOW << "-------------------------------------final results-------------------------------------" << RESET << endl; diff --git a/src/geneCode.cpp b/src/geneCode.cpp index ab5f001c8289d85811c4ee2eb3fca463c719552d..9e9a6f2a03e19142a15f8f010e844e9ac1cec18f 100644 --- a/src/geneCode.cpp +++ b/src/geneCode.cpp @@ -247,28 +247,47 @@ string geneHerbieCode(string uniqueLabel) {"NMSEexample310", "log1p(-x) / log1p(x)"}, {"NMSEexample34", "tan((x / 2.0))"}, {"NMSEexample35", "atan2((x + (1.0- x)), (1.0+fma(sqrt(x), sqrt(x), (x * x))))"}, - {"NMSEexample36", ""}, + {"NMSEexample36", "1.0 / ((x * (pow(x, -0.5) + pow((1.0 + x), -0.5))) + (x * (x * fma(pow(x, -0.25), pow(x, -0.25), pow((1.0 + x), -0.5)))))"}, {"NMSEexample37", "expm1(x)"}, {"NMSEexample38", "fma(x, log((1.0 + (1.0 / x))), log1p(x)) + -1.0"}, - {"NMSEexample39", ""}, + {"NMSEexample39", ""}, // if else {"NMSEproblem331", "-1.0 / fma(x, x, x)"}, {"NMSEproblem333", "((1.0 / (x + -1.0)) + (1.0 / (1.0 + x))) + (-2.0 / x)"}, - {"NMSEproblem334", ""}, + {"NMSEproblem334", "((x + 1.0) - x) / (pow(cbrt((x + 1.0)), 2.0) + (fma((x + 1.0), cbrt(x), (x * cbrt(x))) / (pow(cbrt((x + 1.0)), 2.0) + (cbrt(x) * (cbrt(x) - cbrt((x + 1.0)))))))"}, {"NMSEproblem336", "log1p((1.0 / x))"}, - {"NMSEproblem337", ""}, + {"NMSEproblem337", ""}, // if else {"NMSEproblem341", "(sin(x) / x) * (tan((x / 2.0)) / x)"}, - {"NMSEproblem343", ""}, + {"NMSEproblem343", "log1p(-x) - log1p(x)"}, {"NMSEproblem344", "sqrt((1.0 + exp(x)))"}, - {"NMSEproblem345", ""}, + {"NMSEproblem345", ""}, // if else {"NMSEsection311", "(1.0 + expm1(x)) / expm1(x)"}, - {"predatorPrey", ""}, - {"sine", ""}, - {"sineorder3", ""}, - {"sqroot", ""}, - {"sqrt_add", ""}, - {"test05_nonlin1_r4", ""}, - {"test05_nonlin1_test2", ""}, - {"verhulst", ""}, + {"predatorPrey", ""}, // x * ((x * 4.0) * exp(-log1p(sqrt(pow((x * 0.9009009009009009), 4.0))))) + {"sine", ""}, // x - fma(0.0001984126984126984, pow(x, 7.0), fma(0.16666666666666666, pow(x, 3.0), (-0.008333333333333333 * pow(x, 5.0)))) // this one can not rewrite well, so arfa will use origin + {"sineorder3", ""}, // fma(x, 0.954929658551372, (pow(x, 3.0) * -0.12900613773279798)) // this one can not rewrite well, so arfa will use origin + {"sqroot", ""}, // fma(x, (0.5 + (x * fma(x, fma(x, -0.0390625, 0.0625), -0.125))), 1.0) // this one can not rewrite well, so arfa will use origin + {"sqrt_add", "1.0 / (sqrt((1.0 + x)) + sqrt(x))"}, + {"test05_nonlin1_r4", ""}, // exp(-log1p(x)) // this one can not rewrite well, so arfa will use origin + {"test05_nonlin1_test2", ""}, // exp(-log1p(x)) // this one can not rewrite well, so arfa will use origin + {"verhulst", ""}, // pow(log1p(expm1((64.0 * pow((x / fma(x, 0.9009009009009009, 1.0)), 3.0)))), 0.3333333333333333); // this one can not rewrite well, so arfa will use origin + {"ComplexSinCos", ""}, + {"ComplexSquareRoot", ""}, + {"doppler1", ""}, + {"doppler2", ""}, + {"doppler3", ""}, + {"hypot32", ""}, + {"i4", ""}, + {"i6", ""}, + {"NMSEexample33", ""}, + {"NMSEproblem332", ""}, + {"NMSEproblem335", ""}, + {"NMSEproblem346", ""}, + {"NMSEsection35", ""}, + {"polarToCarthesianX", ""}, + {"polarToCarthesianY", ""}, + {"sec4example", ""}, + {"test03_nonlin2", ""}, + {"theta", ""}, + {"turbine1", ""}, }; auto pos = benchmarkHerbie.find(uniqueLabel); @@ -278,15 +297,15 @@ string geneHerbieCode(string uniqueLabel) if(herbieExpr != "") { geneExprCode(herbieExpr, uniqueLabel, "herbie"); - return herbieExpr; } else { - fprintf(stderr, "ERROR: geneHerbieCode: we can not handle %s\n", uniqueLabel.c_str()); - exit(EXIT_FAILURE); + fprintf(stderr, "ERROR: geneHerbieCode: herbie's rewrite result for %s can not be used.\n", uniqueLabel.c_str()); + // TODO: just write the if-else result to file. } + return herbieExpr; } - fprintf(stderr, "ERROR: geneHerbieCode: we can not handle %s\n", uniqueLabel.c_str()); + fprintf(stderr, "ERROR: geneHerbieCode: we can not support %s now\n", uniqueLabel.c_str()); exit(EXIT_FAILURE); } @@ -310,8 +329,10 @@ string geneMpfrCode(const ast_ptr &exprAst, const string uniqueLabel, vector\n"; - fout << "double " << funcName << "("; + fout << "#include \"mine.h\"\n"; + stringstream ss, ss1; for (size_t i = 0; i < vars.size(); ++i) { if (i != vars.size() - 1) - fout << "double" << " " << vars.at(i) << ", "; + { + ss << "double" << " " << vars.at(i) << ", "; + ss1 << vars.at(i) << ", "; + } else - fout << "double" << " " << vars.at(i); + { + ss << "double" << " " << vars.at(i); + ss1 << vars.at(i); + } } - fout << ") {\n"; + const string ¶mListWithType = ss.str(); + const string ¶mListNoType = ss1.str(); + + // function main body + fout << "double expr_" << uniqueLabel << "_final(" << paramListWithType << ") {\n"; fout << " double result;\n"; // function body @@ -423,7 +457,16 @@ string geneFinalCodeKernel(string exprStr, string uniqueLabel, std::vector interval = exprInfoVector.at(i).intervals; - string &exprStr = exprInfoVector.at(i).exprStr; + string exprStr; + if(exprInfoVector.at(i).exprStr == "mpfr") + { + exprStr = "expr_" + uniqueLabel + "_mpfr1(" + paramListNoType + ")"; + flagMPFR = true; + } + else + { + exprStr = exprInfoVector.at(i).exprStr; + } // generate if statement if (i == 0) { @@ -458,6 +501,34 @@ string geneFinalCodeKernel(string exprStr, string uniqueLabel, std::vector\n"; + // reference to mpfr version + if(flagMPFR) + { + fout << "#include \n"; + fout << "int expr_" << uniqueLabel << "_mpfr(" << paramListWithType << ", mpfr_t mpfrResult);\n"; + // write expr_uniqueLable_mpfr1 + fout << "double expr_" << uniqueLabel << "_mpfr1(" << paramListWithType << ")\n"; + fout << "{\n"; + fout << " mpfr_t mpfrResult;\n"; + fout << " mpfr_init2(mpfrResult, 128);\n"; + fout << " expr_" << uniqueLabel << "_mpfr(" << paramListNoType << ", mpfrResult);\n"; + fout << " double result = mpfr_get_d(mpfrResult, MPFR_RNDN);\n"; + fout << " return result;\n"; + fout << "}\n"; + } + fout << std::flush; + fout.close(); + cout << "&&&&&&&&&&&&&&&&&&&&&&& geneFinalCode &&&&&&&&&&&&&&&&&&&&&&&&&&&&\n" << endl; return funcName; diff --git a/src/getUpEdge.m b/src/getUpEdge.m index 31633ee58590ce7d493c4010877588a73e483aba..984076acb77c44a571489ead89e9304add6a86df 100644 --- a/src/getUpEdge.m +++ b/src/getUpEdge.m @@ -1,102 +1,41 @@ -% disp(sampleFileName); tic; -sampleData = importdata(sampleFileName); -lenTmp = length(sampleData); -maxTmp = max(sampleData(:,2)); -maxIndex = find(sampleData(:,2)>=maxTmp); -meanTmp = mean(sampleData(:,2)); -upperTmp = (maxTmp + meanTmp) / 10; -domainTmp = 0.01; -leftTmp = int64(max(1, maxIndex - lenTmp * domainTmp * 0.5)); -rightTmp = int64(min(lenTmp, maxIndex + lenTmp * domainTmp * 0.5)); +sampleFiles = strcat(outputFilesPath, sampleFileNameKernel); +namelist = dir(sampleFiles); +fileNum = length(namelist); +regexTemplate = '(?<=sample_).*?(?=.txt)'; -for j = 1:1 % 右端点需要更正为maxIndex的长度 - leftTmp(j) = int64(max(1, maxIndex(j) - lenTmp * domainTmp * 0.5)); - rightTmp(j) = int64(min(lenTmp, maxIndex(j) + lenTmp * domainTmp * 0.5)); - localTmp = find(sampleData(leftTmp(j):rightTmp(j),2) > upperTmp); - wholeTmp = find(sampleData(:,2) > upperTmp); - rateTmp = length(localTmp) / length(wholeTmp); - edgeIndex = boundary(sampleData(:,1), sampleData(:,2), 1.0); - edge = [edgeIndex, sampleData(edgeIndex,1), sampleData(edgeIndex,2)]; - - % simple way - % upEdgeIndex = edge(:,3)>=2; - % upEdge = edge(upEdgeIndex,:); +for i = 1 : fileNum + fileNameTmp = strcat(outputFilesPath, namelist(i).name); + sampleData = importdata(fileNameTmp); - % upEdge: tradional way - edge = flipud(edge); % 水平轴上下翻转数组 - if isempty(edge) - fprintf("\tedge is empty!\n"); - break; - end - upEdgeStart = 1; - upEdgeEnd = length(edge); - edgeTmp = edge; - thresholdTrash = 5; - minEdgeInput = min(edgeTmp(:,2)); % 记录的是误差对应的输入 - maxEdgeInput = max(edgeTmp(:,2)); % 记录的是误差对应的输入 - - threshold = 2; - edgeTmp(edge(:,3) thresholdTrash) - upEdgeStart = max(1,k-1-thresholdTrash); - break - end - else - trash = 0; - end - end - % ready for upEdge's tail - trash = 0; - for k = length(edgeTmp):-1:1 - if(edgeTmp(k,2) == maxEdgeInput) - upEdgeEnd = min(k, length(edgeTmp)); - break - end - if(edgeTmp(k,end) ~= threshold) - trash = trash + 1; - if(trash > thresholdTrash) - upEdgeEnd = min(k+1+thresholdTrash, length(edgeTmp)); - break - end - else - trash = 0; - end - end - % after getting head & tail, we get upEdge - upEdge = edge(upEdgeStart:upEdgeEnd,:); % upEdge是保留了上半段轮廓线中小于阈值的部分 - - if rateTmp > 0.5 % 做判断是因为rateTmp大于0.5即说明其图形unstable,出现了畸变 - % fprintf("%s is unstable, rate = %g, maxError = %g\n", sampleFileName, rateTmp, maxTmp); - % draw pic and save pic - % figure(1); - % scatter(sampleData(:,1), sampleData(:,2), '.'); - % hold on; plot(edge(:,2), edge(:,3), '-r', 'LineWidth', 1); hold off; - % set(gca, 'Fontname', 'Times newman', 'Fontsize', 55); - % nameTmp = strcat("unstable_scatterEdge_", sampleFileName); - % % title(nameTmp, 'Interpreter', 'none'); - % % grid on; - % img =gcf; print(img, '-djpeg', '-r100', nameTmp); - - % update boundary error to [2, 10]。这一段其实可以放到前边去 - radio = (maxTmp - 2) / 8; - indexTmp = sampleData(:,2) >= 2; - sampleData(indexTmp, 2) = (sampleData(indexTmp,2) - 2) / radio + 2; - maxTmp = max(sampleData(indexTmp,2)); + strTmp = regexp(fileNameTmp, regexTemplate, 'match'); + sampleDataNameTmp = strTmp{1,1}; + upEdgeFileName = strcat(outputFilesPath, "upEdge_", sampleDataNameTmp, ".txt"); + + lenTmp = length(sampleData); + maxTmp = max(sampleData(:,2)); + maxIndex = find(sampleData(:,2)>=maxTmp); + meanTmp = mean(sampleData(:,2)); + upperTmp = (maxTmp + meanTmp) / 10; + domainTmp = 0.01; + leftTmp = int64(max(1, maxIndex - lenTmp * domainTmp * 0.5)); + rightTmp = int64(min(lenTmp, maxIndex + lenTmp * domainTmp * 0.5)); + + for j = 1:1 % 右端点需要更正为maxIndex的长度 + leftTmp(j) = int64(max(1, maxIndex(j) - lenTmp * domainTmp * 0.5)); + rightTmp(j) = int64(min(lenTmp, maxIndex(j) + lenTmp * domainTmp * 0.5)); + localTmp = find(sampleData(leftTmp(j):rightTmp(j),2) > upperTmp); + wholeTmp = find(sampleData(:,2) > upperTmp); + rateTmp = length(localTmp) / length(wholeTmp); edgeIndex = boundary(sampleData(:,1), sampleData(:,2), 1.0); edge = [edgeIndex, sampleData(edgeIndex,1), sampleData(edgeIndex,2)]; + save(upEdgeFileName, 'edge', '-ascii', '-double'); % the 2nd parameter mean the data to save to file + % simple way + % upEdgeIndex = edge(:,3)>=2; + % upEdge = edge(upEdgeIndex,:); % upEdge: tradional way - edge = flipud(edge); + edge = flipud(edge); % 水平轴上下翻转数组 if isempty(edge) fprintf("\tedge is empty!\n"); break; @@ -105,19 +44,19 @@ for j = 1:1 % 右端点需要更正为maxIndex的长度 upEdgeEnd = length(edge); edgeTmp = edge; thresholdTrash = 5; - minEdgeInput = min(edgeTmp(:,2)); - maxEdgeInput = max(edgeTmp(:,2)); + minEdgeInput = min(edgeTmp(:,2)); % 记录的是误差对应的输入 + maxEdgeInput = max(edgeTmp(:,2)); % 记录的是误差对应的输入 threshold = 2; - edgeTmp(edge(:,3) thresholdTrash) upEdgeStart = max(1,k-1-thresholdTrash); @@ -127,7 +66,7 @@ for j = 1:1 % 右端点需要更正为maxIndex的长度 trash = 0; end end - % tail + % ready for upEdge's tail trash = 0; for k = length(edgeTmp):-1:1 if(edgeTmp(k,2) == maxEdgeInput) @@ -144,50 +83,124 @@ for j = 1:1 % 右端点需要更正为maxIndex的长度 trash = 0; end end - % after head & tail + % after getting head & tail, we get upEdge upEdge = edge(upEdgeStart:upEdgeEnd,:); % upEdge是保留了上半段轮廓线中小于阈值的部分 + + if rateTmp > 0.5 % 做判断是因为rateTmp大于0.5即说明其图形unstable,出现了畸变 + % fprintf("%s is unstable, rate = %g, maxError = %g\n", sampleFileName, rateTmp, maxTmp); + % draw pic and save pic + % figure(1); + % scatter(sampleData(:,1), sampleData(:,2), '.'); + % hold on; plot(edge(:,2), edge(:,3), '-r', 'LineWidth', 1); hold off; + % set(gca, 'Fontname', 'Times newman', 'Fontsize', 55); + % nameTmp = strcat("unstable_scatterEdge_", sampleFileName); + % % title(nameTmp, 'Interpreter', 'none'); + % % grid on; + % img =gcf; print(img, '-djpeg', '-r100', nameTmp); + + % update boundary error to [2, 10]。这一段其实可以放到前边去 + radio = (maxTmp - 2) / 8; + indexTmp = sampleData(:,2) >= 2; + sampleData(indexTmp, 2) = (sampleData(indexTmp,2) - 2) / radio + 2; + maxTmp = max(sampleData(indexTmp,2)); + edgeIndex = boundary(sampleData(:,1), sampleData(:,2), 1.0); + edge = [edgeIndex, sampleData(edgeIndex,1), sampleData(edgeIndex,2)]; - % draw pic and save pic - % figure(1); - % scatter(sampleData(:,1), sampleData(:,2), '.'); - % hold on; plot(upEdge(:,2), upEdge(:,3), '-r', 'LineWidth', 1); hold off; - % set(gca, 'Fontname', 'Times newman', 'Fontsize', 55); - % nameTmp = strcat("unstable_1_scatterEdge_", sampleFileName); - % % title(nameTmp, 'Interpreter', 'none'); - % % grid on; - % img =gcf; print(img, '-djpeg', '-r100', nameTmp); - else % do nothing, just for debug - % fprintf("%s is stable, rate = %g, maxError = %g\n", sampleFileName, rateTmp, maxTmp); - % draw pic and save pic - % figure(1); - % scatter(sampleData(:,1), sampleData(:,2), '.'); - % hold on; plot(upEdge(:,2), upEdge(:,3), '-r', 'LineWidth', 1); hold off; - % set(gca, 'Fontname', 'Times newman', 'Fontsize', 55); - % nameTmp = strcat("stable_scatterEdge_", sampleFileName); - % % title(nameTmp, 'Interpreter', 'none'); - % % grid on; - % img =gcf; print(img, '-djpeg', '-r100', nameTmp); - end + % upEdge: tradional way + edge = flipud(edge); + if isempty(edge) + fprintf("\tedge is empty!\n"); + break; + end + upEdgeStart = 1; + upEdgeEnd = length(edge); + edgeTmp = edge; + thresholdTrash = 5; + minEdgeInput = min(edgeTmp(:,2)); + maxEdgeInput = max(edgeTmp(:,2)); + + threshold = 2; + edgeTmp(edge(:,3) thresholdTrash) + upEdgeStart = max(1,k-1-thresholdTrash); + break + end + else + trash = 0; + end + end + % tail + trash = 0; + for k = length(edgeTmp):-1:1 + if(edgeTmp(k,2) == maxEdgeInput) + upEdgeEnd = min(k, length(edgeTmp)); + break + end + if(edgeTmp(k,end) ~= threshold) + trash = trash + 1; + if(trash > thresholdTrash) + upEdgeEnd = min(k+1+thresholdTrash, length(edgeTmp)); + break + end + else + trash = 0; + end + end + % after head & tail + upEdge = edge(upEdgeStart:upEdgeEnd,:); % upEdge是保留了上半段轮廓线中小于阈值的部分 + + % draw pic and save pic + % figure(1); + % scatter(sampleData(:,1), sampleData(:,2), '.'); + % hold on; plot(upEdge(:,2), upEdge(:,3), '-r', 'LineWidth', 1); hold off; + % set(gca, 'Fontname', 'Times newman', 'Fontsize', 55); + % nameTmp = strcat("unstable_1_scatterEdge_", sampleFileName); + % % title(nameTmp, 'Interpreter', 'none'); + % % grid on; + % img =gcf; print(img, '-djpeg', '-r100', nameTmp); + else % do nothing, just for debug + % fprintf("%s is stable, rate = %g, maxError = %g\n", sampleFileName, rateTmp, maxTmp); + % draw pic and save pic + % figure(1); + % scatter(sampleData(:,1), sampleData(:,2), '.'); + % hold on; plot(upEdge(:,2), upEdge(:,3), '-r', 'LineWidth', 1); hold off; + % set(gca, 'Fontname', 'Times newman', 'Fontsize', 55); + % nameTmp = strcat("stable_scatterEdge_", sampleFileName); + % % title(nameTmp, 'Interpreter', 'none'); + % % grid on; + % img =gcf; print(img, '-djpeg', '-r100', nameTmp); + end - % save upEdge data to file whose format like upEdge_Bspline3.txt - if(~isempty(edge)) - % fprintf("\tupEdgeFileName: %s with %d lines\n", upEdgeFileName, length(upEdge)); - save(upEdgeFileName, 'upEdge', '-ascii', '-double'); % the 2nd parameter mean the data to save to file + % save upEdge data to file whose format like upEdge_Bspline3.txt + if(~isempty(edge)) + % fprintf("\tupEdgeFileName: %s with %d lines\n", upEdgeFileName, length(upEdge)); + save(upEdgeFileName, 'upEdge', '-ascii', '-double'); % the 2nd parameter mean the data to save to file + else + fprintf("\tedge is empty\n"); + end + + % if(length(maxIndex) > 1) + % fprintf("\tleftTmp(%d) = %d, rightTmp(%d) = %d\n", j, leftTmp(j), j, rightTmp(j)); + % end + end + if maxTmp > 2 + indexTmp = sampleData(:,2) >= 2; + meanTmp = mean(sampleData(indexTmp, 2)); else - fprintf("\tedge is empty\n"); + meanTmp = mean(sampleData(:, 2)); end - - % if(length(maxIndex) > 1) - % fprintf("\tleftTmp(%d) = %d, rightTmp(%d) = %d\n", j, leftTmp(j), j, rightTmp(j)); - % end -end -if maxTmp > 2 - indexTmp = sampleData(:,2) >= 2; - meanTmp = mean(sampleData(indexTmp, 2)); -else - meanTmp = mean(sampleData(:, 2)); end -toc +all_time = toc; +fprintf("%f\n", all_time); % compute the threshold for deviding intervals % thresholdTmp = (maxTmp + meanTmp) / 2; % fprintf("%s: max = %g, average = %g, threshold = %d\n", sampleFileName, maxTmp, meanTmp, thresholdTmp); diff --git a/src/main.cpp b/src/main.cpp index dacc1648a4b426288d03919330b4e7b588f96401..ba20c6ca6a220cf2f354b63f94f57062478d85bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,6 +12,7 @@ #include #include #include +#include using std::cin; using std::cout; @@ -35,18 +36,18 @@ map> benchmarkThresholds = { {"NMSEexample35", {1}}, {"NMSEexample36", {2}}, {"NMSEexample37", {0.5}}, - {"NMSEexample38", {10}}, + {"NMSEexample38", {2}}, {"NMSEexample39", {5}}, {"NMSEproblem331", {1}}, {"NMSEproblem333", {1.5}}, - {"NMSEproblem334", {200}}, + {"NMSEproblem334", {2}}, {"NMSEproblem336", {1}}, {"NMSEproblem337", {1}}, {"NMSEproblem341", {2}}, {"NMSEproblem343", {1}}, - {"NMSEproblem344", {2}}, + {"NMSEproblem344", {1}}, {"NMSEproblem345", {2}}, - {"NMSEsection311", {2}}, + {"NMSEsection311", {1}}, {"predatorPrey", {2}}, {"sine", {1}}, {"sineorder3", {3}}, @@ -54,7 +55,26 @@ map> benchmarkThresholds = { {"sqrt_add", {1.5}}, {"test05_nonlin1_r4", {1.2}}, {"test05_nonlin1_test2", {1.2}}, - {"verhulst", {2}}, + {"verhulst", {1}}, + {"ComplexSinCos", {2.861064e+02, 6.019811}}, + {"ComplexSquareRoot", {1, 1}}, + {"doppler1", {2.588287, 2, 2.586046}}, + {"doppler2", {2, 2, 3.107020}}, + {"doppler3", {2.509605, 2, 2.508455}}, + {"hypot32", {2, 2}}, + {"i4", {2, 2}}, + {"i6", {7.869156e+06, 8.400076e+06}}, + {"NMSEexample33", {1.678153e+06, 1.540327e+06}}, + {"NMSEproblem332", {4.957687e+02, 1.740876e+03}}, + {"NMSEproblem335", {1, 1}}, + {"NMSEproblem346", {4.068065e+00, 4.041267e+00}}, + {"NMSEsection35", {0.75, 0.75}}, + {"polarToCarthesianX", {8.225613e+12, 2}}, + {"polarToCarthesianY", {2.161373e+12, 1.341743e+12}}, + {"sec4example", {1.25, 1.25}}, + {"test03_nonlin2", {1.375, 1.25}}, + {"theta", {2, 2}}, + {"turbine1", {3.002278, 2.831004, 2.847586}}, }; //===----------------------------------------------------------------------===// @@ -113,15 +133,15 @@ int main() auto benchMarkData = initalBenchMark(); auto pos = benchMarkData.find(inputStr); bool isBenchMark = false; - string name; + string uniqueLabel = ""; vector thresholds; if (pos != benchMarkData.end()) { - name = inputStr; + uniqueLabel = inputStr; inputStr = pos->second.begin()->first; cout << "expression := " << inputStr << endl; - thresholds = benchmarkThresholds.at(name); + thresholds = benchmarkThresholds.at(uniqueLabel); // fmt::print("thresholds := {}\n", thresholds); isBenchMark = true; @@ -201,13 +221,22 @@ int main() } bool runAllFlag = true; + + // ready for writing to file + double originPerformance = -1; + double numOfIntervals = -1; + int numOfExprs = -1; + exprInfo finalInfo; // ave err, max err, performance + std::chrono::duration init_seconds, matlab_seconds, regime_seconds, rewrite_seconds, final_seconds,elapsed_seconds; + double matlabKernelTime = -1; + if (runAllFlag) { // the whole process - auto uniqueLabel = getUniqueLabel(); - if (isBenchMark) + if (!isBenchMark) { - uniqueLabel = name; + uniqueLabel = getUniqueLabel(); } + cout << BLUE << "uniqueLabel: " << uniqueLabel << RESET << endl; string mkdirCommand = "mkdir -p srcTest/" + uniqueLabel + " outputs/" + uniqueLabel; system(mkdirCommand.c_str()); @@ -219,9 +248,19 @@ int main() // auto exprDaisy = geneDaisyCode(inputStr, uniqueLabel, "daisy"); auto funcNameMpfr = geneMpfrCode(inputStr, uniqueLabel, vars); + originPerformance = testPerformance(uniqueLabel, "origin", intervals); + cout << "origin performance: " << originPerformance << "\n\n"; + // TODO: improve pickTheBest to support more suffix - // pickTheBest(uniqueLabel, 0, 1, 100); - vector suffixSet = {"origin", "herbie"}; + vector suffixSet = {"origin"}; + if (exprHerbie != "") + { + suffixSet.push_back("herbie"); + } + else + { + fprintf(stderr, "For exprOrigin, Herbie's rewrite results can not be used.\nSo, we just pick origin as the best.\n"); + } auto initExprInfo = pickTheBest(uniqueLabel, suffixSet, intervals, scales); auto suffix = initExprInfo.suffix; if (suffix == "origin") @@ -239,7 +278,7 @@ int main() } cout << "the pick expr is " << inputStr << "\n"; auto timeTmp1 = std::chrono::high_resolution_clock::now(); // init over - std::chrono::duration init_seconds = timeTmp1 - timeStart; + init_seconds = timeTmp1 - timeStart; cout << BLUE << "init time: " << init_seconds.count() << " s" << RESET << endl; auto &initExprMaxError = initExprInfo.maxError; if (initExprMaxError <= 0.5) @@ -259,27 +298,67 @@ int main() // cout << BLUE << "testError time: " << testError_seconds.count() << " s" << RESET << endl; // fprintf(stderr, GREEN "ready> " RESET); // continue; - - // auto infoTmp = testError(uniqueLabel, "origin", intervals, scales); // TODO-done: 完善origin误差测试 // WHY do it? Because no pickTheBest before. So, have to use testError to get the sample data. - auto upEdgeFileName = geneBoundaryData(uniqueLabel, suffix); // sample data == matlab ==> upEdge data // TODO: support multiple dimension - cout << "upEdgeFileName: " << upEdgeFileName << "\n"; + + string upEdgeFileName; + vector upEdgeFileNames; + if(dimension == 1) + { + // No sampling is required because for a single parameter, the error test data is equivalent to the sampled data + // Just generate boundary data by matlab + upEdgeFileName = geneBoundaryData(uniqueLabel, suffix, matlabKernelTime); // sample data == matlab ==> upEdge data + upEdgeFileNames.push_back(upEdgeFileName); + } + else + { + // 1. sample for different dimension + // 2. generate boundary data by matlab + string suffixTmp; + vector suffixTmps; + if (dimension == 2) + { + suffixTmp = suffix + "_X"; + suffixTmps.push_back(suffixTmp); + suffixTmp = suffix + "_Y"; + suffixTmps.push_back(suffixTmp); + vector scales{8192, 2048}; + sampleError(uniqueLabel, suffix, intervals, scales); + } + else if (dimension == 3) + { + suffixTmp = suffix + "_X"; + suffixTmps.push_back(suffixTmp); + suffixTmp = suffix + "_Y"; + suffixTmps.push_back(suffixTmp); + suffixTmp = suffix + "_Z"; + suffixTmps.push_back(suffixTmp); + vector scales{512, 128}; // actually are drawNum and findMaxNum, so only need 2 numbers + sampleError(uniqueLabel, suffix, intervals, scales); + } + else + { + fprintf(stderr, "ERROR: main: we can not handle %d parameters (bigger than 3) now\n", dimension); + exit(EXIT_FAILURE); + } + upEdgeFileNames = geneBoundaryData(uniqueLabel, suffix, suffixTmps, matlabKernelTime); // sample data == matlab ==> upEdge data + } + fmt::print("upEdgeFileNames: {}\n", upEdgeFileNames); auto timeTmp2 = std::chrono::high_resolution_clock::now(); // matlab over - std::chrono::duration matlab_seconds = timeTmp2 - timeTmp1; + matlab_seconds = timeTmp2 - timeTmp1; cout << BLUE << "regime time (matlab part): " << matlab_seconds.count() << " s" << RESET << endl; - vector upEdgeFileNames; - upEdgeFileNames.push_back(upEdgeFileName); - auto intervalData = getIntervalData(upEdgeFileNames, thresholds); - fmt::print("after regime, we have {} intervals: {}\n", intervalData.size(), intervalData); + + auto intervalData = getIntervalData(upEdgeFileNames, thresholds, intervals); + numOfIntervals = intervalData.size(); + fmt::print("after regime, we have {} intervals: {}\n", numOfIntervals, intervalData); auto timeTmp3 = std::chrono::high_resolution_clock::now(); - std::chrono::duration regime_seconds = timeTmp3 - timeTmp2; + regime_seconds = timeTmp3 - timeTmp2; cout << BLUE << "regime time (other part): " << regime_seconds.count() << " s" << RESET << endl; // fprintf(stderr, GREEN "ready> " RESET); // continue; cout << "=-=-=-=-=-=-=-=-=-=-=-=-= rewrite start =-=-=-=-=-=-=-=-=-=-=-=-=" << endl; - auto exprInfoVector = rewrite(inputStr, uniqueLabel, intervalData); + auto exprInfoVector = rewrite(inputStr, uniqueLabel, intervalData, numOfExprs); auto timeTmp4 = std::chrono::high_resolution_clock::now(); // rewrite over - std::chrono::duration rewrite_seconds = timeTmp4 - timeTmp3; + rewrite_seconds = timeTmp4 - timeTmp3; cout << BLUE << "rewrite time: " << rewrite_seconds.count() << " s" << RESET << endl; // fprintf(stderr, GREEN "ready> " RESET); // continue; @@ -288,12 +367,12 @@ int main() auto funcNameFinal = geneFinalCodeKernel(inputStr, uniqueLabel, exprInfoVector, vars); cout << "=-=-=-=-=-=-=-=-=-=-=-=-= test final code's error and performance start =-=-=-=-=-=-=-=-=-=-=-=-=\n"; - auto infoTmp = testError(uniqueLabel, "final", intervals, scales); - infoTmp.performance = testPerformance(uniqueLabel, "final", intervals); - cout << "performance: " << infoTmp.performance << "\n\n"; + finalInfo = testError(uniqueLabel, "final", intervals, scales); + finalInfo.performance = testPerformance(uniqueLabel, "final", intervals); + cout << "performance: " << finalInfo.performance << "\n\n"; cout << "=-=-=-=-=-=-=-=-=-=-=-=-= test final code's error and performance end =-=-=-=-=-=-=-=-=-=-=-=-=\n"; auto timeTmp5 = std::chrono::high_resolution_clock::now(); - std::chrono::duration final_seconds = timeTmp5 - timeTmp4; + final_seconds = timeTmp5 - timeTmp4; cout << BLUE << "final time: " << final_seconds.count() << " s" << RESET << endl; // write the results to file // auto results = exprAutoWrapper(inputStr, intervals, scales); @@ -333,8 +412,25 @@ int main() } // only rewrite end auto timeEnd = std::chrono::high_resolution_clock::now(); - std::chrono::duration elapsed_seconds = timeEnd - timeStart; + elapsed_seconds = timeEnd - timeStart; cout << BLUE << "the whole time: " << elapsed_seconds.count() << " s" << RESET << endl; + + vector summaryData; + summaryData.push_back(originPerformance); + summaryData.push_back(numOfIntervals); + summaryData.push_back(double(numOfExprs)); + summaryData.push_back(finalInfo.aveError); + summaryData.push_back(finalInfo.maxError); + summaryData.push_back(finalInfo.performance); + summaryData.push_back(elapsed_seconds.count()); + summaryData.push_back(init_seconds.count()); + summaryData.push_back(matlab_seconds.count()); + summaryData.push_back(regime_seconds.count()); + summaryData.push_back(rewrite_seconds.count()); + summaryData.push_back(final_seconds.count()); + summaryData.push_back(matlabKernelTime); + write_to_file(uniqueLabel, summaryData, "runlog.csv"); + fprintf(stderr, GREEN "ready> " RESET); } diff --git a/src/tools.cpp b/src/tools.cpp index 4f3a4d9b002b620103c2bea7bba2eff7379d3052..3f0fb13c5a1daa09f2a2d83d75de8d9ae041133f 100644 --- a/src/tools.cpp +++ b/src/tools.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include using std::cout; @@ -358,7 +359,7 @@ exprInfo testError(string uniqueLabel, string suffix, const vector &inte return tempError; } -exprInfo testError(string uniqueLabel, string suffix, const vector &intervals, const vector &scales) +exprInfo testError(string uniqueLabel, string suffix, const vector &intervals, const vector &scales, bool errfile) { exprInfo tempError; size_t size = scales.size(); @@ -392,20 +393,22 @@ exprInfo testError(string uniqueLabel, string suffix, const vector &inte string fileNameKernel = prefix + "__" + middle + "_" + suffix; namespace fs = std::filesystem; string currentPath = fs::current_path(); - string testName = currentPath + "/outputs/" + uniqueLabel + "/" + fileNameKernel + "_error.txt"; + string testName = currentPath + "/outputs/" + uniqueLabel + "/" + fileNameKernel + "_error.txt"; // get the output of error detecting string number[3] = {"One", "Two", "Three"}; string scriptName = "./detectError" + number[size - 1] + "FPEDParallel.sh"; - string commandStr = scriptName + " " + uniqueLabel; + stringstream ss; + ss << scriptName << " " << uniqueLabel; for(const auto & param : params) { - commandStr = commandStr + " " + param; + ss << " " << param; } - commandStr = commandStr + " " + prefix + " " + middle + " " + suffix; + ss << " " << prefix << " " << middle << " " << suffix << " " << errfile; + string commandStr = ss.str(); // cout << "fileNameKernel: " << fileNameKernel << "\n"; cout << "command: " << commandStr << "\n"; // cout << "testName: " << testName << "\n"; - char command[200] = {0}; + char command[512] = {0}; strcat(command, commandStr.c_str()); system(command); @@ -451,6 +454,65 @@ exprInfo testError(string uniqueLabel, string suffix, const vector &inte return tempError; } +void sampleError(string uniqueLabel, string suffix, const vector &intervals, const vector &scales) { + exprInfo tempError; + size_t size = intervals.size() / 2; + + if (size < 4) + { + string prefix = "expr_" + uniqueLabel; + vector params; + for(const auto &interval : intervals) + { + auto paraTmp = fmt::format("{}", interval); + params.push_back(paraTmp); + } + for(const auto &scale : scales) + { + auto scaleTmp = fmt::format("{}", scale); + params.push_back(scaleTmp); + } + string middle; + for(size_t i = 0; i < params.size(); ++i) + { + if(i == 0) + { + middle = params.at(i); + } + else + { + middle = middle + "_" + params.at(i); + } + } + string fileNameKernel = prefix + "__" + middle + "_" + suffix; + namespace fs = std::filesystem; + string currentPath = fs::current_path(); + string testName = currentPath + "/outputs/" + uniqueLabel + "/" + fileNameKernel + "_error.txt"; // used to get the output of error detecting, not input parameters + string number[3] = {"One", "Two", "Three"}; + string scriptName = "./sampleError" + number[size - 1] + ".sh"; + stringstream ss; + ss << scriptName << " " << uniqueLabel; + for(const auto & param : params) + { + ss << " " << param; + } + ss << " " << prefix << " " << middle << " " << suffix; + string commandStr = ss.str(); + + // cout << "fileNameKernel: " << fileNameKernel << "\n"; + cout << "command: " << commandStr << "\n"; + // cout << "testName: " << testName << "\n"; + char command[200] = {0}; + strcat(command, commandStr.c_str()); + system(command); + } + else + { + fprintf(stderr, "ERROR: testError: the intervalTmp's dimension is %ld, which we don't support now.\n", size); + exit(EXIT_FAILURE); + } +} + double testPerformance(string uniqueLabel, string suffix, const vector &intervals) { size_t size = intervals.size() / 2; @@ -512,9 +574,43 @@ double testPerformance(string uniqueLabel, string suffix, const vector & return tempCycles; } -// TODO: support multiple dimension +// support setting matlab +string runCommand(string command) +{ + const int maxlen = 128; + FILE *fp = NULL; + char *buff = NULL; + + buff = (char *)malloc(maxlen); + if (buff == NULL) + { + perror("malloc:"); + exit(EXIT_FAILURE); + } + memset(buff, 0, maxlen); + + fp = popen(command.c_str(), "r"); + if (fp == NULL) + { + perror("popen error:"); + free(buff); + exit(EXIT_FAILURE); + } + fgets(buff, maxlen, fp); + if (buff != nullptr && buff[0] == '\0') + { + fprintf(stderr, "there is no result returned by %s\n", command.c_str()); + } + + pclose(fp); + string result = buff; + result.erase(std::remove(result.begin(), result.end(), '\n'), result.end()); + free(buff); + return result; +} + // call matlab to generate the upEdgeData to file -string geneBoundaryData(string uniqueLabel, string suffix) +string geneBoundaryData(string uniqueLabel, string suffix, double &costTime) { char *currentPath; if((currentPath = getcwd(NULL, 0)) == NULL) @@ -523,22 +619,52 @@ string geneBoundaryData(string uniqueLabel, string suffix) } string currentPathStr(currentPath); string outputFilesPath = currentPathStr + "/outputs/" + uniqueLabel + "/"; - string sampleFileName = outputFilesPath + "sample_" + uniqueLabel + "_" + suffix + ".txt"; - string upEdgeFileName = outputFilesPath + "upEdge_" + uniqueLabel + "_" + suffix + ".txt"; - string matlabExecutable = "/home/xyy/helloBro/softwares/matlab/R2020a/bin/matlab"; // set to your own matlab executable - string matlabCommands = " -batch \"sampleFileName=\'" + sampleFileName + "\'; upEdgeFileName = \'" + upEdgeFileName + "\'; run " + currentPathStr + "/src/getUpEdge\""; // DO NOT need to add the suffix ".m" for matlab file! + string sampleFileNameKernel = "sample_" + uniqueLabel + "_" + suffix + ".txt"; + string matlabExecutable = runCommand("which matlab"); // find matlab + string matlabCommands = " -batch \"outputFilesPath=\'" + outputFilesPath + "\'; sampleFileNameKernel = \'" + sampleFileNameKernel + "\'; run " + currentPathStr + "/src/getUpEdge\""; // DO NOT need to add the suffix ".m" for matlab file! string commandStr = matlabExecutable + matlabCommands; cout << "Matlab command: " << commandStr << "\n"; // cout << "length of commandStr: " << commandStr.size() << "\n"; char command[512] = {0}; strcat(command, commandStr.c_str()); - system(command); + auto matlabKernelTime = runCommand(command); + costTime = stod(matlabKernelTime); free(currentPath); // std::cout << "generate upEdge file:" << upEdgeFileName << std::endl; + string upEdgeFileName = outputFilesPath + "upEdge_" + uniqueLabel + "_" + suffix + ".txt"; return upEdgeFileName; } +vector geneBoundaryData(string uniqueLabel, string suffix, vector suffixes, double &costTime) +{ + char *currentPath; + if((currentPath = getcwd(NULL, 0)) == NULL) + { + perror("getcwd error"); + } + string currentPathStr(currentPath); + string outputFilesPath = currentPathStr + "/outputs/" + uniqueLabel + "/"; + string sampleFileNameKernel = "sample_" + uniqueLabel + "_" + suffix + "_" + "*.txt"; + string matlabExecutable = runCommand("which matlab"); // find matlab + string matlabCommands = " -batch \"outputFilesPath=\'" + outputFilesPath + "\'; sampleFileNameKernel = \'" + sampleFileNameKernel + "\'; run " + currentPathStr + "/src/getUpEdge\""; // DO NOT need to add the suffix ".m" for matlab file! + string commandStr = matlabExecutable + matlabCommands; + cout << "Matlab command: " << commandStr << "\n"; + char command[512] = {0}; + strcat(command, commandStr.c_str()); + auto matlabKernelTime = runCommand(command); + costTime = stod(matlabKernelTime); + free(currentPath); + vector upEdgeFileNames; + for(auto &suffix : suffixes) + { + string upEdgeFileName = outputFilesPath + "upEdge_" + uniqueLabel + "_" + suffix + ".txt"; + upEdgeFileNames.push_back(upEdgeFileName); + } + + return upEdgeFileNames; +} + // string geneIntervalData1D(string upEdgeFileName, string uniqueLabel, double threshold) // generate the interval info to file at the target dimension // { // // init @@ -630,19 +756,19 @@ vector> getIntervalData(string filename) return intervalData; } -// according to the corresponding intervalData file in each dimension, generate the interval data, and then generate all permutation of all dimensions. -vector> getIntervalData(vector upEdgeFileNames, vector &thresholds) +// according to the corresponding upEdgeFile, generate intervalData for each dimension, and then combine all permutation of all dimensions. +vector> getIntervalData(vector upEdgeFileNames, vector &thresholds, vector &intervals) { vector> intervalDataMultiDim; int dimension = thresholds.size(); - // auto thresholdCombine = 0; for (int i = 0; i < dimension; i++) // iterate all the dimensions { // call devideUpEdgeData for each dimension: matlab upEdge ==> interval vector auto &upEdgeFileName = upEdgeFileNames.at(i); auto &threshold = thresholds.at(i); - auto intervalData1D = devideUpEdgeData(upEdgeFileName, threshold); // TODO: add the parameter thresholdCombine - // push_back interval vector + auto thresholdCombine = (intervals.at(2 * i + 1) - intervals.at(2 * i)) / 100; // thresholdCombine = 1% of the interval width at the target demision + auto intervalData1D = devideUpEdgeData(upEdgeFileName, threshold, thresholdCombine); + // fmt::print("intervalData1D {}\n", intervalData1D); intervalDataMultiDim.push_back(intervalData1D); } // call permuteMultiVec to get all permutation @@ -651,7 +777,7 @@ vector> getIntervalData(vector upEdgeFileNames, vector rewrite(string exprStr, string uniqueLabel, vector> &intervalData) +vector rewrite(string exprStr, string uniqueLabel, vector> &intervalData, int &numOfExprs) { // string filename = "expr_" + uniqueLabel + "_interval.txt"; // useless // string filename = "./intervalData.txt"; // TODO-done: get the filename from uniqueLabel. Now we get intervalData from input parameters directly. @@ -676,16 +802,26 @@ vector rewrite(string exprStr, string uniqueLabel, vector scales(dimension, scale); auto newTempExprs = exprAutoWrapper(tempExpr, intervalTmp, scales); + numOfExprs = newTempExprs.size(); string suffix = "temp_" + std::to_string(count) + "_"; // special conditions - if(newTempExprs.size() <= 1) + if(numOfExprs <= 1) { - if(isEqual(newTempExprs.at(0), tempExpr)) - { - fprintf(stderr, "rewrite: only %d Equivalent expressions and is equal to inputexpr, so we do not rewrite.\n", newTempExprs.size()); - continue; - } + // auto tempError = testError(uniqueLabel, "mpfr", intervalTmp, scales); // use mpfr + exprInfo tempInfo; + tempInfo.intervals = intervalTmp; + tempInfo.exprStr = "mpfr"; + tempInfo.aveError = 0; + tempInfo.maxError = 0; + tempInfo.rewriteID = -1; + exprInfoVector.push_back(tempInfo); + continue; + // if(isEqual(newTempExprs.at(0), tempExpr)) + // { + // fprintf(stderr, "rewrite: only %d Equivalent expressions and is equal to inputexpr, so we do not rewrite.\n", newTempExprs.size()); + // continue; + // } } // pick the best rewrite expression @@ -693,7 +829,7 @@ vector rewrite(string exprStr, string uniqueLabel, vector rewrite(string exprStr, string uniqueLabel, vector= x2; + // if (x + y > 2) { + // continue; + // } + computeResult2param(x, y, mpfrResult); + computeOrcle2param(x, y, mpfrOrcle); + // orcle.d = mpfr_get_d(mpfrOrcle, MPFR_RNDN); + // result.d = mpfr_get_d(mpfrResult, MPFR_RNDN); + #ifdef SINGLE + reUlp = computeUlpDiffF(mpfrOrcle, mpfrResult); + #else // compute Double ULP as default + reUlp = computeUlpDiff(mpfrOrcle, mpfrResult); + #endif + + if (reUlp > maxReUlp) { + // maxInputX = j; + maxReUlp = reUlp; + } + } + fprintf(f, "%.16le\t%.16e\n", x, maxReUlp); + } + fclose(f); +} + +void sample2paramY(DL xStart, DL xEnd, DL yStart, DL yEnd, unsigned long int testNumX, unsigned long int testNumY, const char* uniqueLabel, const char *fileNameKernel, int myid, int iStartLocal, int iEndLocal) +{ + DL i, j; + // DL maxInputX, maxInputY, orcle, result; + int ii, jj; + double x, y, reUlp, maxReUlp, lenX, lenY; + + // mpfr + mpfr_t mpfrOrcle, mpfrResult; + mpfr_inits2(PRECISION, mpfrOrcle, mpfrResult, (mpfr_ptr) 0); + + // write error data to file + char *directory = "outputs"; + char *suffix = "sample_Y"; + char *fileNameSample; + FILE *f; + fileNameSample = (char *) calloc(strlen(directory) + strlen(uniqueLabel) + strlen(fileNameKernel) + strlen(suffix) + 128, sizeof(char)); + sprintf(fileNameSample, "%s/%s/%s_%s_%02d.txt", directory, uniqueLabel, fileNameKernel, suffix, myid); + // printf("%s\n", fileNameSample); + if ((f = fopen(fileNameSample, "w")) == NULL) { + printf("Error opening file %s.\n", fileNameSample); + exit(0); + } + + // loop boundary + lenX = xEnd.d - xStart.d; + lenY = yEnd.d - yStart.d; + double stepX = lenX / (double)testNumX; + double stepY = lenY / (double)testNumY; + + // Real number average + // 固定y值,求不同x值下的最大误差 + for(ii = iStartLocal; ii <= iEndLocal; ii++) { + i.d = yStart.d + stepY * ii; + y = i.d; + maxReUlp = 0; + for(jj = 0; jj <= testNumX; jj++) { + j.d = xStart.d + stepX * jj; + x = j.d; + // constraint: ((-2 * ((x1 * x1) * (x1 * x1))) + 2) >= x2; + // if (x + y > 2) { + // continue; + // } + computeResult2param(x, y, mpfrResult); + computeOrcle2param(x, y, mpfrOrcle); + // orcle.d = mpfr_get_d(mpfrOrcle, MPFR_RNDN); + // result.d = mpfr_get_d(mpfrResult, MPFR_RNDN); + #ifdef SINGLE + reUlp = computeUlpDiffF(mpfrOrcle, mpfrResult); + #else // compute Double ULP as default + reUlp = computeUlpDiff(mpfrOrcle, mpfrResult); + #endif + + if (reUlp > maxReUlp) { + // maxInputX = j; + maxReUlp = reUlp; + } + } + fprintf(f, "%.16le\t%.16e\n", y, maxReUlp); + } + fclose(f); +} + +int main(int argc, char *argv[]) +{ + // parallel + int myid, numProcs; + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &myid); + MPI_Comm_size(MPI_COMM_WORLD, &numProcs); + + // parameters init + DL xStart, xEnd, yStart, yEnd; + unsigned long int drawNum, findMaxNum; + xStart.d = 0.1; + xEnd.d = 100; + yStart.d = 0.1; + yEnd.d = 100; + drawNum = TESTNUMX; + findMaxNum = TESTNUMY; + + char *fileNameKernel; + fileNameKernel = calloc(256, sizeof(char)); + char *uniqueLabel; + uniqueLabel = calloc(256, sizeof(char)); + + if(argc == 9) { + xStart.d = strtod(argv[1], NULL); + xEnd.d = strtod(argv[2], NULL); + yStart.d = strtod(argv[3], NULL); + yEnd.d = strtod(argv[4], NULL); + drawNum = strtod(argv[5], NULL); + findMaxNum = strtod(argv[6], NULL); + strcpy(fileNameKernel, argv[7]); + strcpy(uniqueLabel, argv[8]); + } else { + printf("Usage: ./sample2paramParallel.out xStart xEnd yStart yEnd drawNum findMaxNum fileNameKernel uniqueLabel\n"); + exit(EXIT_FAILURE); + } + + // local parameters init + int lenLocal = drawNum / numProcs; + int iStartLocal; + iStartLocal = myid * lenLocal; + int iEndLocal; + if (myid != numProcs - 1) + { + iEndLocal = (myid + 1) * lenLocal - 1; + } + else + { + iEndLocal = drawNum; + } + + sample2paramX(xStart, xEnd, yStart, yEnd, drawNum, findMaxNum, uniqueLabel, fileNameKernel, myid, iStartLocal, iEndLocal); + sample2paramY(xStart, xEnd, yStart, yEnd, findMaxNum, drawNum, uniqueLabel, fileNameKernel, myid, iStartLocal, iEndLocal); + + // clear + free(uniqueLabel); + free(fileNameKernel); + MPI_Finalize(); + return 0; +} \ No newline at end of file diff --git a/srcTest/sample3paramFPEDParallel.c b/srcTest/sample3paramFPEDParallel.c new file mode 100644 index 0000000000000000000000000000000000000000..844aa2df7e1fc6898cc28ffdb432bcfbef9e0c68 --- /dev/null +++ b/srcTest/sample3paramFPEDParallel.c @@ -0,0 +1,295 @@ +#include "common.h" +#include "mpi.h" + +#ifndef SUFFIX +#define SUFFIX orgin +#endif +#ifndef EXPRESSION +#define EXPRESSION sum +#endif + +#define EXPRESSIONMINE ADDSUFFIX(EXPRESSION, SUFFIX) +#define SUFFIX1 mpfr +#define EXPRESSIONMPFR ADDSUFFIX(EXPRESSION, SUFFIX1) + +#define TESTNUMX 2048 +#define TESTNUMY 2048 + +double EXPRESSIONMPFR(double, double, double, mpfr_t); +double EXPRESSIONMINE(double, double, double); + +int computeOrcle3param(double x0, double x1, double x2, mpfr_t orcle) +{ + return EXPRESSIONMPFR(x0, x1, x2, orcle); +} + +int computeResult3param(double x0, double x1, double x2, mpfr_t mpfrResult) +{ + int status = 1; + + double result = EXPRESSIONMINE(x0, x1, x2); + mpfr_set_d(mpfrResult, result, MPFR_RNDN); + + return status; +} + +void sample3paramX(DL xStart, DL xEnd, DL yStart, DL yEnd, DL zStart, DL zEnd, unsigned long int testNumX, unsigned long int testNumY, unsigned long int testNumZ, const char* uniqueLabel, const char *fileNameKernel, int myid, int iStartLocal, int iEndLocal) +{ + DL i, j, k; + // DL maxInputX, maxInputY, maxInputZ, orcle, result; + int ii, jj, kk; + double x, y, z, reUlp, maxReUlp, lenX, lenY, lenZ; + + // mpfr + mpfr_t mpfrOrcle, mpfrResult; + mpfr_inits2(PRECISION, mpfrOrcle, mpfrResult, (mpfr_ptr) 0); + + // write error data to file + char *directory = "outputs"; + char *suffix = "sample_X"; + char *fileNameSample; + FILE *f; + fileNameSample = (char *) calloc(strlen(directory) + strlen(uniqueLabel) + strlen(fileNameKernel) + strlen(suffix) + 128, sizeof(char)); + sprintf(fileNameSample, "%s/%s/%s_%s_%02d.txt", directory, uniqueLabel, fileNameKernel, suffix, myid); + // printf("%s\n", fileNameSample); + if ((f = fopen(fileNameSample, "w")) == NULL) { + printf("Error opening file %s.\n", fileNameSample); + exit(0); + } + + // loop boundary + lenX = xEnd.d - xStart.d; + lenY = yEnd.d - yStart.d; + lenZ = zEnd.d - zStart.d; + double stepX = lenX / (double)testNumX; + double stepY = lenY / (double)testNumY; + double stepZ = lenZ / (double)testNumZ; + + // Real number average + // 固定x值,求不同y值下的最大误差 + for(ii = iStartLocal; ii <= iEndLocal; ii++) { + i.d = xStart.d + stepX * ii; + x = i.d; + maxReUlp = 0; + for(jj = 0; jj <= testNumY; jj++) { + j.d = yStart.d + stepY * jj; + y = j.d; + for(kk = 0; kk <= testNumZ; kk++) { + k.d = zStart.d + stepZ * kk; + z = k.d; + computeResult3param(x, y, z, mpfrResult); + computeOrcle3param(x, y, z, mpfrOrcle); + // orcle.d = mpfr_get_d(mpfrOrcle, MPFR_RNDN); + // result.d = mpfr_get_d(mpfrResult, MPFR_RNDN); + #ifdef SINGLE + reUlp = computeUlpDiffF(mpfrOrcle, mpfrResult); + #else // compute Double ULP as default + reUlp = computeUlpDiff(mpfrOrcle, mpfrResult); + #endif + + if (reUlp > maxReUlp) { + // maxInputX = j; + maxReUlp = reUlp; + } + } + } + fprintf(f, "%.16le\t%.16e\n", x, maxReUlp); + } + fclose(f); +} + +void sample3paramY(DL xStart, DL xEnd, DL yStart, DL yEnd, DL zStart, DL zEnd, unsigned long int testNumX, unsigned long int testNumY, unsigned long int testNumZ, const char* uniqueLabel, const char *fileNameKernel, int myid, int iStartLocal, int iEndLocal) +{ + DL i, j, k; + // DL maxInputX, maxInputY, maxInputZ, orcle, result; + int ii, jj, kk; + double x, y, z, reUlp, maxReUlp, lenX, lenY, lenZ; + + // mpfr + mpfr_t mpfrOrcle, mpfrResult; + mpfr_inits2(PRECISION, mpfrOrcle, mpfrResult, (mpfr_ptr) 0); + + // write error data to file + char *directory = "outputs"; + char *suffix = "sample_Y"; + char *fileNameSample; + FILE *f; + fileNameSample = (char *) calloc(strlen(directory) + strlen(uniqueLabel) + strlen(fileNameKernel) + strlen(suffix) + 128, sizeof(char)); + sprintf(fileNameSample, "%s/%s/%s_%s_%02d.txt", directory, uniqueLabel, fileNameKernel, suffix, myid); + // printf("%s\n", fileNameSample); + if ((f = fopen(fileNameSample, "w")) == NULL) { + printf("Error opening file %s.\n", fileNameSample); + exit(0); + } + + // loop boundary + lenX = xEnd.d - xStart.d; + lenY = yEnd.d - yStart.d; + lenZ = zEnd.d - zStart.d; + double stepX = lenX / (double)testNumX; + double stepY = lenY / (double)testNumY; + double stepZ = lenZ / (double)testNumZ; + + // Real number average + // 固定y值,求不同x值下的最大误差 + for(ii = iStartLocal; ii <= iEndLocal; ii++) { + i.d = yStart.d + stepY * ii; + y = i.d; + maxReUlp = 0; + for(jj = 0; jj <= testNumX; jj++) { + j.d = xStart.d + stepX * jj; + x = j.d; + for(kk = 0; kk <= testNumZ; kk++) { + k.d = zStart.d + stepZ * kk; + z = k.d; + computeResult3param(x, y, z, mpfrResult); + computeOrcle3param(x, y, z, mpfrOrcle); + // orcle.d = mpfr_get_d(mpfrOrcle, MPFR_RNDN); + // result.d = mpfr_get_d(mpfrResult, MPFR_RNDN); + #ifdef SINGLE + reUlp = computeUlpDiffF(mpfrOrcle, mpfrResult); + #else // compute Double ULP as default + reUlp = computeUlpDiff(mpfrOrcle, mpfrResult); + #endif + + if (reUlp > maxReUlp) { + // maxInputX = j; + maxReUlp = reUlp; + } + } + } + fprintf(f, "%.16le\t%.16e\n", y, maxReUlp); + } + fclose(f); +} + +void sample3paramZ(DL xStart, DL xEnd, DL yStart, DL yEnd, DL zStart, DL zEnd, unsigned long int testNumX, unsigned long int testNumY, unsigned long int testNumZ, const char* uniqueLabel, const char *fileNameKernel, int myid, int iStartLocal, int iEndLocal) +{ + DL i, j, k; + // DL maxInputX, maxInputY, maxInputZ, orcle, result; + int ii, jj, kk; + double x, y, z, reUlp, maxReUlp, lenX, lenY, lenZ; + + // mpfr + mpfr_t mpfrOrcle, mpfrResult; + mpfr_inits2(PRECISION, mpfrOrcle, mpfrResult, (mpfr_ptr) 0); + + // write error data to file + char *directory = "outputs"; + char *suffix = "sample_Z"; + char *fileNameSample; + FILE *f; + fileNameSample = (char *) calloc(strlen(directory) + strlen(uniqueLabel) + strlen(fileNameKernel) + strlen(suffix) + 128, sizeof(char)); + sprintf(fileNameSample, "%s/%s/%s_%s_%02d.txt", directory, uniqueLabel, fileNameKernel, suffix, myid); + // printf("%s\n", fileNameSample); + if ((f = fopen(fileNameSample, "w")) == NULL) { + printf("Error opening file %s.\n", fileNameSample); + exit(0); + } + + // loop boundary + lenX = xEnd.d - xStart.d; + lenY = yEnd.d - yStart.d; + lenZ = zEnd.d - zStart.d; + double stepX = lenX / (double)testNumX; + double stepY = lenY / (double)testNumY; + double stepZ = lenZ / (double)testNumZ; + + // Real number average + // 固定y值,求不同x值下的最大误差 + for(ii = iStartLocal; ii <= iEndLocal; ii++) { + i.d = zStart.d + stepZ * ii; + z = i.d; + maxReUlp = 0; + for(jj = 0; jj <= testNumX; jj++) { + j.d = xStart.d + stepX * jj; + x = j.d; + for(kk = 0; kk <= testNumY; kk++) { + k.d = yStart.d + stepY * kk; + y = k.d; + computeResult3param(x, y, z, mpfrResult); + computeOrcle3param(x, y, z, mpfrOrcle); + // orcle.d = mpfr_get_d(mpfrOrcle, MPFR_RNDN); + // result.d = mpfr_get_d(mpfrResult, MPFR_RNDN); + #ifdef SINGLE + reUlp = computeUlpDiffF(mpfrOrcle, mpfrResult); + #else // compute Double ULP as default + reUlp = computeUlpDiff(mpfrOrcle, mpfrResult); + #endif + + if (reUlp > maxReUlp) { + // maxInputX = j; + maxReUlp = reUlp; + } + } + } + fprintf(f, "%.16le\t%.16e\n", z, maxReUlp); + } + fclose(f); +} + +int main(int argc, char *argv[]) +{ + // parallel + int myid, numProcs; + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &myid); + MPI_Comm_size(MPI_COMM_WORLD, &numProcs); + + // parameters init + DL xStart, xEnd, yStart, yEnd, zStart, zEnd; + unsigned long int drawNum, findMaxNum; + xStart.d = 0.1; + xEnd.d = 100; + yStart.d = 0.1; + yEnd.d = 100; + zStart.d = 0.1; + zEnd.d = 100; + drawNum = TESTNUMX; + findMaxNum = TESTNUMY; + + char *fileNameKernel; + fileNameKernel = calloc(256, sizeof(char)); + char *uniqueLabel; + uniqueLabel = calloc(256, sizeof(char)); + + if(argc == 11) { + xStart.d = strtod(argv[1], NULL); + xEnd.d = strtod(argv[2], NULL); + yStart.d = strtod(argv[3], NULL); + yEnd.d = strtod(argv[4], NULL); + zStart.d = strtod(argv[5], NULL); + zEnd.d = strtod(argv[6], NULL); + drawNum = strtod(argv[7], NULL); + findMaxNum = strtod(argv[8], NULL); + strcpy(fileNameKernel, argv[9]); + strcpy(uniqueLabel, argv[10]); + } else { + printf("Usage: ./sample3paramParallel.out xStart xEnd yStart yEnd zStart zEnd drawNum findMaxNum fileNameKernel uniqueLabel\n"); + exit(EXIT_FAILURE); + } + + // local parameters init + int lenLocal = drawNum / numProcs; + int iStartLocal; + iStartLocal = myid * lenLocal; + int iEndLocal; + if (myid != numProcs - 1) + { + iEndLocal = (myid + 1) * lenLocal - 1; + } + else + { + iEndLocal = drawNum; + } + + sample3paramX(xStart, xEnd, yStart, yEnd, zStart, zEnd, drawNum, findMaxNum, findMaxNum, uniqueLabel, fileNameKernel, myid, iStartLocal, iEndLocal); + sample3paramY(xStart, xEnd, yStart, yEnd, zStart, zEnd, findMaxNum, drawNum, findMaxNum, uniqueLabel, fileNameKernel, myid, iStartLocal, iEndLocal); + sample3paramZ(xStart, xEnd, yStart, yEnd, zStart, zEnd, findMaxNum, findMaxNum, drawNum, uniqueLabel, fileNameKernel, myid, iStartLocal, iEndLocal); + + // clear + free(uniqueLabel); + free(fileNameKernel); + MPI_Finalize(); + return 0; +} \ No newline at end of file diff --git a/srcTest/test1paramFPEDParallel.c b/srcTest/test1paramFPEDParallel.c index 5ddfeb4f45d0539cc5d038cdfeb9989dfb0def04..0fe0a365fa580f50cea0eb0892c86467bc675dbe 100644 --- a/srcTest/test1paramFPEDParallel.c +++ b/srcTest/test1paramFPEDParallel.c @@ -21,7 +21,9 @@ struct errorInfo { #define TESTNUMX0 500000 // #define FP // #define DEBUG -#define ERRORFILE +#ifndef ERRFILE +#define ERRFILE 0 +#endif double EXPRESSIONMPFR(double, mpfr_t); double EXPRESSIONMINE(double); @@ -51,7 +53,7 @@ struct errorInfo test1FPEDparamParallel(DL x0Start, DL x0End, unsigned long int mpfr_inits2(PRECISION, mpfrOrcle, mpfrResult, (mpfr_ptr) 0); // write error data to file - #ifdef ERRORFILE + #if ERRFILE char *directory = "./outputs"; char *suffix = "sample"; char *fileNameSample; @@ -102,7 +104,7 @@ struct errorInfo test1FPEDparamParallel(DL x0Start, DL x0End, unsigned long int if (isnormal(reUlp) != 0) { - #ifdef ERRORFILE + #if ERRFILE fprintf(f, "%le\t%le\n", x0, reUlp); #endif sumError += reUlp; @@ -122,7 +124,7 @@ struct errorInfo test1FPEDparamParallel(DL x0Start, DL x0End, unsigned long int // printf("%le\t%le\n", aveReUlp, maxReUlp); // printf("\naveReUlp = %lg\nmaxInputX0 = 0x%016lx %lg, maxReUlp = %lg\n", aveReUlp, maxInputX0.l, maxInputX0.d, maxReUlp); // } - #ifdef ERRORFILE + #if ERRFILE // fprintf(f, "\n"); // clear @@ -137,7 +139,8 @@ struct errorInfo test1FPEDparamParallel(DL x0Start, DL x0End, unsigned long int return err; } -int main(int argc, char **argv) { +int main(int argc, char **argv) +{ // parallel int myid, numProcs; MPI_Init(&argc, &argv); @@ -152,7 +155,7 @@ int main(int argc, char **argv) { unsigned long int testNumX0; x0Start.d = 1; x0End.d = 2; - + testNumX0 = TESTNUMX0; char *fileNameKernel; diff --git a/srcTest/test2paramFPEDParallel.c b/srcTest/test2paramFPEDParallel.c index 0d247c15841b026c70a9b49abcf1a9a51ea06de0..a5e26c994361a037850b5718c3b163144d0294c3 100644 --- a/srcTest/test2paramFPEDParallel.c +++ b/srcTest/test2paramFPEDParallel.c @@ -24,6 +24,9 @@ struct errorInfo #define TESTNUMX1 1024 // #define FP // #define DEBUG +#ifndef ERRFILE +#define ERRFILE 0 +#endif double EXPRESSIONMPFR(double, double, mpfr_t); double EXPRESSIONMINE(double, double); @@ -42,7 +45,7 @@ int computeResult2param(double x0, double x1, mpfr_t mpfrResult) return status; } -struct errorInfo test2paramFPEDParallel(DL x0Start, DL x0End, DL x1Start, DL x1End, unsigned long int testNumX0, unsigned long int testNumX1, const char *fileNameKernel, int myid, int i1StartLocal, int i1EndLocal) +struct errorInfo test2paramFPEDParallel(DL x0Start, DL x0End, DL x1Start, DL x1End, unsigned long int testNumX0, unsigned long int testNumX1, const char* uniqueLabel, const char *fileNameKernel, int myid, int i1StartLocal, int i1EndLocal) { // printf("myid = %d: x0Start: %lg, x0End: %lg, x1Start: %lg, x1End: %lg\n", myid, x0Start.d, x0End.d, x1Start.d, x1End.d); DL maxInputX0, maxInputX1; @@ -54,18 +57,20 @@ struct errorInfo test2paramFPEDParallel(DL x0Start, DL x0End, DL x1Start, DL x1E mpfr_t mpfrOrcle, mpfrResult; mpfr_inits2(PRECISION, mpfrOrcle, mpfrResult, (mpfr_ptr)0); - // file - // char *directory = "outputs"; - // char *suffix = "sample"; - // char *fileNameSample; - // FILE *f; - // fileNameSample = (char *) calloc(strlen(fileNameKernel) + strlen(suffix) + 128, sizeof(char)); - // sprintf(fileNameSample, "./%s/%s_%s_%d.txt", directory, fileNameKernel, suffix, myid); + // write error data to file + #if ERRFILE + char *directory = "outputs"; + char *suffix = "sample"; + char *fileNameSample; + FILE *f; + fileNameSample = (char *) calloc(strlen(directory) + strlen(uniqueLabel) + strlen(fileNameKernel) + strlen(suffix) + 128, sizeof(char)); + sprintf(fileNameSample, "%s/%s/%s_%s_%02d.txt", directory, uniqueLabel, fileNameKernel, suffix, myid); // printf("%s\n", fileNameSample); - // if ((f = fopen(fileNameSample, "w")) == NULL) { - // printf("Error opening file %s.\n", fileNameSample); - // exit(0); - // } + if ((f = fopen(fileNameSample, "w")) == NULL) { + printf("Error opening file %s.\n", fileNameSample); + exit(0); + } + #endif // loop boundary lenX0 = x0End.d - x0Start.d; @@ -75,6 +80,7 @@ struct errorInfo test2paramFPEDParallel(DL x0Start, DL x0End, DL x1Start, DL x1E // Real number average maxReUlp = 0; + aveReUlp = 0; // flag = 1; // size_t testCount = 0; sumError = 0; @@ -86,22 +92,25 @@ struct errorInfo test2paramFPEDParallel(DL x0Start, DL x0End, DL x1Start, DL x1E x0 = x0Start.d + stepX0 * i0; computeResult2param(x0, x1, mpfrResult); computeOrcle2param(x0, x1, mpfrOrcle); -#ifdef SINGLE + #ifdef SINGLE reUlp = computeUlpDiffF(mpfrOrcle, mpfrResult); -#else // compute Double ULP as default + #else // compute Double ULP as default reUlp = computeUlpDiff(mpfrOrcle, mpfrResult); -#endif + #endif // if(reUlp <= 0.5) { // reUlp = 0; // } - if (isfinite(reUlp) == 0) - { - printf("happen to NaN or inf\n"); - exit(1); - } - // fprintf(f, "%le\t%le\t%e\n", x0, x1, reUlp); + // if (isfinite(reUlp) == 0) + // { + // printf("happen to NaN or inf\n"); + // exit(1); + // } + if (isnormal(reUlp) != 0) { + #if ERRFILE + fprintf(f, "%le\t%le\n", x0, reUlp); + #endif sumError += reUlp; if (reUlp > maxReUlp) { // flag = 0; @@ -112,7 +121,6 @@ struct errorInfo test2paramFPEDParallel(DL x0Start, DL x0End, DL x1Start, DL x1E } } } - // fprintf(f, "\n"); // aveReUlp = sumError / testCount; // if(flag == 1) { // printf("all error are 0!!\n"); @@ -120,10 +128,13 @@ struct errorInfo test2paramFPEDParallel(DL x0Start, DL x0End, DL x1Start, DL x1E // printf("average ulp\tmax ulp\n"); // printf("%lg\t%lg\n", aveReUlp, maxReUlp); // printf("\naveReUlp = %lg\nmaxInputX0 = 0x%016lx %lg, maxInputX1 = 0x%016lx %lg, maxInputX2 = 0x%016lx %lg, maxReUlp = %lg\n", aveReUlp, maxInputX0.l, maxInputX0.d, maxInputX1.l, maxInputX1.d, maxInputX2.l, maxInputX2.d, maxReUlp); + #if ERRFILE + // fprintf(f, "\n"); // clear - // fclose(f); - // free(fileNameSample); + fclose(f); + free(fileNameSample); + #endif mpfr_clears(mpfrOrcle, mpfrResult, (mpfr_ptr)0); struct errorInfo err; err.sumError = sumError; @@ -151,8 +162,10 @@ int main(int argc, char **argv) x0End.d = 2; x1Start.d = 1; x1End.d = 2; + testNumX0 = TESTNUMX0; testNumX1 = TESTNUMX1; + char *fileNameKernel; fileNameKernel = calloc(256, sizeof(char)); char *uniqueLabel; @@ -191,11 +204,11 @@ int main(int argc, char **argv) printf("Usage: \tthe fixed inputs [%g %g %g %g %lu %lu] will be used\n", x0Start.d, x0End.d, x1Start.d, x1End.d, testNumX0, testNumX1); } - if (myid == 0) - { - printf("\n---------------------------------------------------start test2paramFPEDParallel\n"); - printf("Parameters: x0Start: %lg, x0End: %lg, x1Start: %lg, x1End: %lg, testNumX0 = %lu, testNumX1 = %lu, fileNameKernel: %s\n", x0Start.d, x0End.d, x1Start.d, x1End.d, testNumX0, testNumX1, fileNameKernel); - } + // if (myid == 0) + // { + // printf("\n---------------------------------------------------start test2paramFPEDParallel\n"); + // printf("Parameters: x0Start: %lg, x0End: %lg, x1Start: %lg, x1End: %lg, testNumX0 = %lu, testNumX1 = %lu, fileNameKernel: %s\n", x0Start.d, x0End.d, x1Start.d, x1End.d, testNumX0, testNumX1, fileNameKernel); + // } // local parameters init int lenX1Local = testNumX1 / numProcs; @@ -212,7 +225,7 @@ int main(int argc, char **argv) } // call the error test function - struct errorInfo err = test2paramFPEDParallel(x0Start, x0End, x1Start, x1End, testNumX0, testNumX1, fileNameKernel, myid, i1StartLocal, i1EndLocal); + struct errorInfo err = test2paramFPEDParallel(x0Start, x0End, x1Start, x1End, testNumX0, testNumX1, uniqueLabel, fileNameKernel, myid, i1StartLocal, i1EndLocal); // gather errors and find the max struct errorInfo *errs; @@ -252,7 +265,7 @@ int main(int argc, char **argv) } printf("average ulp\tmax ulp\n"); printf("%lg\t%lg\n", aveError, maxError); - printf("\naveReUlp = %lg\nmaxInputX0 = 0x%016lx %lg, maxInputX1 = 0x%016lx %lg, maxReUlp = %lg\n", aveError, maxInputX0.l, maxInputX0.d, maxInputX1.l, maxInputX1.d, maxError); + // printf("\naveReUlp = %lg\nmaxInputX0 = 0x%016lx %lg, maxInputX1 = 0x%016lx %lg, maxReUlp = %lg\n", aveError, maxInputX0.l, maxInputX0.d, maxInputX1.l, maxInputX1.d, maxError); fprintf(fErr, "average ulp\tmax ulp\n"); fprintf(fErr, "%lg\t%lg\n", aveError, maxError); fprintf(fErr, "\naveReUlp = %lg\nmaxInputX0 = 0x%016lx %lg, maxInputX1 = 0x%016lx %lg, maxReUlp = %lg\n", aveError, maxInputX0.l, maxInputX0.d, maxInputX1.l, maxInputX1.d, maxError); diff --git a/srcTest/test3paramFPEDParallel.c b/srcTest/test3paramFPEDParallel.c index 8946f61bec7ae7178d7034ddfc026584d08a1dc1..04d39b8e6cff4241350ca0b3a326bedc5272e6cb 100644 --- a/srcTest/test3paramFPEDParallel.c +++ b/srcTest/test3paramFPEDParallel.c @@ -25,6 +25,9 @@ struct errorInfo { #define TESTNUMX2 256 // #define FP // #define DEBUG +#ifndef ERRFILE +#define ERRFILE 0 +#endif double EXPRESSIONMPFR(double, double, double, mpfr_t); double EXPRESSIONMINE(double, double, double); @@ -41,7 +44,7 @@ int computeResult3param(double x0, double x1, double x2, mpfr_t mpfrResult) { return status; } -struct errorInfo test3paramFPEDParallel(DL x0Start, DL x0End, DL x1Start, DL x1End, DL x2Start, DL x2End, unsigned long int testNumX0, unsigned long int testNumX1, unsigned long int testNumX2, const char* fileNameKernel, int myid, int i2StartLocal, int i2EndLocal) { +struct errorInfo test3paramFPEDParallel(DL x0Start, DL x0End, DL x1Start, DL x1End, DL x2Start, DL x2End, unsigned long int testNumX0, unsigned long int testNumX1, unsigned long int testNumX2, const char* uniqueLabel, const char* fileNameKernel, int myid, int i2StartLocal, int i2EndLocal) { // printf("myid = %d: x0Start: %lg, x0End: %lg, x1Start: %lg, x1End: %lg, x2Start: %lg, x2End: %lg\n", myid, x0Start.d, x0End.d, x1Start.d, x1End.d, x2Start.d, x2End.d); DL maxInputX0, maxInputX1, maxInputX2; int i0, i1, i2; @@ -52,18 +55,20 @@ struct errorInfo test3paramFPEDParallel(DL x0Start, DL x0End, DL x1Start, DL x1E mpfr_t mpfrOrcle, mpfrResult; mpfr_inits2(PRECISION, mpfrOrcle, mpfrResult, (mpfr_ptr) 0); - // file - // char *directory = "outputs"; - // char *suffix = "sample"; - // char *fileNameSample; - // FILE *f; - // fileNameSample = (char *) calloc(strlen(fileNameKernel) + strlen(suffix) + 128, sizeof(char)); - // sprintf(fileNameSample, "./%s/%s_%s_%d.txt", directory, fileNameKernel, suffix, myid); + // write error data to file + #if ERRFILE + char *directory = "outputs"; + char *suffix = "sample"; + char *fileNameSample; + FILE *f; + fileNameSample = (char *) calloc(strlen(directory) + strlen(uniqueLabel) + strlen(fileNameKernel) + strlen(suffix) + 128, sizeof(char)); + sprintf(fileNameSample, "%s/%s/%s_%s_%02d.txt", directory, uniqueLabel, fileNameKernel, suffix, myid); // printf("%s\n", fileNameSample); - // if ((f = fopen(fileNameSample, "w")) == NULL) { - // printf("Error opening file %s.\n", fileNameSample); - // exit(0); - // } + if ((f = fopen(fileNameSample, "w")) == NULL) { + printf("Error opening file %s.\n", fileNameSample); + exit(0); + } + #endif // loop boundary lenX0 = x0End.d - x0Start.d; @@ -101,6 +106,9 @@ struct errorInfo test3paramFPEDParallel(DL x0Start, DL x0End, DL x1Start, DL x1E // fprintf(f, "%le\t%le\t%le\t%e\n", x0, x1, x2, reUlp); if (isnormal(reUlp) != 0) { + #if ERRFILE + fprintf(f, "%le\t%le\n", x0, reUlp); + #endif sumError += reUlp; if (reUlp > maxReUlp) { // flag = 0; @@ -113,7 +121,6 @@ struct errorInfo test3paramFPEDParallel(DL x0Start, DL x0End, DL x1Start, DL x1E } } } - // fprintf(f, "\n"); // aveReUlp = sumError / testCount; // if(flag == 1) { // printf("all error are 0!!\n"); @@ -121,10 +128,13 @@ struct errorInfo test3paramFPEDParallel(DL x0Start, DL x0End, DL x1Start, DL x1E // printf("average ulp\tmax ulp\n"); // printf("%lg\t%lg\n", aveReUlp, maxReUlp); // printf("\naveReUlp = %lg\nmaxInputX0 = 0x%016lx %lg, maxInputX1 = 0x%016lx %lg, maxInputX2 = 0x%016lx %lg, maxReUlp = %lg\n", aveReUlp, maxInputX0.l, maxInputX0.d, maxInputX1.l, maxInputX1.d, maxInputX2.l, maxInputX2.d, maxReUlp); + #if ERRFILE + // fprintf(f, "\n"); // clear - // fclose(f); - // free(fileNameSample); + fclose(f); + free(fileNameSample); + #endif mpfr_clears(mpfrOrcle, mpfrResult, (mpfr_ptr) 0); struct errorInfo err; err.sumError = sumError; @@ -154,9 +164,11 @@ int main(int argc, char **argv) { x1End.d = 2; x2Start.d = 1; x2End.d = 2; + testNumX0 = TESTNUMX0; testNumX1 = TESTNUMX1; testNumX2 = TESTNUMX2; + char *fileNameKernel; fileNameKernel = calloc(256, sizeof(char)); char *uniqueLabel; @@ -193,10 +205,11 @@ int main(int argc, char **argv) { printf("Usage: if no correct input:\n"); printf("Usage: \tthe fixed inputs [%g %g %g %g %g %g %lu %lu %lu] will be used\n", x0Start.d, x0End.d, x1Start.d, x1End.d, x2Start.d, x2End.d, testNumX0, testNumX1, testNumX2); } - if(myid == 0) { - printf("\n---------------------------------------------------start test3paramFPEDParallel\n"); - printf("Parameters: x0Start: %lg, x0End: %lg, x1Start: %lg, x1End: %lg, x2Start: %lg, x2End: %lg, testNumX0 = %lu, testNumX1 = %lu, testNumX2 = %lu, fileNameKernel: %s\n", x0Start.d, x0End.d, x1Start.d, x1End.d, x2Start.d, x2End.d, testNumX0, testNumX1, testNumX2, fileNameKernel); - } + + // if(myid == 0) { + // printf("\n---------------------------------------------------start test3paramFPEDParallel\n"); + // printf("Parameters: x0Start: %lg, x0End: %lg, x1Start: %lg, x1End: %lg, x2Start: %lg, x2End: %lg, testNumX0 = %lu, testNumX1 = %lu, testNumX2 = %lu, fileNameKernel: %s\n", x0Start.d, x0End.d, x1Start.d, x1End.d, x2Start.d, x2End.d, testNumX0, testNumX1, testNumX2, fileNameKernel); + // } // local parameters init int lenX2Local = testNumX2 / numProcs; @@ -210,7 +223,7 @@ int main(int argc, char **argv) { } // call the error test function - struct errorInfo err = test3paramFPEDParallel(x0Start, x0End, x1Start, x1End, x2Start, x2End, testNumX0, testNumX1, testNumX2, fileNameKernel, myid, i2StartLocal, i2EndLocal); + struct errorInfo err = test3paramFPEDParallel(x0Start, x0End, x1Start, x1End, x2Start, x2End, testNumX0, testNumX1, testNumX2, uniqueLabel, fileNameKernel, myid, i2StartLocal, i2EndLocal); // gather errors and find the max struct errorInfo *errs; diff --git a/srcTest/gccPerformanceTest.c b/srcTest/testPerformanceOne.c similarity index 100% rename from srcTest/gccPerformanceTest.c rename to srcTest/testPerformanceOne.c diff --git a/srcTest/testPerformanceOne.sh b/srcTest/testPerformanceOne.sh index fa7ee700a1c2bf51d734c39ddb19ffc62352b129..32f56cbb0caeb8accd00f8f13fb42a154c4d50d7 100755 --- a/srcTest/testPerformanceOne.sh +++ b/srcTest/testPerformanceOne.sh @@ -1,3 +1,4 @@ +#!/bin/bash #example: cd path/to/srcTest; taskset -c 0 ./testPerformanceOne.sh Bsplines3 origin 0 100 if [ $# == 1 ]; then @@ -26,15 +27,16 @@ fi resultFileName=result_${uniqueLabel}_${start}_${end}.txt funcName=expr_${uniqueLabel}_${suffix} -# gcc gccPerformanceTest.c binary.c ${uniqueLabel}/${funcName}.c -DFUNCNAME=${funcName} -DRUNTIME=${runtime} -I../includeTEST -lm -o gccPerformanceTest_${uniqueLabel}.exe -O3 +# gcc testPerformanceOne.c binary.c ${uniqueLabel}/${funcName}.c -DFUNCNAME=${funcName} -DRUNTIME=${runtime} -I../includeTEST -lm -o testPerformanceOne_${uniqueLabel}.exe -O3 -# make gccPerformanceTest.o -s CFLAGS="-DFUNCNAME=${funcName} -DRUNTIME=${runtime}" -gcc gccPerformanceTest.c -DFUNCNAME=${funcName} -DRUNTIME=${runtime} -I../includeTEST -c -O3 +# make testPerformanceOne.o -s CFLAGS="-DFUNCNAME=${funcName} -DRUNTIME=${runtime}" +gcc testPerformanceOne.c -DFUNCNAME=${funcName} -DRUNTIME=${runtime} -I../includeTEST -c -O3 +gcc ${uniqueLabel}/expr_${uniqueLabel}_mpfr.c -c make binary.o -s # gcc binary.c -I../includeTEST -c -O3 -gcc ${uniqueLabel}/${funcName}.c -I../includeDD -c -O3 -gcc gccPerformanceTest.o binary.o ${funcName}.o -lm -lqd -o gccPerformanceTest_${uniqueLabel}.exe -O3 -./gccPerformanceTest_${uniqueLabel}.exe ${resultFileName} ${start} ${end} > /dev/null -# rm -rf gccPerformanceTest_${uniqueLabel}.exe +gcc ${uniqueLabel}/${funcName}.c -I../includeTEST -I../includeDD -c -O3 +gcc testPerformanceOne.o binary.o ${funcName}.o expr_${uniqueLabel}_mpfr.o -lm -lqd -lmpfr -o testPerformanceOne_${uniqueLabel}.exe -O3 +./testPerformanceOne_${uniqueLabel}.exe ${resultFileName} ${start} ${end} > /dev/null +# rm -rf testPerformanceOne_${uniqueLabel}.exe ### compute the cycles of the function ${uniqueLabel} make dataClean.exe -s CFLAGS="-DRUNTIME=${runtime}" # gcc dataClean.c -DRUNTIME=${runtime} -o dataClean.exe diff --git a/srcTest/testPerformanceThree.c b/srcTest/testPerformanceThree.c new file mode 100644 index 0000000000000000000000000000000000000000..0efe49dcff5d7d90f34b3e35fc9393de3506af30 --- /dev/null +++ b/srcTest/testPerformanceThree.c @@ -0,0 +1,107 @@ +#include +#include +#include +// #include +#include +#include + +#include "common.h" + +#ifndef FUNCNAME +#define FUNCNAME doppler1 +#endif +#ifndef RUNTIME +#define RUNTIME 10000 +#endif + +double FUNCNAME(double, double, double); +/* copy: copy 'from' into 'to'; assume to is big enough */ +void copy(char to[], char from[]); + +// for performance test +extern inline __attribute__((always_inline)) unsigned long rdtscp() +{ + unsigned long a, d, c; + + __asm__ volatile("rdtscp" : "=a"(a), "=d"(d), "=c"(c)); + + return (a | (d << 32)); +} + +int main(int argc, char *argv[]) +{ + int i; + unsigned long times[RUNTIME]; + unsigned long sum; + uint64_t tic, toc; + double inputdataX0[RUNTIME], inputdataX1[RUNTIME], inputdataX2[RUNTIME]; + double result[RUNTIME], sumResult = 0, test = 1; + double data_x0Start = 0, data_x0End = 1, data_x1Start = 0, data_x1End = 1, data_x2Start = 0, data_x2End = 1; + FILE *stream_time; + char outputFile[64] = "FUNCNAME_time.txt"; // the name of the outputFile. + + srand((unsigned)time(NULL)); + if(argc == 2) + { + copy(outputFile, argv[1]); + } + if(argc == 8) + { + copy(outputFile, argv[1]); + data_x0Start = atof(argv[2]); + data_x0End = atof(argv[3]); + data_x1Start = atof(argv[4]); + data_x1End = atof(argv[5]); + data_x2Start = atof(argv[6]); + data_x2End = atof(argv[7]); + } + stream_time = fopen(outputFile, "w"); + if(stream_time == (FILE *)0) + { + printf("open file error!\n"); + exit(1); + } + + // printf("----x0Starting generating %d test data----\n", RUNTIME); + for(i = 0; i < RUNTIME; i++) + { + inputdataX0[i] = (double)rand() / ((double)RAND_MAX + 1) * ((data_x0End) - (data_x0Start)) + (data_x0Start); + inputdataX1[i] = (double)rand() / ((double)RAND_MAX + 1) * ((data_x1End) - (data_x1Start)) + (data_x1Start); + inputdataX2[i] = (double)rand() / ((double)RAND_MAX + 1) * ((data_x2End) - (data_x2Start)) + (data_x2Start); + } + // printf("----End generating %d test data----\n", RUNTIME); + + // printf("----x0Starting performance test----\n"); + for(i = 0; i < 100; i++) + { + FUNCNAME(inputdataX0[i], inputdataX1[i], inputdataX2[i]); + } + for(i = 0; i < RUNTIME; i++) + { + tic = rdtscp(); + result[i] = FUNCNAME(inputdataX0[i], inputdataX1[i], inputdataX2[i]); + toc = rdtscp(); + // printf("the %d result is %f\n", i, result[i]); + result[i] = result[i] + test; + times[i] = toc - tic; + // printf("time is %llu clock cycles\n", times[i]); + } + + // printf("----End performance test----\n"); + + sum = 0; + for(i = 0; i < RUNTIME; i++) + { + fprintf(stream_time, "%lu\n", times[i]); + sum = sum + times[i]; + sumResult = sumResult + result[i]; + } + sum = sum / RUNTIME; + printf("sumResult is %f\n", sumResult); + // printf("the performance result to be clean: %lu\n", sum); + if(fclose(stream_time) == EOF) + { + printf("close file error!\n"); + exit(1); + } +} diff --git a/srcTest/testPerformanceThree.sh b/srcTest/testPerformanceThree.sh new file mode 100755 index 0000000000000000000000000000000000000000..ff057c36dccbb711ad1dd365a03ede3e3941d127 --- /dev/null +++ b/srcTest/testPerformanceThree.sh @@ -0,0 +1,59 @@ +#!/bin/bash +#example: cd path/to/srcTest; taskset -c 0 ./testPerformanceOne.sh i6 origin 0 100 0 100 + +if [ $# == 1 ]; then + uniqueLabel=${1} + suffix=origin + x0Start=0.01 + x0End=100 + x1Start=0.01 + x1End=100 + x2Start=0.01 + x2End=100 + runtime=10000 +elif [ $# == 8 ]; then + uniqueLabel=${1} + suffix=${2} + x0Start=${3} + x0End=${4} + x1Start=${5} + x1End=${6} + x2Start=${7} + x2End=${8} + runtime=10000 +elif [ $# == 9 ]; then + uniqueLabel=${1} + suffix=${2} + x0Start=${3} + x0End=${4} + x1Start=${5} + x1End=${6} + x1Start=${7} + x1End=${8} + runtime=${9} +else + echo "please input 1, 8 or 9 parameters" + exit +fi + +resultFileName=result_${uniqueLabel}_${x0Start}_${x0End}_${x1Start}_${x1End}_${x2Start}_${x2End}.txt +funcName=expr_${uniqueLabel}_${suffix} + +# gcc testPerformanceThree.c binary.c ${uniqueLabel}/${funcName}.c -DFUNCNAME=${funcName} -DRUNTIME=${runtime} -I../includeTEST -lm -o testPerformanceTwo_${uniqueLabel}.exe -O3 + +# make testPerformanceThree.o -s CFLAGS="-DFUNCNAME=${funcName} -DRUNTIME=${runtime}" +gcc testPerformanceThree.c -DFUNCNAME=${funcName} -DRUNTIME=${runtime} -I../includeTEST -c -O3 +gcc ${uniqueLabel}/expr_${uniqueLabel}_mpfr.c -c +make binary.o -s # gcc binary.c -I../includeTEST -c -O3 +gcc ${uniqueLabel}/${funcName}.c -I../includeTEST -I../includeDD -c -O3 +gcc testPerformanceThree.o binary.o ${funcName}.o expr_${uniqueLabel}_mpfr.o -lm -lqd -lmpfr -o testPerformanceTwo_${uniqueLabel}.exe -O3 +./testPerformanceTwo_${uniqueLabel}.exe ${resultFileName} ${x0Start} ${x0End} ${x1Start} ${x1End} ${x2Start} ${x2End} > /dev/null +# rm -rf testPerformanceTwo_${uniqueLabel}.exe + +### compute the cycles of the function ${uniqueLabel} +make dataClean.exe -s CFLAGS="-DRUNTIME=${runtime}" # gcc dataClean.c -DRUNTIME=${runtime} -o dataClean.exe +sort -n ${resultFileName} > ${resultFileName}.sort +./dataClean.exe ${resultFileName}.sort > ../outputs/${uniqueLabel}/${funcName}_performance.txt +rm -rf ${resultFileName} ${resultFileName}.sort +# rm dataClean.exe + diff --git a/srcTest/testPerformanceTwo.c b/srcTest/testPerformanceTwo.c new file mode 100644 index 0000000000000000000000000000000000000000..6c4ce2e2fef8914188985c045b873be2e397cc50 --- /dev/null +++ b/srcTest/testPerformanceTwo.c @@ -0,0 +1,104 @@ +#include +#include +#include +// #include +#include +#include + +#include "common.h" + +#ifndef FUNCNAME +#define FUNCNAME i6 +#endif +#ifndef RUNTIME +#define RUNTIME 10000 +#endif + +double FUNCNAME(double, double); +/* copy: copy 'from' into 'to'; assume to is big enough */ +void copy(char to[], char from[]); + +// for performance test +extern inline __attribute__((always_inline)) unsigned long rdtscp() +{ + unsigned long a, d, c; + + __asm__ volatile("rdtscp" : "=a"(a), "=d"(d), "=c"(c)); + + return (a | (d << 32)); +} + +int main(int argc, char *argv[]) +{ + int i; + unsigned long times[RUNTIME]; + unsigned long sum; + uint64_t tic, toc; + double inputdataX0[RUNTIME], inputdataX1[RUNTIME]; + double result[RUNTIME], sumResult = 0, test = 1; + double data_x0Start = 0, data_x0End = 1, data_x1Start = 0, data_x1End = 1; + FILE *stream_time; + char outputFile[64] = "FUNCNAME_time.txt"; // the name of the outputFile. + + srand((unsigned)time(NULL)); + if(argc == 2) + { + copy(outputFile, argv[1]); + } + if(argc == 6) + { + copy(outputFile, argv[1]); + data_x0Start = atof(argv[2]); + data_x0End = atof(argv[3]); + data_x1Start = atof(argv[4]); + data_x1End = atof(argv[5]); + } + stream_time = fopen(outputFile, "w"); + if(stream_time == (FILE *)0) + { + printf("open file error!\n"); + exit(1); + } + + // printf("----x0Starting generating %d test data----\n", RUNTIME); + for(i = 0; i < RUNTIME; i++) + { + inputdataX0[i] = (double)rand() / ((double)RAND_MAX + 1) * ((data_x0End) - (data_x0Start)) + (data_x0Start); + inputdataX1[i] = (double)rand() / ((double)RAND_MAX + 1) * ((data_x1End) - (data_x1Start)) + (data_x1Start); + } + // printf("----End generating %d test data----\n", RUNTIME); + + // printf("----x0Starting performance test----\n"); + for(i = 0; i < 100; i++) + { + FUNCNAME(inputdataX0[i], inputdataX1[i]); + } + for(i = 0; i < RUNTIME; i++) + { + tic = rdtscp(); + result[i] = FUNCNAME(inputdataX0[i], inputdataX1[i]); + toc = rdtscp(); + // printf("the %d result is %f\n", i, result[i]); + result[i] = result[i] + test; + times[i] = toc - tic; + // printf("time is %llu clock cycles\n", times[i]); + } + + // printf("----End performance test----\n"); + + sum = 0; + for(i = 0; i < RUNTIME; i++) + { + fprintf(stream_time, "%lu\n", times[i]); + sum = sum + times[i]; + sumResult = sumResult + result[i]; + } + sum = sum / RUNTIME; + printf("sumResult is %f\n", sumResult); + // printf("the performance result to be clean: %lu\n", sum); + if(fclose(stream_time) == EOF) + { + printf("close file error!\n"); + exit(1); + } +} diff --git a/srcTest/testPerformanceTwo.sh b/srcTest/testPerformanceTwo.sh new file mode 100755 index 0000000000000000000000000000000000000000..59133bee5379fa4d10e2823366559b552868c5ae --- /dev/null +++ b/srcTest/testPerformanceTwo.sh @@ -0,0 +1,53 @@ +#!/bin/bash +#example: cd path/to/srcTest; taskset -c 0 ./testPerformanceOne.sh i6 origin 0 100 0 100 + +if [ $# == 1 ]; then + uniqueLabel=${1} + suffix=origin + x0Start=0.01 + x0End=100 + x1Start=0.01 + x1End=100 + runtime=10000 +elif [ $# == 6 ]; then + uniqueLabel=${1} + suffix=${2} + x0Start=${3} + x0End=${4} + x1Start=${5} + x1End=${6} + runtime=10000 +elif [ $# == 7 ]; then + uniqueLabel=${1} + suffix=${2} + x0Start=${3} + x0End=${4} + x1Start=${5} + x1End=${6} + runtime=${7} +else + echo "please input 1, 6 or 7 parameters" + exit +fi + +resultFileName=result_${uniqueLabel}_${x0Start}_${x0End}_${x1Start}_${x1End}.txt +funcName=expr_${uniqueLabel}_${suffix} + +# gcc testPerformanceTwo.c binary.c ${uniqueLabel}/${funcName}.c -DFUNCNAME=${funcName} -DRUNTIME=${runtime} -I../includeTEST -lm -o testPerformanceTwo_${uniqueLabel}.exe -O3 + +# make testPerformanceTwo.o -s CFLAGS="-DFUNCNAME=${funcName} -DRUNTIME=${runtime}" +gcc testPerformanceTwo.c -DFUNCNAME=${funcName} -DRUNTIME=${runtime} -I../includeTEST -c -O3 +gcc ${uniqueLabel}/expr_${uniqueLabel}_mpfr.c -c +make binary.o -s # gcc binary.c -I../includeTEST -c -O3 +gcc ${uniqueLabel}/${funcName}.c -I../includeTEST -I../includeDD -c -O3 +gcc testPerformanceTwo.o binary.o ${funcName}.o expr_${uniqueLabel}_mpfr.o -lm -lqd -lmpfr -o testPerformanceTwo_${uniqueLabel}.exe -O3 +./testPerformanceTwo_${uniqueLabel}.exe ${resultFileName} ${x0Start} ${x0End} ${x1Start} ${x1End} > /dev/null +# rm -rf testPerformanceTwo_${uniqueLabel}.exe + +### compute the cycles of the function ${uniqueLabel} +make dataClean.exe -s CFLAGS="-DRUNTIME=${runtime}" # gcc dataClean.c -DRUNTIME=${runtime} -o dataClean.exe +sort -n ${resultFileName} > ${resultFileName}.sort +./dataClean.exe ${resultFileName}.sort > ../outputs/${uniqueLabel}/${funcName}_performance.txt +rm -rf ${resultFileName} ${resultFileName}.sort +# rm dataClean.exe +