Search code examples
makefileconfigureautoconflapackopenblas

How do you set configure.ac (autoconf) in my own application to auto-discover LAPACK, ATLAS, OpenBLAS, and KMP?


I'm new to autoconf as well as linear algebra libraries. So far as I can tell, LAPACK, ATLAS, OpenBLAS, and KML can co-exist on the filesystem but you can only use one of the libraries at link-time and I would like to let ./configure choose whatever is available or let the user select it with ./configure --something.

Different distributions put things in different directories and it would be nice if autoconf can figure that out.

  • LAPACK is -llapack
  • ATLAS is -lsatlas -L /usr/lib64/atlas # CentOS
    • or -ltatlas for the threaded version
  • OpenBLAS is -lopenblas
    • or -lopenblasp for the pthread version
    • or -lopenblaso for the OpenMP version

Questions:

  • Is there already a "proper" way to do this with AC_ macros?
    • Do AC_ macros already exist for these libraries?
  • How would you setup configure.ac to find the first available library that is installed but default to threaded ATLAS if available?
  • How would you setup configure.ac to allow the user to select, for example, the OpenMP version of OpenBLAS?
    • Would you use an option like --with-openblas-openmp ?
    • What would the configure.ac code look like?

Thank you for your help!


Solution

  • The PSFEX package does this, see https://github.com/astromatic/psfex/blob/master/configure.ac#L285 :

    # Provide special options for INTEL MKL and force the use of icc
    AC_MSG_CHECKING([whether INTEL's MKL is enabled])
    AC_ARG_ENABLE(mkl,
        [AS_HELP_STRING([--enable-mkl],
        [Use INTEL's MKL for solvers and FFTs (default = no)])],
            enable_icc="yes"
            CC="icc"
        AC_MSG_RESULT([yes]),
        AC_MSG_RESULT([no]))
        
    # Provide special options for ATLAS
    AC_ARG_WITH(atlas-libdir,
        [AS_HELP_STRING([--with-atlas-libdir=<ATLAS library path>],
        [Provide an alternative path to the ATLAS library])])
    AC_ARG_WITH(atlas-incdir,
        [AS_HELP_STRING([--with-atlas-incdir=<ATLAS header dir>],
        [Provide an alternative path to the ATLAS header directory])])
        
    # Provide special options for OpenBLAS
    AC_MSG_CHECKING([whether OpenBLAS is enabled])
    AC_ARG_ENABLE(openblas,
        [AS_HELP_STRING([--enable-openblas],
        [Use the OpenBLAS library instead of ATLAS (default = no)])],
        AC_MSG_RESULT([yes]),
        AC_MSG_RESULT([no]))
    AC_ARG_WITH(openblas-libdir,
        [AS_HELP_STRING([--with-openblas-libdir=<OpenBLAS library path>],
        [Provide an alternative path to the OpenBLAS library])])
    AC_ARG_WITH(openblas-incdir,
        [AS_HELP_STRING([--with-openblas-incdir=<OpenBLAS header dir>],
        [Provide an alternative path to the OpenBLAS header directory])])
    
    
    ############ handle the INTEL MKL library (FFTW + LAPACKe) ###########
    if test "$enable_mkl" = "yes"; then
      convlibs="${srcdir}/../src/wcs/libwcs_c.a,${srcdir}/../src/levmar/liblevmar.a"
      ACX_MKL($with_mkl_dir,no,$enable_best_link,$convlibs)
      AC_MSG_CHECKING([for the INTEL MKL])
      if test "$MKL_WARN" == ""; then
        AC_MSG_RESULT([yes])
      else
        AC_MSG_RESULT([no])
        AC_MSG_WARN([$MKL_WARN])
      fi
      AM_CFLAGS="$AM_CFLAGS $MKL_CFLAGS "
      AM_LDFLAGS="$AM_LDFLAGS $MKL_LDFLAGS "
      LIBS="$LIBS $MKL_LIBS"
    
    ############ Select either openblas or atlas ############
    else    
      if test "x$enable_openblas" = "xyes"; then
        ######## Handle the OpenBLAS library (linear algebra: BLAS + LAPACKe) ########
        ACX_OPENBLAS($with_openblas_libdir, $with_openblas_incdir, $use_pthreads, no,
          [
            AM_CFLAGS="$AM_CFLAGS $OPENBLAS_CFLAGS "
            AM_LDFLAGS="$AM_LDFLAGS $OPENBLAS_LDFLAGS "
            LIBS="$OPENBLAS_LIBS $LIBS"
            if test "$OPENBLAS_WARN" != ""; then
              AC_MSG_WARN([$OPENBLAS_WARN])
            fi
          ],
          AC_MSG_ERROR([$OPENBLAS_ERROR Exiting.])
        )
    
      else
        ######### handle the ATLAS library (linear algebra: BLAS + cLAPACK) ##########
        ACX_ATLAS($with_atlas_libdir, $with_atlas_incdir, $use_pthreads,
          [
            [LIBS="$ATLAS_LIBS $LIBS"]
            if test "$ATLAS_WARN" != ""; then
          AC_MSG_WARN([$ATLAS_WARN])
        fi
          ],
          AC_MSG_ERROR([$ATLAS_ERROR Exiting. You could try --enable-openblas if Atlas is unavailable.])
        )
      fi
    fi
    
    AC_ARG_WITH([lapack],
      [AS_HELP_STRING([--without-lapack],
      [disable support for lapack])],
      [],
      [with_lapack=no])
    
    LIBLAPACK=
      AS_IF([test "x$with_lapack" != xno],
      [
        AX_BLAS([], [AC_MSG_ERROR([BLAS library not found])])
        AX_LAPACK([], [AC_MSG_ERROR([LAPACK library not found])])
    
        LIBS="$LAPACK_LIBS $BLAS_LIBS $LIBS $FLIBS"
        AC_CHECK_LIB(
        [lapack], [zgetrf], 
        [AC_SUBST([LIBLAPACK], ["$LAPACK_LIBS $BLAS_LIBS $LIBS $FLIBS"]) AC_DEFINE([LAPACK], [1], [Define if you have liblapack])],
        [AC_MSG_FAILURE([lapack library test failed (--without-lapack to disable)])],
        [])
      ])
    

    Also note that you will need their macro libraries (available here) which are too big to paste into the answer:

    • acx_mkl.m4
    • acx_atlas.m4
    • acx_openblas.m4