From mtmorgan at fhcrc.org  Mon May 14 05:34:53 2007
From: mtmorgan at fhcrc.org (Martin Morgan)
Date: Sun, 13 May 2007 20:34:53 -0700
Subject: [Rd] Help understanding LAPACK symbol resolution
In-Reply-To: <Pine.LNX.4.64.0705132040280.27271@auk.stats> (Brian Ripley's
	message of "Sun, 13 May 2007 20:58:44 +0100 (BST)")
References: <6phtzuga5n9.fsf@gopher4.fhcrc.org>
	<Pine.LNX.4.64.0705132040280.27271@auk.stats>
Message-ID: <6phhcqg9ixu.fsf@gopher4.fhcrc.org>

Prof. Ripley,

Thank you for the very helpful guidance and pointer to fastICA. 

Martin

Prof Brian Ripley <ripley at stats.ox.ac.uk> writes:

> On Sun, 13 May 2007, Martin Morgan wrote:
>
>> R developers,
>>
>> I am trying to understand how symbols are resolved, so that I can
>> configure a package that I contributed to, and so that I can provide
>> guidance to (linux / OSX) users of the package. To be concrete, my
>> package uses the LAPACK Fortran symbol zsysv. This is not in
>> libRlapack, but is defined on my system in the library
>> /usr/lib64/liblapack.so.
>>
>> * I suspect that the reason the symbol is not in libRlapack is just
>>  one of economy, i.e., no use for the symbol in R routines, rather
>>  than for other nefarious reasons (?? some fundamental incompatibility
>>  with R?)
>
> Space saving.  'Writing R Extensions' covers this.
>
>> I guess that most of my package users will have an R built without
>> special attention to their lapack library, so will start with
>> something like
>>
>> mtmorgan at gopher4:~> R CMD config LAPACK_LIBS
>> -L/home/mtmorgan/arch/x86_64/R-devel/lib -lRlapack
>>
>> My R is built with --enable-R-shlib, so predictably enough
>>
>> R CMD INSTALL --clean <pkg>
>>
>> is 'successful' (zsysv_ is marked as unresolved in the <pkg>.so, but
>> this doesn't stop compiling and linking). Also predictably enough,
>> loading the package in R indicates 'undefined symbol: zsysv_'. Inside
>> R, LD_LIBRARY_PATH starts with he R_HOME/lib, and includes /usr/lib64,
>> so I surmise that the libraries defined at compile / link are the ones
>> where symbols are searched (rather than all libraries in
>> LD_LIBRARY_PATH).
>
> Not the way R is usually built.  Library dirs specified by -L during
> configure are added to R_LIBRARY_PATH, but not those specified by the
> environment LD_LIBRARY_PATH at build time.  Most loaders have a
> -R/-rpath option, but R does not (by default) make use of it.  (I
> personally think it should: ELF originates on Solaris and that makes
> very effective use of -R.)
>
> At run time ld.so searches its cache as well as LD_LIBRARY_PATH.  The
> order is system-specific: Linux says
>
>     o (ELF only) Using the DT_RPATH dynamic section attribute  of  the
>       binary  if present and DT_RUNPATH attribute does not exist.  Use
>       of DT_RPATH is deprecated.
>
>     o Using the environment variable LD_LIBRARY_PATH.  Except  if  the
>       executable  is  a set-user-ID/set-group-ID binary, in which case
>       it is ignored.
>
>     o (ELF only) Using the DT_RUNPATH dynamic section attribute of the
>         binary if present.
>
>     o From  the  cache file /etc/ld.so.cache which contains a compiled
>       list of candidate libraries previously found  in  the  augmented
>       library  path.  If, however, the binary was linked with -z node-
>       flib linker option, libraries in the default library  paths  are
>       skipped.
>
>     o In  the default path /lib, and then /usr/lib.  If the binary was
>       linked with -z nodeflib linker option, this step is skipped.
>
> (and for a 64-bit system, read lib64 for lib).
>
>
>> To allow the user to provide a specific LAPACK, I added lines to a
>> configure.in file that allow for a --with-lapack
>>
>> LAPACK_LIBS=`"${R_HOME}/bin/R" CMD config LAPACK_LIBS`
>> AC_ARG_WITH([lapack],
>> 	AC_HELP_STRING([--with-lapack=LIB_PATH],
>> 		[LAPACK library location with complex routines]),
>> 		[LAPACK_LIBS=$withval])
>>
>> added a check to see that zsysv_ is actually available
>>
>> AC_CHECK_FUNC(zsysv_,,
>> 	AC_MSG_ERROR([lapack needs zsysv_ in ${LAPACK_LIBS}]))
>>
>> and substituted LAPACK_LIBS into a Makevars.in file
>>
>> AC_SUBST(LAPACK_LIBS)
>> AC_OUTPUT(src/Makevars)
>>
>> Makevars.in:
>> PKG_LIBS=@LAPACK_LIBS@
>>
>> I then install my package with
>>
>> R CMD INSTALL --clean --configure-args=--with-lapack=-llapack <pkg>
>>
>> or more generally
>>
>> R CMD INSTALL --clean \
>>   --configure-args="--with-lapack='-L/usr/lib64 -llapack'" <pkg>
>>
>> This 'works', in the sense that the package compiles, loads, and
>> apparently runs as expected. I'm concerned though about how lapack is
>> being found, and how symbols are actually being resolved.
>>
>> When I
>>
>> mtmorgan at gopehr4:~> ldd <pkg>.so
>>
>> I see an entry
>>
>>        liblapack.so.3 => /usr/lib64/liblapack.so.3 (0x00002b0928a1c000)
>>
>> and I do NOT see an entry pointing to libRlapack .Am I right in
>> interpreting this to mean:
>>
>> * All LAPACK symbols in my package, including those that
>>  coincidentally have a definition in libRlapack, resolve to
>>  /usr/lib64/liblapack.so?
>
> Yes.  libRlapack.so will not be in the search path.
>
>> * liblapack.so will be found without any need to specify
>>  LD_LIBRARY_PATH, or other configuration variables? Or is the library
>>  being found because my LD_LIBRARY_PATH already includes /usr/lib64?
>
> Both ld (used for linking) and ld.so (used a runtime) look in that
> path by default.
>
>>  If the latter, how can the user 'best' configure their system to
>>  find the required library (I think I'm looking for something between
>>  'get the system administrator to install lapack in a findable place'
>>  and 'set LD_LIBRARY_PATH before starting R').
>
> Better to set it in the ld.so cache (via a file in /etc/ld.so.conf.d
> on a modern system), and set -L at build time.
>
>> * Resolving symbols to libraries will occur in a way consistent with
>>  the last two points (as opposed to the implementation details)
>>  across platforms, compilers, and static vs. shared libraries?
>>
>> Thanks for any reassurance or corrective guidance.
>
> The standard advice would be to supply the LAPACK routines in the
> package, and compile them if they are not found in $LAPACK_LIBS.
> Remember that there are quite a few buggy LAPACKs out there so it is
> better to use your own than a system one that might be faster but
> inaccurate.
>
> As I recall, fastICA is an example of the latter strategy.
>
> -- 
> Brian D. Ripley,                  ripley at stats.ox.ac.uk
> Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
> University of Oxford,             Tel:  +44 1865 272861 (self)
> 1 South Parks Road,                     +44 1865 272866 (PA)
> Oxford OX1 3TG, UK                Fax:  +44 1865 272595

-- 
Martin Morgan
Bioconductor / Computational Biology
http://bioconductor.org



[Rd] Help understanding LAPACK symbol resolution
Martin Morgan