Python test fails

Bug #1135519 reported by Timothée Lecomte
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
libadjoint
Fix Committed
Wishlist
Unassigned

Bug Description

Hi,

On r410, built on MacOS X 10.6.8 using g++, I have problems with the python test named test_adjoint_numpy.py .

If I run 'FC="" CC=g++ make test' in libadjoint source directory, after a successful build (see bug #1134511 about how I got a working build), all C tests pass, but the python test fails, with this output:

Traceback (most recent call last):
  File "./test_libadjoint_numpy.py", line 3, in <module>
    from libadjoint.libadjoint_numpy import *
  File "/Users/tlecomte/FEniCS-Dorsal-stable/src/libadjoint/python/libadjoint/__init__.py", line 12, in <module>
    from libadjoint import *
  File "/Users/tlecomte/FEniCS-Dorsal-stable/src/libadjoint/python/libadjoint/libadjoint.py", line 6, in <module>
    import libadjoint.python_utils
ImportError: No module named python_utils
    test_libadjoint_numpy.py: no output
    Failure: non-zero exit code from test

Interestingly, when I run the code in test_adjoint_numpy.py line-by-line in a python interpreter, the above error does not appear and I can run all lines except the last one, which fails with :

In [12]: libadjoint.adj_test_assert(all(soln0.vec[:] == v.vec[:]), "First solution should be v")
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-12-712b877243a4> in <module>()
----> 1 libadjoint.adj_test_assert(all(soln0.vec[:] == v.vec[:]), "First solution should be v")

/Users/tlecomte/FEniCS-Dorsal-stable/lib/python2.7/site-packages/libadjoint/libadjoint.pyc in adj_test_assert(test_pass, msg)
     10 def adj_test_assert(test_pass, msg=None):
     11 assert isinstance(test_pass, bool)
---> 12 clib.adj_test_assert(ctypes.c_int(test_pass), msg)
     13
     14 def handle_error(ierr):

AttributeError: 'module' object has no attribute 'adj_test_assert'

Thanks in advance for your help !

Revision history for this message
Patrick Farrell (pefarrell) wrote :

Hi!

This is because you're trying to do two things that are really awkward together. The first is to compile C code with a C++ compiler.
The second is trying to compile on OSX. It seems there's a bug in the OSX version of g++ that puts leading underscores in front of all symbols it compiles, even with -fno-leading-underscore. If you do:

g++ -g -O0 -fPIC -Iinclude/ -Wall -Wextra -Wunused-parameter -Wunsafe-loop-optimizations -Wno-write-strings -Wpointer-arith -ggdb3 -fstack-protector-all -fno-leading-underscore -c -o obj/adj_adjointer_routines.o src/adj_adjointer_routines.c
nm obj/adj_adjointer_routines.o | grep _adj

you'll see that the OSX g++ has put a leading underscore in front of all the symbol names (e.g. it should be adj_timestep_count instead of _adj_timestep_count). When the Python bindings look for the symbols, it looks for the function name without the underscore, which is why the Python bindings are failing. This is despite the presence of the -fno-leading-underscore in the command line, which is supposed to fix exactly this problem.

I'd strongly suggest just forgetting about linking libadjoint to PETSc: it *really* isn't necessary for 99% of the desired uses of libadjoint/dolfin-adjoint. That way, you can compile libadjoint with a normal C compiler. If you're super keen to link against PETSc, compile PETSc with C language support.

I'd like to emphasise that these issues you're having are caused by a) bugs in the OSX operating system b) the way PETSc has been compiled. I've tried to work around these in libadjoint, but it seems like I can't.

Changed in libadjoint:
status: New → Confirmed
importance: Undecided → Wishlist
Revision history for this message
Timothée Lecomte (timothee-lecomte-5) wrote :

Thanks for your answer ! Ok, I will try without PETSc support.

Still, I have just tried the command you quote on my machine on r418, and I do get symbols _without_ any leading underscore !

minerve:~ tlecomte$ cd FEniCS-Dorsal-stable/src/libadjoint/
minerve:libadjoint tlecomte$ g++ -g -O0 -fPIC -Iinclude/ -Wall -Wextra -Wunused-parameter -Wunsafe-loop-optimizations -Wno-write-strings -Wpointer-arith -ggdb3 -fstack-protector-all -fno-leading-underscore -c -o obj/adj_adjointer_routines.o src/adj_adjointer_routines.c
minerve:libadjoint tlecomte$ nm obj/adj_adjointer_routines.o | grep adj_timestep
0000000000000471 T adj_timestep_count
00000000000356c0 S adj_timestep_count.eh

So it seems that it is working here !
For reference:

minerve:libadjoint tlecomte$ g++ --version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

minerve:libadjoint tlecomte$ uname -a
Darwin ### 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun 7 16:32:41 PDT 2011; root:xnu-1504.15.3~1/RELEASE_X86_64 x86_64

Revision history for this message
Patrick Farrell (pefarrell) wrote :

How interesting! The compiler installed on my friend's OSX installation:

jacks-mac-mini:~ pefarrell$ uname -a
Darwin jacks-mac-mini.lan 12.2.1 Darwin Kernel Version 12.2.1: Thu Oct 18 12:13:47 PDT 2012; root:xnu-2050.20.9~1/RELEASE_X86_64 x86_64

jacks-mac-mini:~ pefarrell$ g++ --version
i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

is only 8 builds older. Clearly they found the bug and fixed it. So there's still hope! I'll ask the admin of the OSX machine to see if it can be upgraded, and then I might be able to get your use case working.

Revision history for this message
Jack Hale (jack-hale) wrote :

Hi Patrick and Timothee,

To be clear on what I'm running it is the latest Mac OS X Mountain Lion 10.8 with the latest update to XCode with the Command Line Tools installed. I have pressed 'check now' and there is no updates available for XCode or the command line tools. Timothee's install I would guess is probably OS X Lion looking at the dates in uname -a. If he could provide more info on his macports/XCode versions that would be handy.

I also have macports installed with:

jacks-mac-mini:~ jack$ sudo port select --list gcc
Available versions for gcc:
 apple-gcc42
 llvm-gcc42
 mp-gcc45
 mp-gcc47
 none (active)

Available versions for gcc:
 apple-gcc42
 llvm-gcc42
 mp-gcc45
 mp-gcc47
 none (active)

A crucial point is that apple-gcc42 and llvm-gcc42 are different compilers chains. LLVM is the new compiler backend that most of the *BSDs (NetBSD, FreeBSD, OpenBSD etc.) + OS X use, along with clang as the new C++/Objective-C/C front end to LLVM. GCC of course is the compiler chain used on Linux. However, it is also possible to use LLVM as a backend for GCC! Yes, its all very confusing.

My understanding is that apple-gcc42 is Apple's version of GCC, and llvm-gcc42 is Apple's version of GCC with the LLVM backend. Source:
https://trac.macports.org/browser/trunk/dports/lang/apple-gcc42/Portfile
https://trac.macports.org/browser/trunk/dports/lang/llvm-gcc42/Portfile
The clang compilers are a different set of compilers again!

The default compilers on my system are (sudo port select gcc none):

jacks-mac-mini:~ jack$ clang --version
Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.2.1
Thread model: posix

jacks-mac-mini:~ jack$ g++ --version
i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
Copyright (C) 2007 Free Software Foundation, Inc.

With sudo port select gcc apple-gcc42:

jacks-mac-mini:~ jack$ g++ --version
i686-apple-darwin12-g++-apple-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3) (MacPorts apple-gcc42 5666.3_10)
Copyright (C) 2007 Free Software Foundation, Inc.

With sudo port select gcc llvm-gcc42:

jacks-mac-mini:~ jack$ g++ --version
i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
Copyright (C) 2007 Free Software Foundation, Inc.

I thought at first that Timothee must have option 2 selected, but his version label doesn't seem to be the MacPorts version. Perhaps he could clarify on this.

For what its worth gcc 4.2 (with or without LLVM) is pretty ancient these days. Patrick, I would recommend you work with the MacPorts version of a modern gcc version, perhaps one that matches your version in Ubuntu. You can then specify this as a requirement in the INSTALL file. My 12.04LTS has 4.6 series installed, which has a macports equivalent:

https://trac.macports.org/browser/trunk/dports/lang/gcc46/Portfile

The other option is clang but I noticed you use gccxml, not sure how compatible this is with using the new clang toolchain.

Jack Hale

Revision history for this message
Patrick Farrell (pefarrell) wrote :

Timothy: the standard name for the standard C++ library is "stdc++"; I've never come across another system where it was called "stdc++6" instead. (But maybe that's just me.)

I don't know how to programatically find out what standard C++ library g++ is linking against. (It would be very helpful of them to add a command line option g++ --print-stdc++, but they haven't been so kind.)

To get this working, just change

-lstdc++

to

-lstdc++6

in the Makefile (line 68).

At some point I'll pull out all of the system-specific stuff into a Makefile.inc that users can see and edit easily.

Aside: why do we need -lstdc++? It's because we use the revolve library for checkpointing, which is unfortunately written in C++.

Revision history for this message
Timothée Lecomte (timothee-lecomte-5) wrote :

Hi Patrick and Jack,

Thanks again for your help and your explanation. I am sorry that the compiler situation is so messy on OS X...

It looks like my stdc++ problem comes from the fact that I have gfortran is used for the linking, and I have gfortran 4.7.2 installed (from Homebrew):
minerve:dorsal tlecomte$ gfortran --version
GNU Fortran (GCC) 4.7.2

'gfortran -lstdc++' complains while 'gcc -lstdc++' and 'g++ -lstdc++' do not,

Well, as you suggested, I changed '-lstdc++' to '-lstdc++.6' in line 176 of the Makefile, and got rid of that error. Finally, I had to install greadlink (through Homebrew coreutils) to get the python bindings properly built, and now I have a fully working libadjoint where all tests pass ! Thanks !!

Revision history for this message
Jack Hale (jack-hale) wrote :

Ah OK, Homebrew. I like Homebrew but I've always run into problems when trying to build the FEniCS project against it, so I've been using macports recently.

Revision history for this message
Patrick Farrell (pefarrell) wrote :

Fantastic!

Like I said, at some point in my spare time I'll clean up the libadjoint build process so that it's much more tweakable. I'm really glad you stuck with it and got it compiling!

Cheerio

Patrick

Changed in libadjoint:
status: Confirmed → Fix Committed
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.