dolfin team mailing list archive
-
dolfin team
-
Mailing list archive
-
Message #09218
Re: Issues when compiling DOLFIN without MPI
On Wed, Aug 20, 2008 at 07:35:48PM +0200, Anders Logg wrote:
> On Wed, Aug 20, 2008 at 12:02:57PM -0500, Matthew Knepley wrote:
> > On Wed, Aug 20, 2008 at 11:54 AM, Marie Rognes <meg@xxxxxxxxxxx> wrote:
> > > Jed Brown wrote:
> > >> On Wed 2008-08-20 17:35, Marie Rognes wrote:
> > >>
> > >>> Matthew Knepley wrote:
> > >>>
> > >>>> On Wed, Aug 20, 2008 at 5:08 AM, Garth N. Wells <gnw20@xxxxxxxxx> wrote:
> > >>>>
> > >>>>
> > >>>>> Marie Rognes wrote:
> > >>>>>
> > >>>>>
> > >>>>>> Garth N. Wells wrote:
> > >>>>>>
> > >>>>>>
> > >>>>>>> Marie Rognes wrote:
> > >>>>>>>
> > >>>>>>>
> > >>>>>>>> I'm trying to compile dolfin with PETSc and SLEPc, but without MPI:
> > >>>>>>>>
> > >>>>>>>> ./scons.local enableMpi=no withPetscDir=$PETSC_DIR
> > >>>>>>>> withSlepcDir=$SLEPC_DIR
> > >>>>>>>>
> > >>>>>>>> This gives the following error:
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>> Hopefully this is fixed now, although my PETSc is built with MPI, so I
> > >>>>>>> can't be sure. Let me know if it's ok or otherwise.
> > >>>>>>>
> > >>>>>>>
> > >>>>>> I get through the compilation stage now, so that's good :)
> > >>>>>>
> > >>>>>> However, if I try to "import dolfin", I get:
> > >>>>>>
> > >>>>>> Python 2.5.2 (r252:60911, Jun 19 2008, 15:12:17)
> > >>>>>> [GCC 4.1.2 (Gentoo 4.1.2 p1.0.2)] on linux2
> > >>>>>> Type "help", "copyright", "credits" or "license" for more information.
> > >>>>>> >>> import dolfin
> > >>>>>> Traceback (most recent call last):
> > >>>>>> File "<stdin>", line 1, in <module>
> > >>>>>> File
> > >>>>>>
> > >>>>>> "/home/meg/src/dolfin/dolfin/local/lib/python2.5/site-packages/dolfin/__init__.py",
> > >>>>>>
> > >>>>>> line 13, in <module>
> > >>>>>> from assemble import *
> > >>>>>> File
> > >>>>>>
> > >>>>>> "/home/meg/src/dolfin/dolfin/local/lib/python2.5/site-packages/dolfin/assemble.py",
> > >>>>>>
> > >>>>>> line 22, in <module>
> > >>>>>> from dolfin import *
> > >>>>>> File
> > >>>>>>
> > >>>>>> "/home/meg/src/dolfin/dolfin/local/lib/python2.5/site-packages/dolfin/dolfin.py",
> > >>>>>>
> > >>>>>> line 7, in <module>
> > >>>>>> import _dolfin
> > >>>>>> ImportError: /home/meg/src/dolfin/dolfin/local/lib/libdolfin.so:
> > >>>>>> undefined symbol: MPIUNI_TMP
> > >>>>>>
> > >>>>>>
> > >>>>>>
> > >>>>> Looks like a linking problem to PETSc. Can you compile C++ DOLFIN programs?
> > >>>>>
> > >>>>>
> > >>>>
> > >>>>
> > >>> Nope. The cpp poisson demo gives:
> > >>>
> > >>> meg in cpp >> scons
> > >>> scons: Reading SConscript files ...
> > >>> scons: done reading SConscript files.
> > >>> scons: Building targets ...
> > >>> c++ -o main.o -c -Wall -pipe -ansi -g -Werror -O2 -fno-strict-aliasing
> > >>> -pthread -DDEBUG -DNDEBUG -DPACKAGE_VERSION="0.8.0" -DHAS_PETSC=1
> > >>> -DHAS_SLEPC=1 -DHAS_UMFPACK=1 -DHAS_GTS=1
> > >>> -I/home/meg/src/dolfin/dolfin/local/include
> > >>> -I/usr/lib/python2.5/site-packages/numpy/core/include
> > >>> -I/home/meg/src/slepc -I/home/meg/src/slepc/include
> > >>> -I/usr/include/python2.5 -I/home/meg/src/petsc/bmake/linux-gnu-c-debug
> > >>> -I/home/meg/src/petsc/include
> > >>> -I/home/meg/src/petsc-2.3.3-p13/include/mpiuni -I/usr/include/libxml2
> > >>> -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include main.cpp
> > >>> c++ -o demo -Wl,-rpath,/home/meg/src/slepc/lib/linux-gnu-c-debug
> > >>> -Wl,-rpath,/home/meg/src/petsc/lib/linux-gnu-c-debug -pthread
> > >>> -Wl,--export-dynamic main.o -L/home/meg/src/dolfin/dolfin/local/lib
> > >>> -L/home/meg/src/slepc/lib/linux-gnu-c-debug -L/usr/lib/atlas
> > >>> -L/home/meg/src/petsc/lib/linux-gnu-c-debug -ldolfin -lslepc -lblas
> > >>> -lumfpack -lamd -lgts -lxml2 -lpetscts -lpetscsnes -lpetscksp -lpetscdm
> > >>> -lpetscmat -lpetscvec -lpetsc -lgthread-2.0 -lrt -lgmodule-2.0 -ldl
> > >>> -lglib-2.0
> > >>> /home/meg/src/dolfin/dolfin/local/lib/libdolfin.so: undefined reference
> > >>> to `Petsc_MPI_Abort'
> > >>>
> > >>>
> > >>>> Almost certainly it is an incomplete link line when libdolfin.so is
> > >>>> constructed. When PETSc
> > >>>> is built without MPI, it creates an extra library (libmpiuni) which
> > >>>> must be linked against to
> > >>>> get these symbols.
> > >>>>
> > >>>>
> > >>> I'm not quite sure what that implies... But, I should somehow add
> > >>> -lmpiuni when linking dolfin? For instance in the pkgconfig file scons
> > >>> creates for petsc?
> > >>>
> > >>
> > >> What does the it look like when you build a PETSc demo? What should be
> > >> on the `Libs:' line of petsc.pc is the result of the following:
> > >>
> > >> echo -e 'include ${PETSC_DIR}/bmake/common/base\nlink:\n\t-@echo ${PETSC_LIB}' | make PETSC_DIR=~/usr/petsc-2* PETSC_ARCH=ompic-opt -f - link
> > >>
> > >> It will probably be ugly and often has lots of repetition for no
> > >> apparent reason. However, it should be reliable.
> > >>
> > >
> > >
> > > Hurray! My DOLFIN is back among the living. (Now, I just need to get it
> > > to understand that SLEPc is hanging around as well.)
> > >
> > > Just adding -lmpiuni to petsc.pc did not help. Adding the output of
> > >
> > > echo -e 'include ${PETSC_DIR}/bmake/common/base\nlink:\n\t-@echo
> > > ${PETSC_LIB}' | make -f - link
> > >
> > > did. Thanks a lot!
> > >
> > > However, there should probably be a prettier way of doing this?
> >
> > Yes, of course. The prettier way is to actually use the information we give
> >
> > 1) at the end of configure
> >
> > 2) in the configure.log
> >
> > 3) in RDict.db (Python pickle)
> >
> > 4) in the makefile (make getincludedirs, make getlinklibs)
> >
> > 5) in the conf files (petscvariables, petsconf.h)
> >
> > instead of ignoring it and hardcoding something into scons.
> >
> > Matt
>
> We don't. We get the include and link flags from the PETSc Makefiles.
> I've attached the pkgconfig generator for PETSc. Take a look at it.
>
> #!/usr/bin/env python
> import os,sys
> import string
> import os.path
> import commands
>
> from commonPkgConfigUtils import *
>
> def getPetscVariables(variables=('includes','libs','compiler','linker'), sconsEnv=None):
> if isinstance(variables, str):
> variables = (variables,)
> filename = "petsc_makefile"
> arch = get_architecture()
> # Create a makefile to read basic things from PETSc
> petsc_makefile_str="""
> # Retrive various flags from PETSc settings.
>
> PETSC_DIR=%s
>
> include ${PETSC_DIR}/bmake/common/variables
>
> get_petsc_include:
> -@echo -I${PETSC_DIR}/bmake/${PETSC_ARCH} -I${PETSC_DIR}/include ${MPI_INCLUDE}
>
> get_petsc_libs:
> -@echo ${C_SH_LIB_PATH} -L${PETSC_LIB_DIR} ${PETSC_LIB_BASIC}
>
> get_petsc_cc:
> -@echo ${PCC}
>
> get_petsc_ld:
> -@echo ${PCC_LINKER}
> """ % getPetscDir(sconsEnv=sconsEnv)
> petsc_make_file = open(filename, "w")
> petsc_make_file.write(petsc_makefile_str)
> petsc_make_file.close()
>
> petsc_includes = None
> if 'includes' in variables:
> cmdstr = "make -s -f %s get_petsc_include" % filename
> runFailed, cmdoutput = commands.getstatusoutput(cmdstr)
> if runFailed:
> os.unlink(filename)
> msg = "Unable to read PETSc includes through make."
> raise UnableToXXXException(msg, errormsg=cmdoutput)
> petsc_includes = cmdoutput
>
> petsc_libs = None
> if 'libs' in variables:
> cmdstr = "make -s -f %s get_petsc_libs" % filename
> runFailed, cmdoutput = commands.getstatusoutput(cmdstr)
> if runFailed:
> os.unlink(filename)
> msg = "Unable to read PETSc libs through make."
> raise UnableToXXXException(msg, errormsg=cmdoutput)
> petsc_libs = cmdoutput
>
> petsc_cc = None
> if 'compiler' in variables:
> cmdstr = "make -s -f %s get_petsc_cc" % filename
> runFailed, cmdoutput = commands.getstatusoutput(cmdstr)
> if runFailed:
> os.unlink(filename)
> msg = "Unable to figure out correct PETSc compiler."
> raise UnableToXXXException(msg, errormsg=cmdoutput)
> # We probably get a c-compiler from the petsc config, switch to a
> # compatible c++
> petsc_cc = cmdoutput
> if not is_cxx_compiler(petsc_cc):
> petsc_cc = get_alternate_cxx_compiler(petsc_cc, arch=arch)
>
> petsc_ld = None
> if 'linker' in variables:
> cmdstr = "make -s -f %s get_petsc_ld" % filename
> runFailed, cmdoutput = commands.getstatusoutput(cmdstr)
> if runFailed:
> os.unlink(filename)
> msg = "Unable to figure out correct PETSc linker"
> raise UnableToXXXException(msg, errormsg=cmdoutput)
> # We probably get a c-compiler from the petsc config, switch to a
> # compatible c++
> petsc_ld = cmdoutput
> if not is_cxx_compiler(petsc_ld):
> petsc_ld = get_alternate_cxx_compiler(petsc_ld, arch=arch)
>
> os.unlink(filename)
>
> ret = []
> for variable in petsc_includes, petsc_libs, petsc_cc, petsc_ld:
> if variable is not None:
> ret.append(variable)
> return ret
>
> def getPetscDir(sconsEnv=None):
> petsc_dir = getPackageDir("petsc", sconsEnv=sconsEnv, default=None)
> if not petsc_dir:
> petsc_locations = ["/usr/lib/petscdir/2.3.3"]
> for petsc_location in petsc_locations:
> if os.access(petsc_location, os.F_OK) == True:
> return petsc_location
> raise UnableToFindPackageException("PETSc")
> return petsc_dir
>
> def pkgVersion(compiler=None, linker=None, cflags=None, libs=None, sconsEnv=None):
> cpp_test_version_str = r"""
> #include <stdio.h>
> #include <petsc.h>
>
> int main() {
> #ifdef PETSC_VERSION_MAJOR
> #ifdef PETSC_VERSION_MINOR
> #ifdef PETSC_VERSION_SUBMINOR
> printf("%d.%d.%d", PETSC_VERSION_MAJOR, PETSC_VERSION_MINOR, PETSC_VERSION_SUBMINOR);
> #else
> printf("%d.%d", PETSC_VERSION_MAJOR, PETSC_VERSION_MINOR);
> #endif
> #else
> printf("%d", PETSC_VERSION_MAJOR);
> #endif
> #endif
> return 0;
> }
> """
> write_cppfile(cpp_test_version_str, "petsc_config_test_version.cpp");
>
> if not compiler:
> compiler = pkgCompiler(sconsEnv=sconsEnv)
> if not linker:
> linker = pkgLinker(sconsEnv=sconsEnv)
> if not cflags:
> cflags = pkgCflags(sconsEnv=sconsEnv)
> if not libs:
> libs = pkgLibs(sconsEnv=sconsEnv)
>
> cmdstr = "%s %s -c petsc_config_test_version.cpp" % (compiler, cflags)
> compileFailed, cmdoutput = commands.getstatusoutput(cmdstr)
> if compileFailed:
> remove_cppfile("petsc_config_test_version.cpp")
> raise UnableToCompileException("PETSc", cmd=cmdstr,
> program=cpp_test_version_str, errormsg=cmdoutput)
> cmdstr = "%s %s petsc_config_test_version.o" % (linker, libs)
> linkFailed, cmdoutput = commands.getstatusoutput(cmdstr)
> if linkFailed:
> remove_cppfile("petsc_config_test_version.cpp", ofile=True)
> raise UnableToLinkException("PETSc", cmd=cmdstr,
> program=cpp_test_version_str, errormsg=cmdoutput)
> runFailed, cmdoutput = commands.getstatusoutput("./a.out")
> if runFailed:
> remove_cppfile("petsc_config_test_version.cpp", ofile=True, execfile=True)
> raise UnableToRunException("PETSc", errormsg=cmdoutput)
> petsc_version = cmdoutput
>
> remove_cppfile("petsc_config_test_version.cpp", ofile=True, execfile=True)
> return petsc_version
>
> def pkgLibs(sconsEnv=None):
> libs, = getPetscVariables(variables='libs', sconsEnv=sconsEnv)
> return libs
>
> def pkgCflags(sconsEnv=None):
> includes, = getPetscVariables(variables='includes', sconsEnv=sconsEnv)
> return includes
>
> def pkgCompiler(sconsEnv=None):
> compiler, = getPetscVariables(variables='compiler', sconsEnv=sconsEnv)
> if not compiler:
> compiler = get_compiler(sconsEnv)
> return compiler
>
> def pkgLinker(sconsEnv=None):
> linker, = getPetscVariables(variables='linker', sconsEnv=sconsEnv)
> if not linker:
> linker = get_linker(sconsEnv)
> return linker
>
> def pkgTests(forceCompiler=None, sconsEnv=None,
> cflags=None, libs=None, version=None, **kwargs):
> """Run the tests for this package.
>
> If Ok, return various variables, if not we will end with an exception.
> forceCompiler, if set, should be a tuple containing (compiler, linker)
> or just a string, which in that case will be used as both.
> """
> if not cflags:
> cflags = pkgCflags(sconsEnv=sconsEnv)
> if not libs:
> libs = pkgLibs(sconsEnv=sconsEnv)
>
> if not forceCompiler:
> compiler = pkgCompiler(sconsEnv=sconsEnv)
> linker = pkgLinker(sconsEnv=sconsEnv)
> else:
> compiler, linker = set_forced_compiler(forceCompiler)
>
> if not version:
> version = pkgVersion(cflags=cflags, libs=libs,
> compiler=compiler, linker=linker, sconsEnv=sconsEnv)
> else:
> # Run pkgVersion since this is the current PETSc test
> pkgVersion(cflags=cflags, libs=libs,
> compiler=compiler, linker=linker, sconsEnv=sconsEnv)
>
> return version, compiler, linker, libs, cflags
>
> def generatePkgConf(directory=suitablePkgConfDir(), sconsEnv=None, **kwargs):
>
> version, compiler, linker, libs, cflags = pkgTests(sconsEnv=sconsEnv)
>
> pkg_file_str = r"""Name: PETSc
> Version: %s
> Description: The PETSc project from Argonne Nat.Lab, Math. and CS Division (http://www-unix.mcs.anl.gov/petsc/petsc-as/)
> compiler=%s
> linker=%s
> Libs: %s
> Cflags: %s
> """ % (version, compiler, linker, libs, cflags)
> pkg_file = open(os.path.join(directory,"petsc.pc"), "w")
> pkg_file.write(pkg_file_str)
> pkg_file.close()
>
> print "done\n Found PETSc and generated pkg-config file in\n '%s'" % directory
>
> if __name__ == "__main__":
> generatePkgConf(directory=".")
The pkgconfig generator for PETSc (and other packages) seems
unecessarily big. Why do we need things like
def pkgCflags(sconsEnv=None):
includes, = getPetscVariables(variables='includes', sconsEnv=sconsEnv)
return includes
This is a function that just calls another function, puts the result
in a variable and returns that variable.
--
Anders
Attachment:
signature.asc
Description: Digital signature
Follow ups
References