#!/bin/bash # This configure script is hand-generated, not auto-generated. It creates the # file kaldi.mk, which is %included by the Makefiles in the subdirectories. # The file kaldi.mk is editable by hand -- for example, you may want to # uncomment the options -O0 -DKALDI_PARANOID, or edit the DOUBLE_PRECISION # variable (to be 1 not 0). # Example command lines: # ./configure # ./configure --shared # Build shared Kaldi libraries. # ./configure --mathlib=OPENBLAS # Build and use OpenBLAS. # # Before doing this, cd to ../tools and type "make -j openblas". # ./configure --openblas-root=/usr # Use system OpenBLAS. # # Note: this is not working correctly on all platforms, do "make test" # # and look out for segmentation faults. # ./configure --atlas-root=../tools/ATLAS/build # ./configure --use-cuda=no # disable CUDA detection (will build cpu-only # # version of kaldi even on CUDA-enabled machine. # ./configure --use-cuda --cudatk-dir=/usr/local/cuda/ --cuda-arch=-arch=sm_70 # # Use cuda in /usr/local/cuda and set the arch to sm_70 # ./configure --static --fst-root=/opt/cross/armv8hf \ # --atlas-root=/opt/cross/armv8hf --host=armv8-rpi3-linux-gnueabihf # # Cross-compile for armv8hf. This assumes that you have OpenFST built # # with the armv8-rpi3-linux-gnueabihf toolchain and installed to # # /opt/cross/armv8hf. It also assumes that you have an ATLAS library # # built for the target install to /opt/cross/armv8hf and that the # # armv8-rpi3-linux-gnueabihf toolchain is available in your path. # ./configure --static --openblas-root=/opt/cross/arm-linux-androideabi \ # --fst-root=/opt/cross/arm-linux-androideabi --fst-version=1.6.9 \ # --android-incdir=/opt/cross/arm-linux-androideabi/sysroot/usr/include \ # --host=arm-linux-androideabi # # Cross-compile for Android on arm. The only difference here is the # # addition of the the --android-includes flag because the toolchains # # produced by the Android NDK don't always include the C++ stdlib # # headers in the normal cross-compile include path. # --host=aarch64-linux-android # # support for 64bit ARMv8 (AArch64) architecture in Android. # This should be incremented after any significant change to the configure # script, i.e. any change affecting kaldi.mk or the build system as a whole. CONFIGURE_VERSION=11 # We support bash version 3.2 (Macs still ship with this version as of 2019) # and above. [[ $BASH_VERSION < '3.2' ]] && { echo >&2 "bash version ${BASH_VERSION} is too old, cannot continue." \ "You won't be able to run Kaldi recipes with it anyway." \ "Please upgrade. bash version 3.2 or higher is required." exit 1; } if ! [ -x "$PWD/configure" ]; then echo 'You must run "configure" from the src/ directory.' exit 1 fi function usage { cat < LDFLAGS Additional linker flags, e.g. -L LDLIBS Additional libraries to pass to the linker, e.g. -l EOF } # E.g. Die "Invalid switch --foobar" Die() { echo >&2 "$0: FATAL:" "$@"; exit 1; } # E.g. abspath=$(rel2abs "../tools") || exit 1 # - Set 'abspath' to existing absolute path of $1, return 0. # - print empty string if path does not exist, return non-0. function rel2abs { [[ $1 ]] && cd -P "$1" 2>/dev/null && pwd } # E.g.: GetSwitchValue var --some-switch=foo # Assign variable named 'var' to 'foo'. Return 0 iff value is not empty. GetSwitchValue() { IFS='=' read -r -- _ $1 <<< "$2" && [[ ${!1} ]] } # E.g.: GetSwitchValueOrDie var --some-switch=foo # Assign variable named 'var' to 'foo'. Die with a fatal error if value is empty. GetSwitchValueOrDie() { GetSwitchValue "$@" || Die "'$2': switch requires a value. See '$0 --help'." } # E.g.: GetSwitchExistingPathOrDie var --some-switch=../tools # - Set 'var' to absolute path of '../tools' if exists, return 1. # - Die with a fatal error if path does not exist or not given in switch. GetSwitchExistingPathOrDie() { GetSwitchValueOrDie "$@" # Already sets variable named $1 to path. local path varname=$1 path=$(rel2abs "${!varname}") && [[ -d $path ]] || Die "'$2': switch must specify an existing directory. See '$0 --help'." builtin printf -v $varname %s "$path" # Assign $path to variable '$varname'. } # TODO(kkm): Kill this. `[[ ${var-} ]]' is the idiomatic equivalent in bash. # Even better, do not rely on uninitialized variables. function is_set { local myvar=${1:-notset} if [ "$myvar" == "notset" ]; then return 1 else return 0 fi } # Lowercase/uppercase argument. Only bash 4.2+ has internal faclilties for this, # and we support versions down to 3.2. lcase () { awk '{print tolower($0)}' <<<"$1" ; } ucase () { awk '{print toupper($0)}' <<<"$1" ; } function failure { echo "***configure failed: $* ***" >&2 if [ -f kaldi.mk ]; then rm kaldi.mk; fi exit 1; } function check_exists { if [[ ! -f $1 ]]; then failure "$1 not found."; fi } function check_library { local libpath=$1 local libname=$2 local libext=$3 local full_libname="$libpath/$libname.$libext" ##echo "Testing $full_libname" >&2 test -f "$full_libname" && return ; return 1 } function check_compiler { COMPILER=$1 if ! which $COMPILER >&/dev/null; then failure "$COMPILER is not installed. You need g++ >= 4.7, Apple clang >= 5.0 or LLVM clang >= 3.3." else COMPILER_VER_INFO=$($COMPILER --version 2>/dev/null) if [[ $COMPILER_VER_INFO == *"g++"* ]]; then GCC_VER=$($COMPILER -dumpversion) GCC_VER_NUM=$(echo $GCC_VER | sed 's/\./ /g' | xargs printf "%d%02d%02d") if [ $GCC_VER_NUM -lt 40700 ]; then failure "$COMPILER (g++-$GCC_VER) is not supported. You need g++ >= 4.7, Apple clang >= 5.0 or LLVM clang >= 3.3." elif [ $GCC_VER_NUM == 40801 ] || [ $GCC_VER_NUM == 40802 ]; then failure "$COMPILER (g++-$GCC_VER) is not supported. GCC 4.8.1 and 4.8.2 have a bug in the implementation of the nth_element algorithm provided by the standard library. This will cause Kaldi to crash (make test would fail). Please use another C++ compiler with C++11 support. You need g++ >= 4.7, Apple clang >= 5.0 or LLVM clang >= 3.3." fi elif [[ $COMPILER_VER_INFO == *"Apple"* ]]; then CLANG_VER=$(echo $COMPILER_VER_INFO | grep version | sed "s/.*version \([0-9\.]*\).*/\1/") CLANG_VER_NUM=$(echo $COMPILER_VER_INFO | grep version | sed "s/.*clang-\([0-9]*\).*/\1/") if [ $CLANG_VER_NUM -lt 500 ]; then failure "$COMPILER (Apple clang-$CLANG_VER) is not supported. You need g++ >= 4.7, Apple clang >= 5.0 or LLVM clang >= 3.3." fi elif [[ $COMPILER_VER_INFO == *"LLVM"* ]]; then CLANG_VER=$(echo $COMPILER_VER_INFO | grep version | sed "s/.*version \([0-9\.]*\).*/\1/") CLANG_VER_NUM=$(echo $CLANG_VER | sed 's/\./ /g' | xargs printf "%d%02d") if [ $CLANG_VER_NUM -lt 303 ]; then failure "$COMPILER (LLVM clang-$CLANG_VER) is not supported. You need g++ >= 4.7, Apple clang >= 5.0 or LLVM clang >= 3.3." fi fi fi } function check_for_slow_expf { # We cannot run this test if we are cross compiling. if [[ "$TARGET_ARCH" == "`uname -m`" ]] ; then cd probe rm -f exp-test make -f Makefile.slow_expf 1>/dev/null ./exp-test if [ $? -eq 1 ]; then echo "*** WARNING: expf() seems to be slower than exp() on your machine. This is a known bug in old versions of glibc. Please consider updating glibc. ***" echo "*** Kaldi will be configured to use exp() instead of expf() in base/kaldi-math.h Exp() routine for single-precision floats. ***" echo "CXXFLAGS += -DKALDI_NO_EXPF" >> ../kaldi.mk fi cd .. fi } # MKL functions function linux_configure_mkllibdir { local mklroot=$1 if [ -d $mklroot/lib/em64t ]; then echo $mklroot/lib/em64t elif [ -d $mklroot/lib/intel64 ]; then echo $mklroot/lib/intel64 else return 1; fi } function linux_configure_mkl_includes { test -d $1/include && echo "$1/include" && return; test -d $2/../../include && echo "$2/../../include" && return; failure "Could not find the MKL include directory" } function linux_configure_mkl_libraries { local mkllibdir=$1 local static=$2 local threaded=$3 local mplib=$4 declare -A mkl_libs mkl_libs=( [sequential]="mkl_intel_lp64 mkl_core mkl_sequential" [gomp]="mkl_intel_lp64 mkl_core mkl_gnu_thread" [iomp]="mkl_intel_lp64 mkl_core mkl_intel_thread " [tbb]="mkl_intel_lp64 mkl_core mkl_tbb_thread " ) if [ -z "${mkl_libs[$threaded]}" ]; then echo >&2 "Unknown threading mode: $threaded" return 1; fi local linkline="" if ! $static ; then linkline="-L$mkllibdir -Wl,-rpath=$mkllibdir" for file in ${mkl_libs[$threaded]}; do local libfile=$mkllibdir/lib$file.so check_exists $libfile linkline+=" -l$file " done else if [ $threaded == "sequential" ] ; then test -f "$mkllibdir/libmkl_solver_lp64.a" && \ linkline="$linkline $mkllibdir/libmkl_solver_lp64.a" else test -f "$mkllibdir/libmkl_solver_lp64_sequential.a" && \ linkline="$linkline $mkllibdir/libmkl_solver_lp64_sequential.a" fi linkline="$linkline -Wl,--start-group" for file in ${mkl_libs[$threaded]}; do local libfile=$mkllibdir/lib${file}.a check_exists $libfile linkline="$linkline $libfile" done linkline="$linkline -Wl,--end-group " fi echo "$linkline" } function linux_configure_mkl_extra { local static=$1 local threaded=$2 declare -A extra_libs extra_libs=( [sequential]="-ldl -lpthread -lm" [gomp]="-lgomp -ldl -lpthread -lm" [iomp]="-ldl -lpthread -lm" [tbb]=" -ldl -lpthread -lm " ) echo "$linkline ${extra_libs[$threaded]}" } function linux_configure_mkl_threadinglibdir { local library=$1 local mklroot=$2 local mkllibdir=$3 local libexts=$4 ##First we try to use the library in the same directory ##where the mkl libraries reside ##Afterwards, just try some possibilities for different MKL layouts for libext in $libexts; do check_library $mkllibdir "lib$library" $libext \ && echo `readlink -f $mkllibdir` && return 0 local testdir=`(cd $mklroot; cd ..; cd lib/intel64;pwd)` test -d $testdir && check_library $testdir "lib$library" $libext && echo `readlink -f $testdir` && return 0; local testdir=`(cd $mklroot; cd ..; cd lib/em64t;pwd)` test -d $testdir && check_library $testdir "lib$library" $libext && echo `readlink -f $testdir` && return 0; local testdir=`(cd $mkllibdir; cd ../../..; cd lib/intel64;pwd)` test -d $testdir && check_library $testdir "lib$library" $libext && echo `readlink -f $testdir` && return 0; local testdir=`(cd $mklroot; cd ../../..; cd lib/em64t;pwd)` test -d $testdir && check_library $testdir "lib$library" $libext && echo `readlink -f $testdir` && return 0; done #failure "Could not find the library iomp5, use the configure switch --omp-libdir" return 1 } function linux_configure_mkl_threading { local mklroot=$1 local mkllibdir=$2 local static=$3 local threading=$4 declare -A libs libs=( [sequential]="" [gomp]="" [iomp]="iomp5" [tbb]="tbb" ) echo >&2 "Configuring MKL threading as $threading" library=${libs[$threading]} if [ -z "$library" ]; then return 0 fi if ! is_set $OMPLIBDIR ; then if $static ; then OMPLIBDIR=`linux_configure_mkl_threadinglibdir $library "$MKLROOT" "$MKLLIBDIR" "a"` else OMPLIBDIR=`linux_configure_mkl_threadinglibdir $library "$MKLROOT" "$MKLLIBDIR" "so"` fi fi check_library $OMPLIBDIR "lib$library" "a" || \ check_library $OMPLIBDIR "lib$library" "so" || \ failure "Could not find the $library library, have your tried the --omp-libdir switch?" OMP_LINK_LINE='' # TODO(arnab): in the following conditional, the $static_math test is # needed since the OpenMP library is assumed to be dynamic. if [ "$OMPLIBDIR" != "$MKLLIBDIR" ] ; then OMP_LINK_LINE="-L${OMPLIBDIR}" fi #if the libiomp5 library is dynamic, we add the rpath attribute if ! $static_math ; then OMP_LINK_LINE="$OMP_LINK_LINE -Wl,-rpath=$OMPLIBDIR -l$library" else OMP_LINK_LINE="$OMP_LINK_LINE -Wl,-Bstatic -l$library -Wl,-Bdynamic" fi echo "$OMP_LINK_LINE" } # CUDA is used only in selected directories including src/cudamatrix, src/nnet* # and src/chain*. It is used to accelerate the neural network training. # The rest of Kaldi runs on CPUs. function configure_cuda { # Check for CUDA toolkit in the system if [ ! -d "$CUDATKDIR" ]; then for base in /usr/local/share/cuda /usr/local/cuda /usr/; do if [ -f $base/bin/nvcc ]; then CUDATKDIR=$base fi done fi if [ -d "$CUDATKDIR" ]; then if [ ! -f $CUDATKDIR/bin/nvcc ]; then failure "Cannnot find nvcc in CUDATKDIR=$CUDATKDIR" fi if [[ "$TARGET_ARCH" != "`uname -m`" ]] ; then failure "Cannot cross compile with CUDA support" fi # Determine 'CUDA_ARCH', CUDA_VERSION=$($CUDATKDIR/bin/nvcc -V | tr '.,' '_ ' | awk '/release/{sub(/.*release/,""); print $1;}') # MAJOR_MINOR, if [ -z "$CUDA_VERSION" ] ; then echo "Cannot figure out CUDA_VERSION from the nvcc output. Either your CUDA is too new or too old." exit 1 fi COMPILER_VER_INFO=$($CXX --version 2>/dev/null) if [[ $COMPILER_VER_INFO == *"g++"* ]]; then GCC_VER=$($COMPILER -dumpversion) GCC_VER_NUM=$(echo $GCC_VER | sed 's/\./ /g' | xargs printf "%d%02d%02d") case $CUDA_VERSION in 7_*) MIN_UNSUPPORTED_GCC_VER="5.0" MIN_UNSUPPORTED_GCC_VER_NUM=50000; CUSOLVER=false ;; 8_*) MIN_UNSUPPORTED_GCC_VER="6.0" MIN_UNSUPPORTED_GCC_VER_NUM=60000; CUSOLVER=false ;; 9_0) MIN_UNSUPPORTED_GCC_VER="7.0" MIN_UNSUPPORTED_GCC_VER_NUM=70000; CUSOLVER=false ;; 9_1) MIN_UNSUPPORTED_GCC_VER="7.0" MIN_UNSUPPORTED_GCC_VER_NUM=70000; CUSOLVER=true ;; 9_2 | 9_* | 10_0) MIN_UNSUPPORTED_GCC_VER="8.0" MIN_UNSUPPORTED_GCC_VER_NUM=80000; CUSOLVER=true ;; 10_1 | 10_*) MIN_UNSUPPORTED_GCC_VER="9.0" MIN_UNSUPPORTED_GCC_VER_NUM=90000; CUSOLVER=true ;; *) echo "Unsupported CUDA_VERSION (CUDA_VERSION=$CUDA_VERSION), please report it to Kaldi mailing list, together with 'nvcc -h' or 'ptxas -h' which lists allowed -gencode values..."; exit 1; ;; esac if [ $GCC_VER_NUM -ge $MIN_UNSUPPORTED_GCC_VER_NUM ]; then failure "CUDA $CUDA_VERSION does not support $CXX (g++-$GCC_VER). You need g++ < $MIN_UNSUPPORTED_GCC_VER." fi fi if [ -z "$CUDA_ARCH" ]; then case `uname -m` in x86_64|ppc64le) case $CUDA_VERSION in 5_5) CUDA_ARCH="-gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=sm_35" ;; 6_*) CUDA_ARCH="-gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=sm_35 -gencode arch=compute_50,code=sm_50" ;; 7_*) CUDA_ARCH="-gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=sm_35 -gencode arch=compute_50,code=sm_50 -gencode arch=compute_52,code=sm_52" ;; 8_*) CUDA_ARCH="-gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=sm_35 -gencode arch=compute_50,code=sm_50 -gencode arch=compute_52,code=sm_52 -gencode arch=compute_60,code=sm_60 -gencode arch=compute_61,code=sm_61" ;; 9_*) CUDA_ARCH="-gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=sm_35 -gencode arch=compute_50,code=sm_50 -gencode arch=compute_52,code=sm_52 -gencode arch=compute_60,code=sm_60 -gencode arch=compute_61,code=sm_61 -gencode arch=compute_70,code=sm_70" ;; 10_*) CUDA_ARCH="-gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=sm_35 -gencode arch=compute_50,code=sm_50 -gencode arch=compute_52,code=sm_52 -gencode arch=compute_60,code=sm_60 -gencode arch=compute_61,code=sm_61 -gencode arch=compute_70,code=sm_70 -gencode arch=compute_75,code=sm_75" ;; *) echo "Unsupported CUDA_VERSION (CUDA_VERSION=$CUDA_VERSION), please report it to Kaldi mailing list, together with 'nvcc -h' or 'ptxas -h' which lists allowed -gencode values..."; exit 1 ;; esac ;; aarch64) case $CUDA_VERSION in 7_*) CUDA_ARCH="-gencode arch=compute_53,code=sm_53" ;; 8_*|9_*) CUDA_ARCH="-gencode arch=compute_53,code=sm_53 -gencode arch=compute_62,code=sm_62" ;; 10_*) CUDA_ARCH="-gencode arch=compute_53,code=sm_53 -gencode arch=compute_62,code=sm_62 -gencode arch=compute_72,code=sm_72" ;; *) echo "Unsupported CUDA_VERSION (CUDA_VERSION=$CUDA_VERSION), please report it to Kaldi mailing list, together with 'nvcc -h' or 'ptxas -h' which lists allowed -gencode values..."; exit 1 ;; esac ;; *) echo "Unsupported architecture for use of Kaldi with CUDA. Please report it to Kaldi mailing list."; exit 1 ;; esac fi echo "Using CUDA toolkit $CUDATKDIR (nvcc compiler and runtime libraries)" echo >> kaldi.mk echo "# CUDA configuration" >> kaldi.mk echo >> kaldi.mk echo CUDA = true >> kaldi.mk echo CUDATKDIR = $CUDATKDIR >> kaldi.mk echo "CUDA_ARCH = $CUDA_ARCH" >> kaldi.mk echo >> kaldi.mk # 64bit/32bit? We do not support cross compilation with CUDA so, use direct # calls to uname -m here if [ "`uname -m`" == "x86_64" ]; then if [ "`uname`" == "Darwin" ]; then sed 's/lib64/lib/g' < makefiles/cuda_64bit.mk >> kaldi.mk else cat makefiles/cuda_64bit.mk >> kaldi.mk fi elif [ "`uname -m`" == "aarch64" ]; then cat makefiles/cuda_64bit.mk >> kaldi.mk elif [ "`uname -m`" == "ppc64le" ]; then cat makefiles/cuda_64bit.mk >> kaldi.mk else echo "\ WARNING: CUDA will not be used! CUDA is not supported with 32-bit builds." exit 1; fi #add cusolver flags for newer toolkits if [ "$CUSOLVER" == "true" ]; then echo "CUDA_LDLIBS += -lcusolver" >> kaldi.mk fi else echo "\ WARNING: CUDA will not be used! If you have already installed cuda drivers and CUDA toolkit, try using the --cudatk-dir= option. A GPU and CUDA are required to run neural net experiments in a realistic time." fi } function linux_configure_speex { # Check whether the user has called tools/extras/install_speex.sh or not [ ! -z "$SPEEXROOT" ] || SPEEXROOT=`pwd`/../tools/speex [ ! -z "$SPEEXLIBDIR" ] || SPEEXLIBDIR="$SPEEXROOT"/lib [ ! -z "$SPEEXINCDIR" ] || SPEEXINCDIR="$SPEEXROOT"/include static_speex=$1 if [ "foo"$static_speex == "foo" ]; then static_speex=false fi if $static_speex; then spx_type=a else spx_type=so fi if [ ! -f "$SPEEXLIBDIR/libspeex.${spx_type}" ];then echo "\ INFO: Configuring Kaldi not to link with Speex. Don't worry, it's only needed if you intend to use 'compress-uncompress-speex', which is very unlikely." return fi if [ -f $SPEEXINCDIR/speex/speex.h ]; then echo >> kaldi.mk echo CXXFLAGS += -DHAVE_SPEEX -I${SPEEXINCDIR} >> kaldi.mk if $static_speex; then echo LDLIBS += $SPEEXLIBDIR/libspeex.a else echo LDLIBS += -L${SPEEXLIBDIR} -lspeex >> kaldi.mk echo LDFLAGS += -Wl,-rpath=${SPEEXLIBDIR} >> kaldi.mk fi echo "Successfully configured with Speex at $SPEEXROOT, (static=[$static_speex])" else echo "Speex will not be used. If you want to use it, run tools/extras/install_speex.sh first." fi } function linux_configure_atlas_failure { echo ATLASINC = $ATLASROOT/include >> kaldi.mk echo ATLASLIBS = [somewhere]/liblapack.a [somewhere]/libcblas.a [somewhere]/libatlas.a [somewhere]/libf77blas.a $ATLASLIBDIR >> kaldi.mk echo >> kaldi.mk echo "** $* ***" echo "** ERROR **" echo "** Configure cannot proceed automatically." echo "** If you know that you have ATLAS installed somewhere on your machine, you" echo "** may be able to proceed by replacing [somewhere] in kaldi.mk with a directory." echo "** If you have sudo (root) access you could install the ATLAS package on your" echo "** machine, e.g. 'sudo apt-get install libatlas-dev libatlas-base-dev' or" echo "** 'sudo yum install atlas.x86_64' or 'sudo zypper install libatlas3-devel'," echo "** or on cygwin, install atlas from the installer GUI; and then run ./configure" echo "** again." echo "**" echo "** Otherwise (or if you prefer OpenBLAS for speed), you could go the OpenBLAS" echo "** route: cd to ../tools, type 'extras/install_openblas.sh', cd back to here," echo "** and type './configure --mathlib=OPENBLAS'" exit 1; } function linux_atlas_check_static { # will exit with success if $dir seems to contain ATLAS libraries with # right architecture (compatible with default "nm") echo "int main(void) { return 0; }" > test_linking.cc; if [ -f $dir/libatlas.a ]; then # candidate... # Note: on the next line, the variable assignment # LANG=en_US should apply just to the program called on that line. if LANG=en_US $CXX -o test_linking test_linking.cc -u ATL_flushcache $dir/libatlas.a 2>&1 | grep -i "incompatible" >/dev/null; then echo "Directory $dir may contain ATLAS libraries but seems to be wrong architecture"; rm test_linking test_linking.cc 2>/dev/null return 1; fi rm test_linking test_linking.cc 2>/dev/null return 0; else rm test_linking.cc return 1; fi } function linux_configure_atlas_generic { # You pass in a directory (e.g. /usr/lib/atlas-base) and a suffix (e.g. so.3.0) # and it tries to find ATLAS libraries with that dir and suffix. On success it # returns 0; on failure, it returns 1. dir=$1 suffix=$2 ATLASLIBS="$dir/libatlas.$suffix $dir/libf77blas.$suffix $dir/libcblas.$suffix $dir/liblapack_atlas.$suffix" for f in $ATLASLIBS; do [ ! -f $f ] && return 1; done lapacklib=$(echo $ATLASLIBS | awk '{print $NF}') if ! nm --dynamic $lapacklib | grep ATL_cgetrf >/dev/null; then echo "configure: failed to find symbol ATL_cgetrf in library $lapacklib" exit 1; fi libdir=$(dirname $(echo $ATLASLIBS | awk '{print $1}')) [ -z "$libdir" ] && echo "Error getting libdir in linux_configure_atlas_generic: dir=$dir,suffix=$suffix" && exit 1; echo ATLASINC = $ATLASROOT/include >> kaldi.mk echo ATLASLIBS = $ATLASLIBS -Wl,-rpath=$libdir >> kaldi.mk echo >> kaldi.mk echo "Successfully configured ATLAS with ATLASLIBS=$ATLASLIBS" } function linux_configure_atlas_redhat_fat { # This is for when only two so-called 'fat' ATLAS libs are provided: # libsatlas.so.3 and libtatlas.so.3. # See http://stackoverflow.com/questions/13439296/build-shared-libraries-in-atlas. m=$1 # 64 or empty. ATLASLIBS="/usr/lib$m/atlas/libsatlas.so.3 /usr/lib$m/atlas/libtatlas.so.3" for f in $ATLASLIBS; do [ ! -f $f ] && return 1; done libdir=$(dirname $(echo $ATLASLIBS | awk '{print $1}')) [ -z "$libdir" ] && echo "Error getting libdir in linux_configure_atlas_redhat_fat" && exit 1; echo ATLASINC = $ATLASROOT/include >> kaldi.mk echo ATLASLIBS = $ATLASLIBS -Wl,-rpath=$libdir >> kaldi.mk echo >> kaldi.mk echo "Successfully configured for red hat [dynamic libraries, fat] with ATLASLIBS =$ATLASLIBS" } function linux_configure_atlas_static { if $threaded_atlas; then pt=pt; else pt=""; fi if [ -z $ATLASLIBDIR ]; then # Note: it'll pick up the last one below. for dir in /usr{,/local}/lib{64,}{,/atlas,/atlas-sse2,/atlas-sse3} \ /usr/local/atlas/lib{,64} `pwd`/../tools/ATLAS/build/install/lib/ $ATLASROOT/lib; do linux_atlas_check_static && ATLASLIBDIR=$dir done if [ -z $ATLASLIBDIR ]; then # Note: it'll pick up the last one below. echo "Could not find libatlas.a in any of the generic-Linux places, but we'll try other stuff..." return 1; fi elif [ ! -f $ATLASLIBDIR/libatlas.a ]; then echo "Could not find libatlas.a in '$ATLASLIBDIR'" return 1; fi echo "Validating presence of ATLAS libs in $ATLASLIBDIR" ATLASLIBS= # The Lapack part of ATLAS seems to appear under various different names.. but it # should always have symbols like ATL_cgetrf and clapack_cgetrf defined, so we test for this. for libname in liblapack liblapack_atlas libclapack; do if [ -f $ATLASLIBDIR/${libname}.a -a "$ATLASLIBS" == "" ]; then if nm $ATLASLIBDIR/${libname}.a | grep ATL_cgetrf >/dev/null && \ nm $ATLASLIBDIR/${libname}.a | grep clapack_cgetrf >/dev/null; then ATLASLIBS=$ATLASLIBDIR/${libname}.a echo "Using library $ATLASLIBS as ATLAS's CLAPACK library." fi fi done if [ "$ATLASLIBS" == "" ]; then echo Could not find any libraries $ATLASLIBDIR/{liblapack,liblapack_atlas,libclapack} that seem to be an ATLAS CLAPACK library. return 1; fi for x in lib${pt}cblas.a libatlas.a lib${pt}f77blas.a; do if [ ! -f $ATLASLIBDIR/$x ]; then echo "Configuring static ATLAS libraries failed: Could not find library $x in directory $ATLASLIBDIR" return 1; fi ATLASLIBS="$ATLASLIBS $ATLASLIBDIR/$x" done if $threaded_atlas; then ATLASLIBS="$ATLASLIBS"; fi echo ATLASINC = $ATLASROOT/include >> kaldi.mk echo ATLASLIBS = $ATLASLIBS >> kaldi.mk echo >> kaldi.mk echo "Successfully configured for Linux [static libraries] with ATLASLIBS =$ATLASLIBS" } ############################# CONFIGURATION ############################# # If configuration sets any of these variables, we will switch the external # math library. Here we unset them so that we can check later. #TODO(kkm): Maybe allow env vars to provide defaults? ATLASROOT= CLAPACKROOT= MATHLIB= MKLLIBDIR= MKLROOT= OPENBLASROOT= # This variable identifies the type of system where built programs and # libraries will run. It is set by the configure script when cross compiling. HOST= # These environment variables can be used to override the default toolchain. CXX=${CXX:-g++} AR=${AR:-ar} AS=${AS:-as} RANLIB=${RANLIB:-ranlib} # These environment variables can be used to provide additional flags to the # compiler/linker. We want these flags to override the flags determined by the # configure script, so we append them to the appropriate variables (CXXFLAGS, # LDFLAGS and LDLIBS) after those variables are set by the configure script. ENV_CXXFLAGS=$CXXFLAGS ENV_LDFLAGS=$LDFLAGS ENV_LDLIBS=$LDLIBS # Default configuration double_precision=false dynamic_kaldi=false use_cuda=true static_fst=false static_math=false threaded_atlas=false mkl_threading=sequential android=false FSTROOT=`rel2abs ../tools/openfst` CUBROOT=`rel2abs ../tools/cub` # Save the command line to include in kaldi.mk cmd_line="$0 $@" while [ $# -gt 0 ]; do case "$1" in --help) usage; exit 0 ;; --version) echo $CONFIGURE_VERSION; exit 0 ;; --static) dynamic_kaldi=false; static_math=true; static_fst=true; shift ;; --shared) dynamic_kaldi=true; static_math=false; static_fst=false; shift ;; --double-precision) double_precision=true; shift ;; --double-precision=yes) double_precision=true; shift ;; --double-precision=no) double_precision=false; shift ;; --atlas-root=*) GetSwitchExistingPathOrDie ATLASROOT "$1" shift ;; --threaded-atlas) threaded_atlas=true; shift ;; --threaded-atlas=yes) threaded_atlas=true; shift ;; --threaded-atlas=no) threaded_atlas=false; shift ;; --threaded-math) threaded_atlas=true; mkl_threading=iomp shift ;; --threaded-math=yes) threaded_atlas=true; mkl_threading=iomp shift ;; --threaded-math=no) threaded_atlas=false; mkl_threading=sequential shift ;; --use-cuda) use_cuda=true; shift ;; --use-cuda=yes) use_cuda=true; shift ;; --use-cuda=no) use_cuda=false; shift ;; --static-math) static_math=true; shift ;; --static-math=yes) static_math=true; shift ;; --static-math=no) static_math=false; shift ;; --static-fst) static_fst=true; shift ;; --static-fst=yes) static_fst=true; shift ;; --static-fst=no) static_fst=false; shift ;; --mkl-threading=sequential) threaded_atlas=false; mkl_threading=sequential; shift ;; --mkl-threading=*) GetSwitchValueOrDie mkl_threading "$1" threaded_atlas=true; shift ;; --fst-root=*) GetSwitchExistingPathOrDie FSTROOT "$1" shift ;; --cub-root=*) GetSwitchExistingPathOrDie CUBROOT "$1" shift ;; --clapack-root=*) GetSwitchExistingPathOrDie CLAPACKROOT "$1" shift ;; --openblas-root=*) GetSwitchExistingPathOrDie OPENBLASROOT "$1" shift ;; --mkl-root=*) GetSwitchExistingPathOrDie MKLROOT "$1" shift ;; --mkl-libdir=*) GetSwitchExistingPathOrDie MKLLIBDIR "$1" shift ;; --speex-root=*) GetSwitchExistingPathOrDie SPEEXROOT "$1" shift ;; --speex-libdir=*) GetSwitchExistingPathOrDie SPEEXLIBDIR "$1" shift ;; --speex-incdir=*) GetSwitchExistingPathOrDie SPEEXINCDIR "$1" shift ;; --omp-libdir=*) GetSwitchExistingPathOrDie OMPLIBDIR "$1" shift ;; --mathlib=*) GetSwitchValueOrDie MATHLIB "$1" shift ;; --cudatk-dir=*) # CUDA is used in src/cudamatrix and src/nnet{,bin} only. GetSwitchExistingPathOrDie CUDATKDIR "$1" shift ;; --cuda-arch=*) GetSwitchValueOrDie CUDA_ARCH "$1" shift;; --fst-version=*) GetSwitchValueOrDie OPENFST_VER "$1" shift;; --host=*) # The type of system where built programs and libraries will run. # It should be in the format cpu-vendor-os. If specified, this script # will infer the target architecture from the specified host triple. GetSwitchValueOrDie HOST "$1" shift ;; --android-incdir=*) android=true; threaded_math=false; static_math=true; static_fst=true; dynamic_kaldi=false; MATHLIB='OPENBLAS'; GetSwitchExistingPathOrDie ANDROIDINC "$1" shift;; *) echo "Unknown argument: $1, exiting"; usage; exit 1 ;; esac done # The idea here is that if you change the configuration options from using # CUDA to not using it, or vice versa, we want to recompile all parts of the # code that may use a GPU. Touching this file is a way to force this. touch cudamatrix/cu-common.h 2>/dev/null if $android && [[ "$CXX" != *clang++* ]] ; then failure "Android build requires clang++. Make sure you have clang++ installed on your system and then override the default compiler by setting CXX, e.g. CXX=clang++ ./configure" fi # If HOST is set # 1. We prepend it to CXX, AR, AS and RANLIB. # 2. We parse the target architecture from the HOST triple. # Otherwise we set the target architecture to the output of `uname -m`. if is_set $HOST; then CXX="$HOST-$CXX" AR="$HOST-$AR" AS="$HOST-$AS" RANLIB="$HOST-$RANLIB" # The host triple will be something like "armv8-rpi3-linux-gnueabihf". We # need the first field which is the target architecture for this build. The # following command will take the host triple "armv8-rpi3-linux-gnueabihf" # and return ["armv8", "rpi3", "linux", "gnueabihf"] in PARTS. IFS='-' read -ra PARTS <<< "$HOST" # The first field in the PARTS list is the target architecture. TARGET_ARCH="$PARTS" if [[ "$TARGET_ARCH" != aarch64* && "$TARGET_ARCH" != arm* && "$TARGET_ARCH" != ppc64le && \ "$TARGET_ARCH" != x86* && "$TARGET_ARCH" != i686* ]] ; then # We currently only support building for x86[_64], arm*, aarch64* and ppc64le. # If TARGET_ARCH was read from the HOST variable, it must be one of these. failure "$TARGET_ARCH is not a supported architecture. Supported architectures: x86[_64], arm*, aarch64*, ppc64le." fi else TARGET_ARCH="`uname -m`" fi #------------------------------------------------------------------------------ # Matrix algebra library selection and validation. #-------------- declare -a mathlibs # Contains e. g. 'atlas', 'mkl' declare -a incompat # Contains mutually-inconsistent switches, if any. auto_lib= # Deduced lib name, used when $MATHLIB is not set. # Validate the (optionally) provided MATHLIB value. case $MATHLIB in ''|ATLAS|CLAPACK|MKL|OPENBLAS) : ;; *) failure "Unknown --mathlib='${MATHLIB}'. Supported libs: ATLAS CLAPACK MKL OPENBLAS" ;; esac # See which library-root switches are set, what mathlib they imply, and whether # there are any conflicts betweeh the switches. [[ $MKLLIBDIR || $MKLROOT ]] && { mathlibs+=(mkl); auto_lib=MKL; } [[ $CLAPACKROOT ]] && { mathlibs+=(clapack); auto_lib=CLAPACK; } [[ $OPENBLASROOT ]] && { mathlibs+=(openblas); auto_lib=OPENBLAS; } [[ $ATLASROOT ]] && { mathlibs+=(atlas); auto_lib=ATLAS; } # When --mathlib= is explicitly provided, and some mathlib(s) deduced, but # MATHLIB is not among them, record a conflict for the --mathlib= value. shopt -s nocasematch [[ $MATHLIB && $mathlibs && ! " ${mathlibs[@]} " =~ " $MATHLIB " ]] && incompat+=(--mathlib=$MATHLIB) shopt -u nocasematch # If more than one library specified, or a conflict has been recorded above # already, then add all deduced libraries as conflicting options (not all may # be conflicting sensu stricto, but let the user deal with it). if [[ ${#mathlibs[@]} -gt 1 || $incompat ]]; then for libpfx in "${mathlibs[@]}"; do # Handle --mkl-libdir out of common pattern. [[ $libpfx == mkl && $MKLLIBDIR ]] && incompat+=(--mkl-libdir=) # All other switches follow the pattern --$libpfx-root. incompat+=(--$(lcase $libpfx)-root=) done failure "Incompatible configuration switches: ${incompat[@]}" fi # When no library roots were provided, so that auto_lib is not deduced, and # MATHLIB is also not explicitly provided by the user, then default to MKL. [[ ! $auto_lib && ! $MATHLIB ]] && case $TARGET_ARCH in x86_64) auto_lib=MKL ;; *) auto_lib=OPENBLAS ;; esac : ${MATHLIB:=$auto_lib} export MATHLIB #TODO(kkm): Likely not needed. Briefly tested without, # but left in the hotfix. Remove when doing the #3192. # Define default library roots where known (others may be found by probing). case $MATHLIB in MKL) [[ ! $MKLLIBDIR && ! $MKLROOT ]] && MKLROOT=/opt/intel/mkl ;; ATLAS) : ${ATLASROOT:=$(rel2abs ../tools/ATLAS_headers/)} ;; esac unset auto_lib incompat libpfx mathlibs echo "Configuring KALDI to use ${MATHLIB}." # Back up the old kaldi.mk in case we modified it if [ -f kaldi.mk ]; then echo "Backing up kaldi.mk to kaldi.mk.bak ..." cp kaldi.mk kaldi.mk.bak fi # Generate the new kaldi.mk file echo "# This file was generated using the following command:" > kaldi.mk echo "# $cmd_line" >> kaldi.mk echo >> kaldi.mk echo "CONFIGURE_VERSION := $CONFIGURE_VERSION" >> kaldi.mk echo >> kaldi.mk echo "# Toolchain configuration" >> kaldi.mk echo >> kaldi.mk echo "CXX = $CXX" >> kaldi.mk echo "AR = $AR" >> kaldi.mk echo "AS = $AS" >> kaldi.mk echo "RANLIB = $RANLIB" >> kaldi.mk echo >> kaldi.mk echo "Checking compiler $CXX ..." check_compiler $CXX echo "# Base configuration" >> kaldi.mk echo >> kaldi.mk if $dynamic_kaldi ; then KALDILIBDIR=`pwd`/lib echo "KALDI_FLAVOR := dynamic" >> kaldi.mk echo "KALDILIBDIR := $KALDILIBDIR" >> kaldi.mk fi if $double_precision; then echo "DOUBLE_PRECISION = 1" >> kaldi.mk else echo "DOUBLE_PRECISION = 0" >> kaldi.mk fi echo "Checking OpenFst library in $FSTROOT ..." if [ ! -f $FSTROOT/include/fst/fst.h ]; then failure "Could not find file $FSTROOT/include/fst/fst.h: you may not have installed OpenFst. See ../tools/INSTALL" fi OPENFST_VER=${OPENFST_VER:-$(grep 'PACKAGE_VERSION' $FSTROOT/Makefile | sed -e 's:.*= ::')} OPENFST_VER_NUM=$(echo $OPENFST_VER | sed 's/\./ /g' | xargs printf "%d%02d%02d") if [ $OPENFST_VER_NUM -lt 10600 ]; then failure "OpenFst-$OPENFST_VER is not supported. You need OpenFst >= 1.6.0.)" fi echo "OPENFSTINC = $FSTROOT/include" >> kaldi.mk if $static_fst ; then OPENFSTLIBS="$FSTROOT/lib/libfst.a" else if [ "`uname`" == "Darwin" ]; then OPENFSTLIBS="$FSTROOT/lib/libfst.dylib" OPENFSTLDFLAGS="-Wl,-rpath -Wl,${FSTROOT}/lib" elif [ "`uname`" == "Linux" ]; then OPENFSTLIBS="$FSTROOT/lib/libfst.so" OPENFSTLDFLAGS="-Wl,-rpath=${FSTROOT}/lib" else failure "Dynamic libraries are not supported on this platform. Run configure with --static --static-fst flag." fi fi if [ ! -f "$OPENFSTLIBS" ]; then failure "Static=[$static_fst] OpenFST library not found: See ../tools/INSTALL" fi echo "OPENFSTLIBS = $OPENFSTLIBS" >> kaldi.mk echo "OPENFSTLDFLAGS = $OPENFSTLDFLAGS" >> kaldi.mk echo >> kaldi.mk $use_cuda && echo "Checking cub library in $CUBROOT ..." if [[ "$use_cuda" = true && ! -f $CUBROOT/cub/cub.cuh ]]; then failure "Could not find file $CUBROOT/cub/cub.cuh: you may not have installed cub. Go to ../tools/ and type e.g. 'make cub'; cub is a new requirement." else echo "CUBROOT = $CUBROOT" >> kaldi.mk fi # OS-specific steps given below append to kaldi.mk echo "Doing OS specific configurations ..." if $android ; then if [ -z $ANDROIDINC ] ; then failure "--android-incdir must be specified for android builds." fi if ! is_set $HOST; then failure "HOST must be specified for android builds." fi OPENBLASROOT=`rel2abs "$OPENBLASROOT"` if [ -z "$OPENBLASROOT" ]; then failure "The location of OPENBLAS must be specified for android builds using --openblas-root (and it must exist)" fi if [ ! -f $OPENBLASROOT/lib/libopenblas.a ]; then failure "Expected to find the file $OPENBLASROOT/lib/libopenblas.a" fi echo "Using OpenBLAS as the linear algebra library." OPENBLASLIBS="$OPENBLASROOT/lib/libopenblas.a $OPENBLASROOT/lib/libclapack.a $OPENBLASROOT/lib/liblapack.a $OPENBLASROOT/lib/libblas.a $OPENBLASROOT/lib/libf2c.a" echo "OPENBLASINC = $OPENBLASROOT/include" >> kaldi.mk echo "OPENBLASLIBS = $OPENBLASLIBS" >> kaldi.mk echo "ANDROIDINC = $ANDROIDINC" >> kaldi.mk cat makefiles/android_openblas.mk >> kaldi.mk echo "Successfully configured for Android with OpenBLAS from $OPENBLASROOT." elif [ "`uname`" == "Darwin" ]; then # Check for Darwin first, because we later call uname -o (for Cygwin) # which crashes on Darwin. echo "On Darwin: Checking for Accelerate framework ..." if [ ! -e /System/Library/Frameworks/Accelerate.framework ]; then failure "Need the Accelerate framework to compile on Darwin." fi OSX_VER=$(sw_vers | grep ProductVersion | awk '{print $2}' | awk '{split($0,a,"."); print a[1] "." a[2]; }') OSX_VER_NUM=$(echo $OSX_VER | sed 's/\./ /g' | xargs printf "%d%02d") echo "Configuring for OS X version $OSX_VER ..." if [ $OSX_VER_NUM -ge 1005 ]; then cat makefiles/darwin.mk >> kaldi.mk else failure "Mac OS X version '$OSX_VER' is not supported." fi if [ $OSX_VER_NUM == 1011 ]; then echo "**BAD WARNING**: You are using OS X El Capitan. Some versions of this OS" echo "**BAD WARNING**: have a bug in the BLAS implementation that affects Kaldi." echo "**BAD WARNING**: After compiling, cd to matrix/ and type 'make test'. The" echo "**BAD WARNING**: test will fail if the problem exists in your version. " echo "**BAD WARNING**: Eventually this issue will be fixed by system updates from" echo "**BAD WARNING**: Apple. Unexplained crashes with reports of NaNs will" echo "**BAD WARNING**: be caused by this bug, but some recipes will (sometimes) work." sleep 1; echo -n .; sleep 1; echo -n .; sleep 1; echo . fi echo "Successfully configured for Darwin with Accelerate framework." $use_cuda && configure_cuda elif [ "`uname -o`" == "Cygwin" ]; then echo "On Cygwin: Checking for linear algebra libraries ..." if [ ! -f ../tools/CLAPACK/clapack.h ]; then failure "could not find file ../tools/CLAPACK/clapack.h" fi if [ ! -f /usr/lib/lapack/cygblas-0.dll ]; then failure "please first install package liblapack0" fi cat makefiles/cygwin.mk >> kaldi.mk echo "Successfully configured for Cygwin with CLAPACK." elif [ "`uname`" == "Linux" ]; then echo "On Linux: Checking for linear algebra header files ..." if [ "$MATHLIB" == "ATLAS" ]; then if [ ! -f $ATLASROOT/include/cblas.h ] || [ ! -f $ATLASROOT/include/clapack.h ] ; then failure "Could not find required header files cblas.h or clapack.h in ATLAS dir '$ATLASROOT/include'" fi echo "Using ATLAS as the linear algebra library." # Finding out where the libraries are located: # First we look for the static libraries and then look for dynamic ones. # We're looking for four libraries, all in the same directory, named # libcblas.a, libatlas.a, libf77blas.a, and a library that's variously # named liblapack.a, libclapack.a, or liblapack_atlas.a, but which exports # the symbol ATL_cgetrf. # Note: there is a different type of ATLAS installation that is not # covered. We saw a case where there was a directory called /usr/lib/atlas # containing {liblapack.a,libblas.a}, and linking against just these two # libraries worked. ( $static_math && linux_configure_atlas_static ) || \ linux_configure_atlas_generic /usr/lib "so.3" || \ linux_configure_atlas_generic /usr/lib/atlas-base "so.3gf" || \ linux_configure_atlas_generic /usr/lib64/atlas-base "so.3gf" \ linux_configure_atlas_generic /usr/lib/atlas "so.3" || \ linux_configure_atlas_generic /usr/lib64/atlas "so.3" || \ linux_configure_atlas_generic /usr/lib/x86_64-linux-gnu/ "so.3" || \ linux_configure_atlas_generic /usr/lib/x86_64-linux-gnu/ "so" || \ linux_configure_atlas_redhat_fat 64 || \ linux_configure_atlas_redhat_fat || \ linux_configure_atlas_static || \ linux_configure_atlas_failure "Failed to configure ATLAS libraries"; case $TARGET_ARCH in arm*) cat makefiles/linux_atlas_arm.mk ;; ppc64le) cat makefiles/linux_atlas_ppc64le.mk ;; *) cat makefiles/linux_atlas.mk ;; esac >> kaldi.mk elif [ "$MATHLIB" == "MKL" ]; then if [ "$TARGET_ARCH" != "x86_64" ]; then failure "MKL on Linux only supported for Intel(R) 64 architecture (x86_64). See makefiles/linux_64_mkl.mk to manually configure for other platforms." fi if ( is_set "$MKLROOT" && ! is_set "$MKLLIBDIR" ); then echo -n "Configuring MKL library directory: " MKLLIBDIR=`linux_configure_mkllibdir $MKLROOT` if [ $? -ne 0 ]; then failure "MKL libraries could not be found. Please use the switch --mkl-libdir or try another math library, e.g. --mathlib=ATLAS (would be slower)" else echo "Found: $MKLLIBDIR" fi fi MKL_LINK_LINE=`linux_configure_mkl_libraries "$MKLLIBDIR" $static_math $mkl_threading` || exit 1 echo "MKL configured with threading: $mkl_threading, libs: $MKL_LINK_LINE" MKL_COMPILE_LINE=`linux_configure_mkl_includes "$MKLROOT" "$MKLLIBDIR"` || exit 1 echo "MKL include directory configured as: $MKL_COMPILE_LINE" MKL_COMPILE_LINE=" -I${MKL_COMPILE_LINE} " THREADING_LINE=`linux_configure_mkl_threading $MKLROOT $MKLLIBDIR $static_math $mkl_threading` || exit 1 EXTRA_LIBS=`linux_configure_mkl_extra $static_math $mkl_threading` || exit 1 if [ ! -z "$THREADING_LINE" ] || [ ! -z "$EXTRA_LIBS" ]; then echo "MKL threading libraries configured as $THREADING_LINE $EXTRA_LIBS" fi echo "Using Intel MKL as the linear algebra library." ( cd probe; rm -f mkl-test; g++ mkl-test.cc -o mkl-test $MKL_COMPILE_LINE $MKL_LINK_LINE $THREADING_LINE $EXTRA_LIBS || exit 1 test -f ./mkl-test || exit 1 ./mkl-test || exit 1 cd .. ) || failure "Cannot validate the MKL switches" echo MKLROOT = $MKLROOT >> kaldi.mk if [ ! -z $MKLLIBDIR ]; then echo MKLLIB = $MKLLIBDIR >> kaldi.mk fi echo >> kaldi.mk check_exists makefiles/linux_x86_64_mkl.mk cat makefiles/linux_x86_64_mkl.mk >> kaldi.mk echo "MKLFLAGS = ${MKL_LINK_LINE} ${THREADING_LINE} $EXTRA_LIBS " >> kaldi.mk echo "Successfully configured for Linux with MKL libs from $MKLROOT" elif [ "$MATHLIB" == "CLAPACK" ]; then if [ -z "$CLAPACKROOT" ]; then failure "Must specify the location of CLAPACK with --clapack-root option (and it must exist)" fi if [ ! -f ../tools/CLAPACK/clapack.h ]; then failure "could not find file ../tools/CLAPACK/clapack.h" fi if [ ! -d "$CLAPACKROOT" ]; then failure "The directory $CLAPACKROOT does not exist" fi # Also check for cblas.h and f2c.h echo "Using CLAPACK libs from $CLAPACKROOT as the linear algebra library." if [ ! -f makefiles/linux_clapack.mk ]; then failure "makefiles/linux_clapack.mk not found." fi if [[ "$TARGET_ARCH" == arm* ]]; then cat makefiles/linux_clapack_arm.mk >> kaldi.mk else cat makefiles/linux_clapack.mk >> kaldi.mk fi echo "Warning (CLAPACK): this part of the configure process is not properly tested and may not work." echo "Successfully configured for Linux with CLAPACK libs from $CLAPACKROOT" elif [ "$MATHLIB" == "OPENBLAS" ]; then if [[ ! $OPENBLASROOT ]]; then # Either the user specified --mathlib=OPENBLAS or we've autodetected the # system where OpenBLAS is the preferred option (the parser for # --openblas-root fails fatally if the path does not exist, so we trust # that if set, the variable contains the existing path, converted to # absolute form). OPENBLASROOT="$(rel2abs ../tools/OpenBLAS/install)" || Die "OpenBLAS not found in '../tools/OpenBLAS/install'. ** This is the only place we look for it. The best option is to build OpenBLAS ** tuned for your system and CPU. To do that, run the following commands: ** ** cd ../tools; extras/install_openblas.sh ** ** Another option is to specify the location of existing OpenBLAS directory ** with the switch '--openblas-root='. However, even if a package is provided ** for your system, the packaged version is almost always significantly slower ** and often older than the above commands can fetch and build. ** ** You can also use other matrix algebra libraries. For information, see: ** http://kaldi-asr.org/doc/matrixwrap.html" fi if [ -f $OPENBLASROOT/lib/libopenblas.so ]; then OPENBLASLIBDIR=$OPENBLASROOT/lib elif [ -f $OPENBLASROOT/lib64/libopenblas.so ]; then # in REDHAT/CentOS package installs, the library is located here OPENBLASLIBDIR=$OPENBLASROOT/lib64 else failure "Expected to find the file $OPENBLASROOT/lib/libopenblas.so" fi if [ -f $OPENBLASROOT/include/cblas.h ] ; then OPENBLASINCDIR=$OPENBLASROOT/include elif [ -f $OPENBLASROOT/include/openblas/cblas.h ] ; then # in REDHAT/CentOS/Ubuntu package installs, the includes are located here OPENBLASINCDIR=$OPENBLASROOT/include/openblas else echo "$0: ***** Using OpenBLAS from $OPENBLASROOT but cblas.h is not found. " echo "** Assuming openblas is aleady in a default include path, but" echo "** if you get compilation messages about not finding files like cblas.h," echo "** you should look into this (e.g. make sure to install the 'openblas-dev' package," echo "** if it is a package-based install)." OPENBLASINCDIR="/usr/include" fi echo "Your math library seems to be OpenBLAS from $OPENBLASROOT. Configuring appropriately." # TODO(kkm): Probably, OpenBLAS required libgfortran.so.3 at some point, but # no longer does. *My* linker does not complain about a missing library, but # is it safe to keep the reference if no longer required? Try to figure out # how long ago the dependency was dropped. if $static_math; then echo "Configuring static OpenBlas since --static-math=yes" OPENBLASLIBS="-L$OPENBLASLIBDIR -l:libopenblas.a -lgfortran" else echo "Configuring dynamically loaded OpenBlas since --static-math=no (the default)" OPENBLASLIBS="-L$OPENBLASLIBDIR -lopenblas -lgfortran -Wl,-rpath=$OPENBLASLIBDIR" fi echo "OPENBLASINC = $OPENBLASINCDIR" >> kaldi.mk echo "OPENBLASLIBS = $OPENBLASLIBS" >> kaldi.mk echo >> kaldi.mk case $TARGET_ARCH in aarch64*) cat makefiles/linux_openblas_aarch64.mk ;; arm*) cat makefiles/linux_openblas_arm.mk ;; ppc64le) cat makefiles/linux_openblas_ppc64le.mk ;; *) cat makefiles/linux_openblas.mk ;; esac >> kaldi.mk echo "Successfully configured for Linux with OpenBLAS from $OPENBLASROOT" else failure "Unsupported linear algebra library '$MATHLIB'" fi $use_cuda && configure_cuda linux_configure_speex else failure "Could not detect the platform or we have not yet worked out the appropriate configuration for this platform. Please contact the developers." fi # Append the flags set by environment variables last so they can be used # to override the automatically generated configuration. echo >> kaldi.mk echo "# Environment configuration" >> kaldi.mk echo >> kaldi.mk if [ -n "$ENV_CXXFLAGS" ]; then echo "CXXFLAGS += $ENV_CXXFLAGS" >> kaldi.mk; fi if [ -n "$ENV_LDFLAGS" ]; then echo "LDFLAGS += $ENV_LDFLAGS" >> kaldi.mk; fi if [ -n "$ENV_LDLIBS" ]; then echo "LDLIBS += $ENV_LDLIBS" >> kaldi.mk; fi # We check for slow exp implementation just before we exit. This check uses # and possibly modifies the kaldi.mk file that we just generated. check_for_slow_expf; echo "Kaldi has been successfully configured. To compile: make -j clean depend; make -j where is the number of parallel builds you can afford to do. If unsure, use the smaller of the number of CPUs or the amount of RAM in GB divided by 2, to stay within safe limits. 'make -j' without the numeric value may not limit the number of parallel jobs at all, and overwhelm even a powerful workstation, since Kaldi build is highly parallelized." exit 0