Revision 4be626c188e8c9c59520165432861ac58ea2f08b authored by Alexander Kruppa on 20 February 2014, 16:48:59 UTC, committed by Alexander Kruppa on 20 February 2014, 16:48:59 UTC
1 parent 3df61d1
factor.sh
#!/usr/bin/env bash
# Run cadofactor.py on the current machine.
# This script is recommended only for small factorizations (less than 100
# digits). For larger numbers, you should use the cadofactor.py script
# (see the documentation in that script).
#
# All partial data are put in a temp dir that is removed at the end in
# case of success. The temp dir is left here in case of failure. If
# CADO_DEBUG is set, the temp dir is never removed.
# If the environment variable $t exists, this sets the directory to use.
usage() {
cat >&2 <<EOF
Usage: $0 <integer> [options] [arguments passed to cadofactor.py]
<integer> - integer to be factored. must be at least 57 digits,
and free of small prime factors [parameters are
optimized only for 85 digits and above]
options:
-dlp - don't factor, solve dlp in GF(integer)
-t <integer> - numbers of cores to be used
-s <integer> - numbers of slave scripts to be used
-h <host1>,<host2>,...,<hostn>
- comma-separated list of hosts to use for factorization.
With -s <n>, run <n> many scripts per host.
Default: localhost
-timeout <integer>
- abort computation after this many seconds
If the shell environment variable CADO_DEBUG is set to any non-empty
string, the working directory is not deleted even if the factorization
succeeds.
If CADO_USEHOST is set to any non-empty string, the script will
listen on "*" even if all clients given with -h are on localhost.
EOF
}
# If a duration is specified, find the "timeout" binary and store its
# path and the duration in the TIMEOUT array. If no duration is specified,
# or if the timeout binary is not found, leave TIMEOUT unset.
# Returns 1 (false) if a timeout was requested and the binary was not found.
# Otherwise returns 0 (true).
# We use an array for TIMEOUT so that we can expand it to exactly 3 words on
# the resulting command line.
function find_timeout() {
local TIMEOUT_DURATION="$1"
test -z "$TIMEOUT_DURATION" && return 0
# Maybe it's not a GNU system, but with GNU coreutils installed
# with "g" prefix to all binaries
for TIMEOUT_NAME in timeout gtimeout
do
TIMEOUT_BIN="`which timeout 2>/dev/null`"
if [ -n "$TIMEOUT_BIN" ]
then
TIMEOUT[0]="$TIMEOUT_BIN"
TIMEOUT[1]="--signal=SIGINT"
TIMEOUT[2]="$TIMEOUT_DURATION"
return 0
fi
done
return 1
}
# Set "t" to a temp directory, if not already set.
# The ":" shell built-in causes variable expansion but nothing else to happen
: ${t:=`mktemp -d /tmp/cado.XXXXXXXXXX`}
# Make temp dir writable by us and readable by everyone
chmod 755 $t
n=$1
shift
if [ ! "$(grep "^[ [:digit:] ]*$" <<< $n)" ]; then
echo "Error, first parameter must be the number to factor" >&2
usage
exit 1
fi
cores=1
slaves=1
verbose=false
dlp=false
while [ -n "$1" ] ; do
if [ "$1" = "-t" ]; then
cores=$2
if [ ! "$(grep "^[ [:digit:] ]*$" <<< $cores)" ]; then
echo "Error, number of cores '$cores' is not an integer" >&2
usage
exit 1
fi
shift 2
elif [ "$1" = "-s" ]; then
slaves=$2
if [ ! "$(grep "^[ [:digit:] ]*$" <<< $slaves)" ]; then
echo "Error, number of slaves '$slaves' is not an integer" >&2
usage
exit 1
fi
shift 2
elif [ "$1" = "-h" ]; then
hostnames="$2"
shift 2
elif [ "$1" = "-timeout" ]; then
timeout="$2"
if [ ! "$(grep "^[ [:digit:] ]*$" <<< $timeout)" ]; then
echo "Error, number of seconds '$timeout' is not an integer" >&2
usage
exit 1
fi
if ! find_timeout $2
then
echo "timeout binary not found. Timeout disabled"
fi
shift 2
elif [ "$1" = "-dlp" ]; then
dlp=true
CADO_DEBUG="Yes, pleas"
shift
elif [ "$1" = "-v" ]; then
verbose=true
shift
else
break
fi
done
# Set default value
: ${hostnames:=localhost}
#########################################################################
# Set paths properly.
# Try to find out from which location this script is running:
# the install directory (i.e., where 'make install' put it),
# the build directory (where 'cmake' put it, substituting the
# CMake variables below), or in the source directory tree.
cado_prefix="@CMAKE_INSTALL_PREFIX@"
cado_source_dir="@CADO_NFS_SOURCE_DIR@"
cado_build_dir="@CADO_NFS_BINARY_DIR@"
example_subdir="@example_subdir@"
mpiexec="@MPIEXEC@"
if [ "$0" -ef "$cado_prefix/bin/factor.sh" ] ; then
# We're called in the install tree.
bindir="$cado_prefix/bin"
scriptpath="$bindir"
cadofactor="$scriptpath/cadofactor.py"
paramdir="$cado_prefix/$example_subdir"
elif [ "$0" -ef "$cado_build_dir/factor.sh" ] ; then
# We're called in the build tree.
scriptpath="$cado_source_dir/scripts/cadofactor"
paramdir="$cado_source_dir/params"
cadofactor="$scriptpath/cadofactor.py"
# Make the path absolute.
bindir="$cado_build_dir"
elif [ -f "`dirname $0`/cado_config_h.in" ] ; then
# Otherwise we're called from the source tree (or we hope so)
srcdir=$(cd "`dirname $0`" ; pwd)
call_cmake="`dirname $0`/scripts/call_cmake.sh"
unset build_tree
if [ -x "$call_cmake" ] ; then
# This should set $build_tree:
eval `cd $srcdir ; $call_cmake show`
fi
if ! [ -z "$build_tree" ] ; then
scriptpath="${srcdir}/scripts/cadofactor"
cadofactor="${scriptpath}/cadofactor.py"
paramdir="${srcdir}/params"
# Make the path absolute.
bindir=`cd "$build_tree" ; pwd`
fi
fi
if [ -z "$cadofactor" ] ; then
echo "I don't know where I am !" >&2
# but I do care!
exit 1
fi
if $dlp ; then
paramdir="${paramdir}_dl"
fi
if ! [ -d "$paramdir" ] ; then
echo "Parameter dir $paramdir not found." >&2 ; exit 1
elif ! [ -d "$bindir" ] ; then
echo "Binary dir $bindir not found." >&2 ; exit 1
elif ! [ -x "$cadofactor" ] ; then
echo "Script $cadofactor not found." >&2 ; exit 1
else
# Ok, everything looks good.
:
fi
size=${#n}
# Try n, n+1, n-1, n+2...
for ((i=1; i<=4; i=i+1)) ; do
if $dlp ; then
file="$paramdir/params.p$size"
else
file="$paramdir/params.c$size"
fi
if [ -f $file ] ; then
break
fi
size=`expr $size + \( 2 \* \( $i % 2 \) - 1 \) \* $i`
done
if [ ! -f $file ] ; then
echo "no parameter file found for c${#n} (last tried was $file)" >&2
usage
exit 1
fi
#########################################################################
[ "$CADO_DEBUG" ] && echo "(debug mode, temporary files will be kept in $t)"
# This copy is not strictly necessary (it used to be when we used the
# fixup_params_file.sh script), but it might not be a bad idea to have the
# parameter file together with the rest in the working directory, which also
# allows for easy modification of parameters for the specific factorization.
cp $file $t/param
# Sets the machine description file
if [ -z "$CADO_USEHOST" ] && echo "$hostnames" | grep -E "^(localhost, *)*localhost$" > /dev/null
then
server_address="server.address=localhost" # For the Python script
else
server_address=""
fi
mkdir $t/tmp
# $PYTHON is there to expand a shell variable having that name, if
# provided, in the case there is no python3 script in the path, or if
# one which is named otherwise, or placed in a non-prority location
# is the path, is preferred. If $PYTHON is empty, this is a no-op
"${TIMEOUT[@]}" $PYTHON $cadofactor "$t/param" N=$n tasks.execpath="$bindir" \
tasks.threads=$cores tasks.workdir="$t" slaves.hostnames="$hostnames" \
slaves.nrclients=$slaves \
slaves.scriptpath="$scriptpath" "$server_address" \
slaves.basepath="$t/client/" "$@"
rc=$?
#########################################################################
# Check result, clean up the mess afterwards.
if [ "$rc" = 0 ] ; then
echo OK
if ! [ "$CADO_DEBUG" ] ; then
rm -rf $t
fi
else
echo "FAILED ; data left in $t"
fi
exit $rc
Computing file changes ...