Skip to content

Commit

Permalink
Version 2.2 - multi-precision variant that allows double and single t…
Browse files Browse the repository at this point in the history
…o co-exist

              with _s suffix for single precision CUTEst subroutines
  • Loading branch information
dalekopera committed Dec 12, 2023
1 parent 4457a20 commit 16c19c4
Show file tree
Hide file tree
Showing 370 changed files with 9,481 additions and 13,686 deletions.
68 changes: 46 additions & 22 deletions bin/runcutest
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ Initialize_Settings() {
# PRECISION = single (single precision), = double (double precision)
PRECISION="double"

# PSUFFIX = _s (single precision), = (double precision)
PSUFFIX=""

# KEEP = 0 (discard f load module after use), = 1 (keep it)
let KEEP=0

Expand Down Expand Up @@ -152,6 +155,8 @@ Parse_Arguments() {
shift
;;
-sp|--single) PRECISION="single"
PSUFFIX="_s"
sd_opts=( ${sd_opts[@]} "-sp" )
;;
-h|--help) Display_Usage
exit 0
Expand Down Expand Up @@ -220,11 +225,11 @@ Decode_Problem() {
# Temporary working dir is passed as argument #2
cd $2
${RM} ${EXEC}/run_${PACKAGE}
${RM} ELFUN.f GROUP.f RANGE.f EXTER.f
${RM} ELFUN.o GROUP.o RANGE.o EXTER.o
${RM} ${FUNSF} ${FUNSO}
if [[ ${SIFDECODE+set} == 'set' ]]; then
echo "sifdecoder -A ${ARCH} -st ${START} ${sd_opts[@]} $1"
${SIFDECODE}/bin/sifdecoder -A ${ARCH} ${sd_opts[@]} $1
command="${SIFDECODE}/bin/sifdecoder -A ${ARCH} ${sd_opts[@]} $1"
(( show_commands )) && echo $command
$command
cd - 2>&1 >/dev/null
[[ $? != 0 ]] && exit $?
else
Expand Down Expand Up @@ -277,7 +282,7 @@ Clean_Up() {
# Tidy up the current directory, deleting all junk.
if (( KEEP == 0 )); then
${RM} ${EXEC}/run_${PACKAGE}
${RM} ELFUN.o GROUP.o RANGE.o EXTER.o
${RM} ${FUNSO}
fi
}

Expand Down Expand Up @@ -345,6 +350,11 @@ if (( show_config )); then
echo "Working in $WorkingDir"
fi

# Record problem-specfic functions and object files

FUNSF="ELFUN${PSUFFIX}.f GROUP${PSUFFIX}.f RANGE${PSUFFIX}.f EXTER${PSUFFIX}.f"
FUNSO="ELFUN${PSUFFIX}.o GROUP${PSUFFIX}.o RANGE${PSUFFIX}.o EXTER${PSUFFIX}.o"

# Decode problem if required
(( problem_set )) && Decode_Problem ${PROBLEM} $WorkingDir

Expand Down Expand Up @@ -389,7 +399,8 @@ if [[ ! -e ${LIBDIR}/libcutest.a ]]; then
[[ -w $LIBDIR ]] && let writable=1 || let writable=0
if (( writable )); then
cd ${LIBDIR}
${MAKE} -s -f ${CUTEST}/makefiles/${ARCH} cutest_silent
${MAKE} -s -f ${CUTEST}/makefiles/${ARCH} \
PRECIS=$(PRECISION) cutest_silent
cd ${WorkingDir}
else
error "${LIBDIR}/libcutest.a does not exist and
Expand All @@ -402,7 +413,7 @@ fi
[[ -w ${CUTEST}/objects ]] && let writable=1 || let writable=0
if (( writable )); then
cd ${CUTEST}/src/${PKG}
${MAKE} -s -f ${CUTEST}/makefiles/${ARCH} tools ${PKG}
${MAKE} -s -f ${CUTEST}/makefiles/${ARCH} PRECIS=${PRECISION} tools ${PKG}
else
warning "You do not have write permissions to ${CUTEST}/objects
Attempting to continue..."
Expand All @@ -427,10 +438,12 @@ if [[ ${SPECS} != "" ]]; then
fi
fi

FUNSO="ELFUN${PSUFFIX}.o GROUP${PSUFFIX}.o RANGE${PSUFFIX}.o"

# Ensure that the current test problem has been compiled.
(( OUTPUT )) && printf '\nCompiling current test problem if necessary ...\n'
(( RECOMPILE )) && ${RM} ELFUN.o GROUP.o RANGE.o EXTER.o
for i in ELFUN GROUP RANGE
(( RECOMPILE )) && ${RM} ${FUNSO}
for i in ELFUN${PSUFFIX} GROUP${PSUFFIX} RANGE${PSUFFIX}
do
if [[ ! -e ${i}.o ]]; then
${CP} ${i}.f ${i}.f90
Expand All @@ -442,16 +455,16 @@ do
fi
done

EXTER=""
[[ -e EXTER.f && ! -s EXTER.f ]] && ${RM} EXTER.f
if [[ -e EXTER.f ]]; then
${CP} EXTER.f EXTER.f90
command="${FORTRAN} ${PROBFLAGS} EXTER.f90"
[[ -e EXTER${PSUFFIX}.f && ! -s EXTER${PSUFFIX}.f ]] && ${RM} EXTER${PSUFFIX}.f
if [[ -e EXTER${PSUFFIX}.f ]]; then
${CP} EXTER${PSUFFIX}.f EXTER${PSUFFIX}.f90
command="${FORTRAN} ${PROBFLAGS} EXTER${PSUFFIX}.f90"
(( show_commands )) && echo $command
$command
[[ $? != 0 ]] && exit $?
${RM} EXTER.f90
[[ -e EXTER.o && -z EXTER.o ]] && ${RM} EXTER.o || EXTER="EXTER.o"
${RM} EXTER${PSUFFIX}.f90
[[ -e EXTER${PSUFFIX}.o && -z EXTER${PSUFFIX}.o ]] \
&& ${RM} EXTER${PSUFFIX}.o || FUNSO="${FUNSO} EXTER${PSUFFIX}.o"
fi

# The package-dependent object files are either fully in full-specified
Expand All @@ -460,7 +473,8 @@ PACKOBJS=( ${PACKOBJS} )
nobjs=${#PACKOBJS[@]}
for (( i = 0; i < nobjs ; i++ ))
do
[[ ! -e ${PACKOBJS[$i]} ]] && PACKOBJS[$i]=${CUTEST}/objects/${ARCH}/${PRECISION}/${PACKOBJS[$i]}
[[ ! -e ${PACKOBJS[$i]} ]] && \
PACKOBJS[$i]=${CUTEST}/objects/${ARCH}/${PRECISION}/${PACKOBJS[$i]}
done
cd ${WorkingDir}

Expand All @@ -477,7 +491,9 @@ if [[ ${PKG} == "matlab" ]]; then
fi
(( OUTPUT )) && printf '\nBuilding MEX file ...\n'
outputName=mcutest
command="${MEXFORTRAN} -cxx -I${CUTEST}/include -output ${outputName} ${CUTEST}/objects/${ARCH}/${PRECISION}/mcutest.o ELFUN.o GROUP.o RANGE.o ${EXTER} -L${LIBDIR} -lcutest ${ALT_LIB_PATH[@]} ${BLAS} ${LAPACK} ${PACKLIBS} -lgfortran -g"
command="${MEXFORTRAN} -cxx -I${CUTEST}/include -output ${outputName} \
${CUTEST}/objects/${ARCH}/${PRECISION}/mcutest.o ${FUNSO} -L${LIBDIR} \
-lcutest ${ALT_LIB_PATH[@]} ${BLAS} ${LAPACK} ${PACKLIBS} -lgfortran -g"
(( show_commands )) && echo "$command"
$command
Run_Post
Expand All @@ -490,8 +506,10 @@ elif [[ ${PKG} == "octave" ]]; then
exit 11
fi
(( OUTPUT )) && printf '\nBuilding MEX file ...\n'
outputName=mcutest
command="${MEXFORTRAN} --mex -I${CUTEST}/include --output ${outputName} ${CUTEST}/objects/${ARCH}/${PRECISION}/mcutest.o ELFUN.o GROUP.o RANGE.o ${EXTER} -L${LIBDIR} -lcutest ${ALT_LIB_PATH[@]} ${BLAS} ${LAPACK} ${PACKLIBS} -g"
outputName=ocutest
command="${MEXFORTRAN} --mex -I${CUTEST}/include --output ${outputName} \
${CUTEST}/objects/${ARCH}/${PRECISION}/ocutest.o ${FUNSO} \
-L${LIBDIR} -lcutest ${ALT_LIB_PATH[@]} ${BLAS} ${LAPACK} ${PACKLIBS} -g"
(( show_commands )) && echo "$command"
$command
Run_Post
Expand All @@ -500,7 +518,10 @@ elif [[ ${PKG} == "octave" ]]; then
elif [[ ${PKG} == "nomad" ]]; then
# Link all the PACK and tools files together.
(( OUTPUT )) && printf '\nLinking all the object files together ...\n'
command="${FORTRAN} ${FFLAGS} -o ${DRIVER} ELFUN.o GROUP.o RANGE.o ${EXTER} ${CUTEST}/objects/${ARCH}/${PRECISION}/${DRIVER}.o ${PACKOBJS[@]} ${ALT_LIB_PATH[@]} -L${LIBDIR} ${PACKLIBS} ${SPECIALLIBS} -lcutest ${XTRALIBS[*]} ${BLAS} ${LAPACK}"
command="${FORTRAN} ${FFLAGS} -o ${DRIVER} ${FUNSO} \
${CUTEST}/objects/${ARCH}/${PRECISION}/${DRIVER}.o ${PACKOBJS[@]} \
${ALT_LIB_PATH[@]} -L${LIBDIR} ${PACKLIBS} ${SPECIALLIBS} \
-lcutest ${XTRALIBS[*]} ${BLAS} ${LAPACK}"
(( show_commands )) && echo "$command"
$command
command="$CP $CUTEST/src/nomad/run_nomad ./"
Expand All @@ -510,7 +531,10 @@ elif [[ ${PKG} == "nomad" ]]; then
else
# Link all the PACK and tools files together.
(( OUTPUT )) && printf '\nLinking all the object files together ...\n'
command="${FORTRAN} ${FFLAGS} -o run_${PACKAGE} ELFUN.o GROUP.o RANGE.o ${EXTER} ${CUTEST}/objects/${ARCH}/${PRECISION}/${DRIVER}.o ${PACKOBJS[@]} ${ALT_LIB_PATH[@]} -L${LIBDIR} ${PACKLIBS} ${SPECIALLIBS} -lcutest ${XTRALIBS[*]} ${BLAS} ${LAPACK}"
command="${FORTRAN} ${FFLAGS} -o run_${PACKAGE} ${FUNSO} \
${CUTEST}/objects/${ARCH}/${PRECISION}/${DRIVER}.o ${PACKOBJS[@]} \
${ALT_LIB_PATH[@]} -L${LIBDIR} ${PACKLIBS} ${SPECIALLIBS} \
-lcutest ${XTRALIBS[*]} ${BLAS} ${LAPACK}"
(( show_commands )) && echo "$command"
$command
fi
Expand Down
Binary file modified doc/pdf/sif.pdf
Binary file not shown.
92 changes: 50 additions & 42 deletions include/cg_user.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@
#define NULL 0
#endif

/* added by nick gould to allow single (float) precision */

#ifdef CUTEST_SINGLE
typedef float rp_;
#else
typedef double rp_;
#endif

/*============================================================================
cg_parameter is a structure containing parameters used in cg_descent
cg_default assigns default values to these parameters */
Expand Down Expand Up @@ -56,25 +64,25 @@ typedef struct cg_parameter_struct /* user controlled parameters */

/* when relative distance from current gradient to subspace <= eta0,
enter subspace if subspace dimension = mem */
double eta0 ;
rp_ eta0 ;

/* when relative distance from current gradient to subspace >= eta1,
leave subspace */
double eta1 ;
rp_ eta1 ;

/* when relative distance from current direction to subspace <= eta2,
always enter subspace (invariant space) */
double eta2 ;
rp_ eta2 ;

/* T => use approximate Wolfe line search
F => use ordinary Wolfe line search, switch to approximate Wolfe when
|f_k+1-f_k| < AWolfeFac*C_k, C_k = average size of cost */
int AWolfe ;
double AWolfeFac ;
rp_ AWolfeFac ;

/* factor in [0, 1] used to compute average cost magnitude C_k as follows:
Q_k = 1 + (Qdecay)Q_k-1, Q_0 = 0, C_k = C_k-1 + (|f_k| - C_k-1)/Q_k */
double Qdecay ;
rp_ Qdecay ;

/* terminate after nslow iterations without strict improvement in
either function value or gradient */
Expand All @@ -84,41 +92,41 @@ typedef struct cg_parameter_struct /* user controlled parameters */
T => ||proj_grad||_infty <= max(grad_tol,initial ||grad||_infty*StopFact)
F => ||proj_grad||_infty <= grad_tol*(1 + |f_k|) */
int StopRule ;
double StopFac ;
rp_ StopFac ;

/* T => estimated error in function value is eps*Ck,
F => estimated error in function value is eps */
int PertRule ;
double eps ;
rp_ eps ;

/* factor by which eps grows when line search fails during contraction */
double egrow ;
rp_ egrow ;

/* T => attempt quadratic interpolation in line search when
|f_k+1 - f_k|/f_k <= QuadCutoff
F => no quadratic interpolation step */
int QuadStep ;
double QuadCutOff ;
rp_ QuadCutOff ;

/* maximum factor by which a quad step can reduce the step size */
double QuadSafe ;
rp_ QuadSafe ;

/* T => when possible, use a cubic step in the line search */
int UseCubic ;

/* use cubic step when |f_k+1 - f_k|/|f_k| > CubicCutOff */
double CubicCutOff ;
rp_ CubicCutOff ;

/* |f| < SmallCost*starting cost => skip QuadStep and set PertRule = FALSE*/
double SmallCost ;
rp_ SmallCost ;

/* T => check that f_k+1 - f_k <= debugtol*C_k
F => no checking of function values */
int debug ;
double debugtol ;
rp_ debugtol ;

/* if step is nonzero, it is the initial step of the initial line search */
double step ;
rp_ step ;

/* abort cg after maxit iterations */
INT maxit ;
Expand All @@ -127,15 +135,15 @@ typedef struct cg_parameter_struct /* user controlled parameters */
int ntries ;

/* maximum factor secant step increases stepsize in expansion phase */
double ExpandSafe ;
rp_ ExpandSafe ;

/* factor by which secant step is amplified during expansion phase
where minimizer is bracketed */
double SecantAmp ;
rp_ SecantAmp ;

/* factor by which rho grows during expansion phase where minimizer is
bracketed */
double RhoGrow ;
rp_ RhoGrow ;

/* maximum number of times that eps is updated */
int neps ;
Expand All @@ -147,49 +155,49 @@ typedef struct cg_parameter_struct /* user controlled parameters */
int nline ;

/* conjugate gradient method restarts after (n*restart_fac) iterations */
double restart_fac ;
rp_ restart_fac ;

/* stop when -alpha*dphi0 (estimated change in function value) <= feps*|f|*/
double feps ;
rp_ feps ;

/* after encountering nan, growth factor when searching for
a bracketing interval */
double nan_rho ;
rp_ nan_rho ;

/* after encountering nan, decay factor for stepsize */
double nan_decay ;
rp_ nan_decay ;

/*============================================================================
technical parameters which the user probably should not touch
----------------------------------------------------------------------------*/
double delta ; /* Wolfe line search parameter */
double sigma ; /* Wolfe line search parameter */
double gamma ; /* decay factor for bracket interval width */
double rho ; /* growth factor when searching for initial
rp_ delta ; /* Wolfe line search parameter */
rp_ sigma ; /* Wolfe line search parameter */
rp_ gamma ; /* decay factor for bracket interval width */
rp_ rho ; /* growth factor when searching for initial
bracketing interval */
double psi0 ; /* factor used in starting guess for iteration 1 */
double psi_lo ; /* in performing a QuadStep, we evaluate at point
rp_ psi0 ; /* factor used in starting guess for iteration 1 */
rp_ psi_lo ; /* in performing a QuadStep, we evaluate at point
betweeen [psi_lo, psi_hi]*psi2*previous step */
double psi_hi ;
double psi1 ; /* for approximate quadratic, use gradient at
rp_ psi_hi ;
rp_ psi1 ; /* for approximate quadratic, use gradient at
psi1*psi2*previous step for initial stepsize */
double psi2 ; /* when starting a new cg iteration, our initial
rp_ psi2 ; /* when starting a new cg iteration, our initial
guess for the line search stepsize is
psi2*previous step */
int AdaptiveBeta ; /* T => choose beta adaptively, F => use theta */
double BetaLower ; /* lower bound factor for beta */
double theta ; /* parameter describing the cg_descent family */
double qeps ; /* parameter in cost error for quadratic restart
rp_ BetaLower ; /* lower bound factor for beta */
rp_ theta ; /* parameter describing the cg_descent family */
rp_ qeps ; /* parameter in cost error for quadratic restart
criterion */
double qrule ; /* parameter used to decide if cost is quadratic */
rp_ qrule ; /* parameter used to decide if cost is quadratic */
int qrestart ; /* number of iterations the function should be
nearly quadratic before a restart */
} cg_parameter ;

typedef struct cg_stats_struct /* statistics returned to user */
{
double f ; /*function value at solution */
double gnorm ; /* max abs component of gradient */
rp_ f ; /*function value at solution */
rp_ gnorm ; /* max abs component of gradient */
INT iter ; /* number of iterations */
INT IterSub ; /* number of subspace iterations */
INT NumSub ; /* total number subspaces */
Expand All @@ -214,17 +222,17 @@ int cg_descent /* return:
9 (debugger is on and the function value increases)
10 (out of memory) */
(
double *x, /* input: starting guess, output: the solution */
rp_ *x, /* input: starting guess, output: the solution */
INT n, /* problem dimension */
cg_stats *Stats, /* structure with statistics (see cg_descent.h) */
cg_parameter *UParm, /* user parameters, NULL = use default parameters */
double grad_tol, /* StopRule = 1: |g|_infty <= max (grad_tol,
rp_ grad_tol, /* StopRule = 1: |g|_infty <= max (grad_tol,
StopFac*initial |g|_infty) [default]
StopRule = 0: |g|_infty <= grad_tol(1+|f|) */
double (*value) (double *, INT), /* f = value (x, n) */
void (*grad) (double *, double *, INT), /* grad (g, x, n) */
double (*valgrad) (double *, double *, INT), /* f = valgrad (g,x,n)*/
double *Work /* either size 4n work array or NULL */
rp_ (*value) (rp_ *, INT), /* f = value (x, n) */
void (*grad) (rp_ *, rp_ *, INT), /* grad (g, x, n) */
rp_ (*valgrad) (rp_ *, rp_ *, INT), /* f = valgrad (g,x,n)*/
rp_ *Work /* either size 4n work array or NULL */
) ;

void cg_default /* set default parameter values */
Expand Down
Loading

0 comments on commit 16c19c4

Please sign in to comment.