Acousto

I have just succeeded in building Acousto 1.6 on Mavericks.

Note that my Mavericks installation is absolutely fresh: I bought a new SSD, formatted it, installed Mavericks, then went straight to http://acousto.sourceforge.net/user_manual/html/UserManualse32.html#x61-87000F.3

Ok, follow the instructions on the page linked above until you get to the symlinks. But instead do this:

Look in /usr/local/lib/ and check whether {libgfortran.a libblas.a liblapack.a} exist, if so, rename them.

Do:

cd /usr/local/lib
ln -s /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libgfortran.3.dylib
ln -s /usr/local/Cellar/openblas/0.2.8/lib/libopenblas.dylib
ln -s /usr/local/Cellar/openblas/0.2.8/lib/libopenblas.dylib

Now you could try just continuing with the instructions — it may work. Remember, even if it builds you still need to test it out with one of the tutorial .cfg files just to check you don't get a runtime error.

Now I can't guarantee that will work, because I've modified { configure.ac Makefile.am /src/Makefile.am } and tidied up the file structure, so as to keep clutter out of the root project folder:

ps-MacBook-Air:~ pi$ cd Downloads/acousto-1.6

ps-MacBook-Air:acousto-1.6 pi$ ls
configure.ac
configure        

Makefile.am        
Makefile.in    

m4
aux_build
tmp_build
autom4te.cache        

doc            
blender            

mysql
php

src

AUTHORS            
COPYING            
NEWS            
README
INSTALL
ChangeLog

ps-MacBook-Air:acousto-1.6 pi$ ls m4/
NOTES        aclocal.m4

ps-MacBook-Air:acousto-1.6 pi$ cat m4/NOTES 
make sure this folder is not empty, as some related technologies have trouble with an empty folder e.g. git

ps-MacBook-Air:acousto-1.6 pi$ ls aux_build/
compile        config.guess    config.sub    depcomp        install-sh    missing

Note that I've also used a tmp_build folder, this is so that I can do:

configure blah blah; cd tmp_build; make; make install; cd ..

And it puts all of the temporary build stuff in tmp_build, which keeps things clean

Seeing as we're redesigning the configure script, you need autotools:

brew install automake

Then to build Acousto:

clear; autoreconf -if; configure --enable-scalapack_new --with-libs=/usr/local/lib; cd tmp_build; make clean; make; make install; cd..

Before I list the files, please note that there are still issues with configure.ac — it is still in need of much attention.

  • I'm not at all clear how it handles library resolution http://stackoverflow.com/questions/21205484/autoconf-ac-check-lib-dealing-with-duplicate-libraries
  • LDFLAGS should not be written to, it is bad convention. And it is automatically included in AC_CHECK_LIB so that means that as it stands, stuff is included twice in those calls. The correct way to do it would be to either get the user to pass in LDFLAGS=/usr/local/lib as a parameter, or to disregard it completely
  • I'm still not sure I'm using the best conditional checking syntax
  • the actual logic path needs an overhaul. There is going to be a simpler way to do this. For example, when checking which library to use for BLAS, we could first check the default libs folder, i.e. the '/usr/local/lib' passed in as a parameter, then we could check whether Atlas was specified and if so use the Atlas BLAS library. Then we could check if a specific BLAS library was specified. 3 separate checks, no nesting, because each one if it exists overwrites the previous one.
  • .dylib vs .a needs investigating. As far as I am aware, .dylib is better —it can avoid circular dependencies and I think that if a function in A.dylib calls through to a function in B.dylib, then your project X only needs to link to A. But if they are .a's then X would need to link to both of them. I think I might have actually hit up against this problem when I got a VecLib style runtime error despite having not linked to any VecLib's. Maybe a OpenBLAS-LAPACK routine was referencing through to a VecLib BLAS routine, due to the way OpenBLAS.a got constructed. That was one of the main problems, switching to using openBLAS's .dylib's not .a's

In fact I think it would be nice to create /usr/local/lib/acousto/symlinks and populate it with a link to gfortran, blas, lapack, blacs, scalapack

And then just point configure at it. This way uses could clearly decide which BLAS etc implementation to use.

Just pointing to /usr/local/lib/ I think is a bad idea, as lots of different things write into that folder, so there is more scope for error, and it is going to be more difficult to support users as they will all have different bumpf on their systems.

If you would like write access to this page, or you get stuck, or especially if you're interested in improving this whole setup, send me an e-mail.

π
moc.liamg|7hsifnus#moc.liamg|7hsifnus

configure.ac

                       -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

# Reworked by π 16.1.2014                        

# http://stackoverflow.com/questions/21160206/bash-sh-autoconf-wrapping-string-comparison
# https://www.flameeyes.eu/autotools-mythbuster/index.html
# http://www.dwheeler.com/autotools/

dnl NOTE: use dnl (Delete to NewLine) instead of # to prevent comments from passing through M4 to output

# "Every configure script must call AC_INIT before doing anything else that produces output."
AC_INIT([acousto],[1.6],[u.iemma@uniroma3.it])

AC_MSG_NOTICE( * * * * * * *   A C O U S T O configure.ac for Acousto ver. $PACKAGE_VERSION * * * * * * * )

# this is where all the automake gubbins gets stored... remove this folder before shipping!
AC_CONFIG_AUX_DIR([aux_build])

# there is one more automake file that needs to be tucked away: aclocal.m4
# This requires fiddling with Makefile.am, I don't think it requires fiddling with /src/Makefile.am but I'm not sure
# It also requires creating a m4 folder and making it nonempty due to some silliness with git etc storing empty folders
#AC_CONFIG_MACRO_DIR([m4])

AC_CONFIG_SRCDIR([src/main.c])

AC_CONFIG_FILES([Makefile src/Makefile])

# π  http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation
AM_INIT_AUTOMAKE

AC_MSG_NOTICE( --> Checking for programs... )
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PATH_PROG([robodoc_pathfile],[robodoc],[false],[/usr/bin:/usr/local/bin])

#-----------------------------------
# Check for supported OS
#-----------------------------------
# π note that even $host doesn't match any of our targets, we allow the process to continue until it fails.
AC_CANONICAL_HOST
case $host in
    *linux*|*solaris*|*darwin*|*cygwin*)
        AC_MSG_NOTICE( --> Compatible host detected: $host )
        ;;
    *)
        AC_MSG_NOTICE( linux, solaris, darwin, cygwin are supported, your host is $host and might not be supported... let us find out )
        ;;
esac  

#-----------------------------------
# finding MPICC
#-----------------------------------

mpicc_compiler=""

AC_ARG_WITH(
            [mpicc],            
            [AS_HELP_STRING([--with-mpicc],[MPI C Compiler])], 
            [
                mpicc_compiler=$withval
                AC_MSG_NOTICE( -->  Using user-supplied mpicc: $mpicc_compiler )
            ],
            [
                AC_MSG_NOTICE( -->  Searching $PATH for MPICC compiler... )
                AC_PATH_PROG(
                             mpicc_compiler, 
                             [mpicc],
                             [ AC_MSG_ERROR( Failed to find MPICC compiler ) ], 
                             [$PATH]
                             )
                AC_MSG_NOTICE( -->  ... Found at: $mpicc_compiler )
            ]
            )

# definition of C compiler.
CC=$mpicc_compiler

# ---------------------------------------------------------------
# Check GCC Version on MacOSX
# ---------------------------------------------------------------

GCCVER=`$CC -dumpversion`;
if [[ $host = "darwin" ]]; then
    AS_VERSION_COMPARE(
                       $GCCVER,
                       "4",
                       AC_MSG_ERROR( Need gcc >= 4.0.x due to the restFP/saveFP problem )
                       )
fi

# -------------------------------------
# CFGPARSE
# -------------------------------------
AC_ARG_WITH(
            libconfig,
            [AS_HELP_STRING([--with-libconfig],[config lib dir])],
            [  LDFLAGS="-L$withval $LDFLAGS" ], 
            []
            )

AC_CHECK_LIB(
             config, 
             config_init, 
             AC_MSG_NOTICE( -->  libconfig found ),
             AC_MSG_ERROR( Cannot find libconfig ),
             [ $LDFLAGS ]
             )

libConfig_LIBS="-lconfig"

# π ^ original code created CFGPARSE_DIR here, at the end it does 'AC_SUBST([CFGPARSE_DIR])'
#    so it exports it. What picks it up?  NOTE: I need to put this variable back in!

# ----------------------------------
# INTEL COMPILER
# ----------------------------------

FORTRAN_libs=""

AC_ARG_ENABLE(
              [intel], 
              [AS_HELP_STRING([--enable-intel],[build with intel compiler (default gcc)])], 
              [
                  # intel libs
                  AC_ARG_WITH(
                      intel-libs,
                      [AS_HELP_STRING([--with-intel-libs],[intel compiler libs dir])],
                      [
                          LDFLAGS="-L$withval $LDFLAGS"
                          FORTRAN_libs="-lifcore -limf -lintlc"
                      ],
                      [AC_MSG_ERROR( Intel compiler has been specified. You must provide the location of Intel libraries  ifcore.a ) ]
                      )
              ],
              [
                  FORTRAN_libs="-lgfortran.3"
              ]
              )

# ----------------------------------
# MATH LIBS
# ----------------------------------

libs_dir=""
AC_ARG_WITH(
            libs,
            [AS_HELP_STRING([--with-libs],[math libs dir])],
            [
                libs_dir="$withval"
                LDFLAGS="$LDFLAGS -L$libs_dir"
            ],
            []
            )

# ----------------------------------
# Check for ATLAS
# ----------------------------------

have_ATLAS="0"
ATLAS_BLAS_libs="-lf77blas -lcblas -latlas"

# --with-atlas overrides --with-libs
AC_ARG_WITH(
            atlas,
            [AS_HELP_STRING([--with-atlas],[Atlas lib dir])],
            [
                have_ATLAS="1"
                LDFLAGS="$LDFLAGS -L$withval"
            ], 
            [
                AC_MSG_NOTICE( Checking user-supplied libs for ATLAS... )
                AC_CHECK_LIB(
                             atlas,
                             ATL_zgemm,
                             [
                                 have_ATLAS="1"
                                 AC_MSG_NOTICE( ... Found Atlas! )
                             ],
                             [
                                 have_ATLAS="0"
                                 AC_MSG_NOTICE( ... Could not find Atlas! )
                             ],
                             [ $ATLAS_BLAS_libs $LDFLAGS ]
                             )
                # this test is bad because it may return an incompatible file with the right name: 
                #   Also it might miss the right file in a different folder

                #if test -n "$libs_dir"; then
                #    if test -f "$libs_dir/libatlas.a"; then
                #        have_ATLAS="1"
                #    fi
                #fi
            ]
            )

# ----------------------------------
# BLAS
# ----------------------------------

BLAS_libs=""

# first, check if user is manually supplying BLAS path
AC_ARG_WITH(
            blas,
            [AS_HELP_STRING([--with-blas],[blas lib dir])],
            [
                LDFLAGS="$LDFLAGS -L$withval";
                AC_MSG_NOTICE( -->  Using user-supplied BLAS: $withval )
            ],
            [
                # otherwise if we have ATLAS, use it's BLAS
                if [[ $have_ATLAS = "1" ]]; then
                    AC_MSG_NOTICE( -->  Getting BLAS from ATLAS... )
                    AC_CHECK_LIB(
                                 f77blas,
                                 ATL_zgemm,
                                 AC_MSG_NOTICE( -->  ... Success! ),
                                 AC_MSG_ERROR( ... Fail! ),
                                 [ $ATLAS_BLAS_libs $LDFLAGS ]
                                 )

                    BLAS_libs=$ATLAS_BLAS_libs
                else
                    # else attempt to find in libs
                    AC_CHECK_LIB(
                                 blas,
                                 dgemm_,
                                 AC_MSG_NOTICE( -->  Auto-Located BLAS ),
                                 AC_MSG_ERROR( Failed to auto-locate BLAS ),
                                 [ -lblas $FORTRAN_libs -lm $LDFLAGS ]
                                 )

                    BLAS_libs="-lblas"
                fi
            ]
            )

# ---------------------------------
# LAPACK
# ----------------------------------

AC_ARG_WITH(
            lapack,
            [AS_HELP_STRING([--with-lapack],[lapack lib dir])],
            [ LDFLAGS="$LDFLAGS -L$withval" ],
            []
            )

AC_CHECK_LIB(
             lapack, 
             zgegv_, 
             AC_MSG_NOTICE( -->  Got LAPACK ),
             AC_MSG_ERROR( Failed to find LAPACK ),
             [ $LDFLAGS $BLAS_libs -llapack $FORTRAN_libs -lm ]
             )

LAPACK_libs="-llapack"

# π ^ not sure whether this should be nested. I'm keeping it flat as this way, if the user specified a LAPACK, then it will add the path to the linker flags and still perform a check to see whether the library is good.
# NOTE: maybe elsewhere code should be adapted to do this. Because if the user is supplying a path, elsewhere it is not checking the validity of the library. But here it is.

# ---------------------------------------------------------------
# Check OpenMPI Version 
# Needed to corectly link the fortran libraries  
# ---------------------------------------------------------------

# mpi_mpifh will override mpi_f77
MPI_FORTRAN_libs=""
AC_CHECK_LIB( mpi_f77, MPI_Init, MPI_FORTRAN_libs="-lmpi_f77", [], [ -lblas $FORTRAN_libs -lm $LDFLAGS ] )
AC_CHECK_LIB( mpi_mpifh, MPI_Init, MPI_FORTRAN_libs="-lmpi_mpifh", [], [ -lblas $FORTRAN_libs -lm $LDFLAGS ] )

ifelse( MPI_FORTRAN_libs, "", 
    AC_MSG_ERROR( OpenMPI fortran library -- lmpi_mpifh or lmpi_f77 -- not found! ),
    AC_MSG_NOTICE( --> Setting MPI_FORTRAN_libs: $MPI_FORTRAN_libs )
    )

# ---------------------------------
# SCALAPACK  and BLACS
# ----------------------------------

# ---------------------------------
# BLACS 
# ----------------------------------

needToFindBLACSManually="0"

AC_ARG_WITH(
            blacs,
            [AS_HELP_STRING([--with-blacs],[blacs lib dir])],
            [
                LDFLAGS="$LDFLAGS -L$withval"
                AC_MSG_NOTICE( -->  Using user-supplied BLACS )
            ],
            [
               AC_ARG_ENABLE(
                             [scalapack_new], 
                             [AC_HELP_STRING([--enable-scalapack_new],[use new version of Scalapack with embedded Blacs (default=NO)])], 
                             [AC_MSG_NOTICE( -->  Gettings BLACS from new scaLapack ) ],
                             [needToFindBLACSManually="1"]
                             )
            ]
            )

BLACS_libs=""

if [[ $needToFindBLACSManually = "1" ]]; then
    AC_MSG_NOTICE( -->  Attempting to locate BLACS... )
    got_BLACS="0"
    # We try a few different BLACS naming schemes
    for lib in "blacs blacsCinit" "blacs blacsC" "mpiblacs mpiblacsCinit" "blacs_MPI blacsCinit_MPI"  "blacs-openmpi blacsCinit-openmpi"
    do
        set -- $lib
        AC_CHECK_LIB(
                     $2,
                     Cblacs_pinfo,
                     got_BLACS="1" && break,
                     [],
                     [ $BLAS_libs $FORTRAN_libs -lm $MPI_FORTRAN_libs -l$2 -l$1 -l$2 $LDFLAGS ]
                   )
    done

    if [[ $got_BLACS = "0" ]]; then
        AC_MSG_ERROR( Failed to find BLACS! )
    fi

    BLACS_libs="-l$2 -l$1 -l$2"
fi

# ---------------------------------
# SCALAPACK 
# ----------------------------------

AC_ARG_WITH(
            scalapack,
            [AS_HELP_STRING([--with-scalapack],[scalapack lib dir])],
            [
                LDFLAGS="$LDFLAGS -L$withval";
                AC_MSG_NOTICE( -->  Using user-supplied scaLapack )
            ],
            []
            )

AC_CHECK_LIB(
             scalapack,
             sl_init_,
             AC_MSG_NOTICE( -->  scaLapack found & working ),
             AC_MSG_ERROR( Cannot find/work scalapack! ),
             [$LDFLAGS -lscalapack $BLACS_libs $LAPACK_libs $BLAS_libs $FORTRAN_libs -lm $MPI_FORTRAN_libs ])

SCALAPACK_libs="-lscalapack"

# ---------------------------------------------
# MYSQL
# ---------------------------------------------

have_MySQL="0"

MySQL_libs=""

AC_ARG_ENABLE(
              [mysql],
              [AS_HELP_STRING([--enable-mysql],[build with mysql support for run info storage (default NO)])],
              [
                  # enable SQL
                   AC_ARG_WITH(
                               libmysqlclient,
                               [AS_HELP_STRING([--with-libmysqlclient],[mysqlclient lib dir])],
                               [LDFLAGS="$LDFLAGS -L$withval"], 
                               []
                               )

                   AC_CHECK_LIB(
                                mysqlclient, 
                                mysql_close, 
                                [ 
                                    CFLAGS="$CFLAGS -D_MYSQL_";
                                    MySQL_libs="-lmysqlclient";
                                    have_MySQL="1"
                                ],
                                [],
                                [ $LDFLAGS ]
                                )
               ],
              []
              )

# Wrapping up
AC_MSG_NOTICE( --> [--------------------------])
AC_MSG_NOTICE( --> [-------- Summary ---------])
AC_MSG_NOTICE( --> [--------------------------])
AC_MSG_NOTICE( --> [LIBCONFIG       : $libConfig_LIBS])
AC_MSG_NOTICE( --> [FORTRAN         : $FORTRAN_libs])
AC_MSG_NOTICE( --> [BLAS            : $BLAS_libs])
AC_MSG_NOTICE( --> [LAPACK          : $LAPACK_libs])
AC_MSG_NOTICE( --> [MPI FORTRAN     : $MPI_FORTRAN_libs])
AC_MSG_NOTICE( --> [BLACS           : $BLACS_libs])
AC_MSG_NOTICE( --> [SCALAPACK       : $SCALAPACK_libs])
AC_MSG_NOTICE( --> [MYSQL_LIBS      : $MYSQL_LIBS])
AC_MSG_NOTICE( --> [CFLAGS          : $CFLAGS])
AC_MSG_NOTICE( --> [LDFLAGS         : $LDFLAGS])
AC_MSG_NOTICE( --> [--------------------------])

#AC_MSG_NOTICE( --> [ATLAS           : $ATLAS_LIBS]) <--these have got amalgamated into BLAS_libs
#AC_MSG_NOTICE( --> [MPI_VER         : $mpi_version])

math_libs="$SCALAPACK_libs $BLACS_libs $LAPACK_libs $BLAS_libs $FORTRAN_libs -lm $MPI_FORTRAN_libs"

# ----------------------------------------------
#  AUTOCONF substitutions
# ----------------------------------------------

AC_SUBST([MySQL_libs])
AC_SUBST([math_libs])
AC_SUBST([libConfig_LIBS])

#AC_SUBST([CFGPARSE_DIR]) <-- 'grep -r "CFGPARSE_DIR" .' suggests this is never used, same for ROBODOC
#AC_SUBST([ROBODOC])
#AM_CONDITIONAL(ROBODOC_FOUND, test x$robodoc_pathfile != xfalse)

AM_CONDITIONAL(have_MySQL, [$have_MySQL])

AC_OUTPUT

# remember to have a newline character to terminate the file

Makefile.am

## Process this with automake to create Makefile.in

#Here is the fiddle I was talking about in configure.ac:
# http://www.dwheeler.com/autotools/  - video at 23:40
#ACLOCAL_AMFLAGS = -I m4 --install

SUBDIRS = src
EXTRA_DIST =     mysql\
                 blender\
                doc/pdf \
                doc/tutorials \
                php

dist-hook:
    rm -rf `find $(distdir) -name .svn `
    rm -rf `find $(distdirstdir) -name .deps `
    rm -rf `find $(distdir) -name .cvsignore `
    cp -f docs/user_manual/UserManual.pdf doc/pdf
    cp -f docs/reference_manual/latex/refman.pdf doc/pdf/ReferenceManual.pdf
    cp -f tutorials/doc/Tutorials.pdf doc/pdf
    cp -fr tutorials/Aircraft_Engines_Installation doc/tutorials
    cp -fr tutorials/Brass_FreqResponse doc/tutorials
    cp -fr tutorials/ImpedSphere_PlaneWave doc/tutorials
    cp -fr tutorials/Potential_Aerodynamics doc/tutorials
    cp -fr tutorials/Radiating_Box doc/tutorials
    cp -fr tutorials/Room_Acoustics doc/tutorials
    cp -fr tutorials/Sphere_Monopole doc/tutorials

/src/Makefile.am

## Process this with automake to create Makefile.in

if have_MySQL
  bin_PROGRAMS = acousto ac_mysqlread
  mysqlsave=mysqlsave.c
else  
  bin_PROGRAMS = acousto
endif

acousto_SOURCES = main.c \
                  geom.c \
                  geom_utils.c \
                  logger.c \
                  ac_coef_body.c \
                  ac_coef_mics.c \
                  solution.c \
                  linsys.c \
                  ac_gmres.c \
                  math.c \
                  integrals.c \
                  nrwash.c \
                  matrices.c \
                        matutils.c \
                  ${mysqlsave} \
                  pre_mic.c \
                  vtkout.c

noinst_HEADERS=acousto.h \
                ac_coef_body.h \
                      ac_coef_mics.h \
                ac_scalapack.h \
                acousto_math.h \
                                geom.h \
                                geom_utils.h \
                                integrals.h \
                                linsys.h \
                                ac_gmres.h \
                                matrices.h \
                                nrwash.h \
                                pre_mic.h \
                                solution.h \
                                vtkout.h \
                common.h \
                logger.h \
                matutils.h \
                messages.h \
                mysqlsave.h \
                version.h 

ac_mysqlread_FFLAGS=-I../include -I/usr/local/include
ac_mysqlread_CFLAGS=-Wall
ac_mysqlread_LDFLAGS=@MySQL_libs@ 

acousto_FFLAGS=-I../include -I/usr/local/include
acousto_CFLAGS=-Wall 
acousto_LDADD=@math_libs@ @libConfig_LIBS@ @MySQL_libs@
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License