dolfin team mailing list archive
-
dolfin team
-
Mailing list archive
-
Message #09232
Re: Issues when compiling DOLFIN without MPI
On Wed, August 20, 2008 20:01, Anders Logg wrote:
> 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.
I think we had an idea of making the different pkgconfig scripts more
consistent with each other; all with functions like pkgVersion, pkgCflags,
pkgLibs, and pkgTests. Since it's only the latter that is used outside the
pkgconfig scripts, I guess the others aren't really that useful in many
cases, like in boost.py:
def pkgLibs(sconsEnv=None):
return ""
Not very useful in itself, but at least it makes the script consistent
with the others.
Johannes
References
-
Issues when compiling DOLFIN without MPI
From: Marie Rognes, 2008-08-19
-
Re: Issues when compiling DOLFIN without MPI
From: Garth N. Wells, 2008-08-19
-
Re: Issues when compiling DOLFIN without MPI
From: Marie Rognes, 2008-08-19
-
Re: Issues when compiling DOLFIN without MPI
From: Garth N. Wells, 2008-08-20
-
Re: Issues when compiling DOLFIN without MPI
From: Matthew Knepley, 2008-08-20
-
Re: Issues when compiling DOLFIN without MPI
From: Marie Rognes, 2008-08-20
-
Re: Issues when compiling DOLFIN without MPI
From: Marie Rognes, 2008-08-20
-
Re: Issues when compiling DOLFIN without MPI
From: Matthew Knepley, 2008-08-20
-
Re: Issues when compiling DOLFIN without MPI
From: Anders Logg, 2008-08-20
-
Re: Issues when compiling DOLFIN without MPI
From: Anders Logg, 2008-08-20