Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7875 Discussions

Building Python with icc 13.0.0. Extension modules (shared objects) not linking properly


I'm trying to build a highly-optimised Python (2.7 from mercurial), using profile guided optimisation (PGO) and all the other optimising features that icc provides. Perhaps I don't understand the implications of PGO and interprocedural optimisation well enough, but for some reason, extension modules are getting over-linked against the main shared library. i.e. The main Python library seems to be statically linked into each extension module, resulting in shared objects of about ~5MB, when they should be much smaller. This is confirmed by running for example `nm build/lib.linux-x86_64-2.7/`, and seeing all the text and data symbols from as local, when they should be external, or undefined here.

One of the reasons for this I thought, is that the linker (ld or xild) is never directly called by Python's Makefile, so the LD environment variable makes no difference. Instead, only CC (=icc) is used, to build both the main executable and shared libraries. A static archive is built with AR (=xiar) and has the same file name prefix as the shared library,  so I hope it's not linking against the archive by mistake.

I'm not sure if this is a bug with the compiler-linker interface, or I'm just passing the incorrect link flags, but some help getting the desired effect (a working, optimal build) would be great.

My current configure command is:-


CFLAGS="-g -fPIC -O3 -ipo -xHost -prec-div -prec-sqrt -fp-model precise -fp-model source -fomit-frame-pointer -prof-use -prof-dir $PWD/PGO" \

CPPFLAGS="-I/opt/intel/composerxe/include/intel64 -I/opt/intel/composerxe/include -I/usr/include/x86_64-linux-gnu" \

LDFLAGS="-fPIC -ipo -xHost -prof-use -prof-dir $PWD/PGO -L/opt/intel/lib/intel64" \

LIBS="-limf -lirc" AR=xiar CXX=icpc CPP="icc -E"  \

./configure --build=x86_64-linux-intel --with-fpectl --without-libc --without-gcc --without-libm \

--with-cxx-main="/opt/intel/composerxe/bin/icc -ipo -O3 -xHost -prec-div -prof-use -prof-dir $PWD/PGO" \

--with-threads --enable-ipv6 --enable-shared --with-signal-module --enable-unicode=ucs4

I've also been playing with the generated Makefile, to try and get this to work, but I've had no joy when using all these optimisations. Do I need to hack the generated Makefile to use xild instead of icc when linking objects into shared objects? One way I got it link properly, was to copy and paste the exact compile command, and delete the '-lpython2.7' flag, which is automatically added by Python's distutils module.

If you'd like to see the generated build commands, below are some for linking the main python shared library, and for building one of the extension modules.

/opt/intel/bin/icc -pthread -shared -fPIC -ipo -xHost -prof-use -prof-dir /usr/local/src/pysrc/cpython/PGO -L/opt/intel/lib/intel64 -Wl, -o Modules/getbuildinfo.o Parser/acceler.o Parser/grammar1.o Parser/listnode.o Parser/node.o Parser/parser.o Parser/parsetok.o Parser/bitset.o Parser/metagrammar.o Parser/firstsets.o

... <snip> ...

Modules/pwdmodule.o  Modules/_sre.o  Modules/_codecsmodule.o  Modules/_weakref.o  Modules/zipimport.o  Modules/symtablemodule.o  Modules/xxsubtype.o \

  -lpthread -ldl -limf -lirc -lutil

select extension:

/opt/intel/bin/icc -pthread -fPIC -fno-strict-aliasing -OPT:Olimit=0 -g -fPIC -O3 -xHost -prec-div -prec-sqrt -fp-model precise -fp-model source -fomit-frame-pointer -prof-use -prof-dir /usr/local/src/pysrc/cpython/PGO -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I. -IInclude -I./Include -I/opt/intel/composerxe/include/intel64 -I/opt/intel/composerxe/include -I/usr/include/x86_64-linux-gnu -I/usr/local/include -I/usr/local/src/pysrc/cpython/Include -I/usr/local/src/pysrc/cpython -c /usr/local/src/pysrc/cpython/Modules/selectmodule.c -o build/temp.linux-x86_64-2.7/usr/local/src/pysrc/cpython/Modules/selectmodule.o
icc: command line warning #10006: ignoring unknown option '-OPT:Olimit=0'

/opt/intel/bin/icc -pthread -shared -fPIC -ip -xHost -prof-use -prof-dir /usr/local/src/pysrc/cpython/PGO -L/opt/intel/lib/intel64 -I. -IInclude -I./Include -I/opt/intel/composerxe/include/intel64 -I/opt/intel/composerxe/include -I/usr/include/x86_64-linux-gnu build/temp.linux-x86_64-2.7/usr/local/src/pysrc/cpython/Modules/selectmodule.o -L/opt/intel/lib/intel64 -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -L. -lpython2.7 -o build/lib.linux-x86_64-2.7/ is then 5MB and has 6,080 symbol definitions (`nm build/lib.linux-x86_64-2.7/  | awk '{};END{print NR}'` ), most of which are local. If I copy and paste that last link command, delete '-lpython2.7', is then 63KB, and has 141 symbols, about half of which are external or undefined. It also imports okay, so seems fine and how it should be built, but Python's distutils always adds the link flag for the python shared library.

I've been sifting through the icc and ld man pages, but can't figure out exactly why these libraries are being overlinked... Is a flag missing somewhere? Does anyone know for sure that PGO doesn't work when compiling shared objects for Linux?

Ta in advance for any help or advice with this. Cheers,


0 Kudos
0 Replies