tech-pkg archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Deciding on wich variant(s) of OpenBLAS library to install



To boil it down …

Am Tue, 20 Feb 2018 22:09:57 +0100
schrieb "Dr. Thomas Orgis" <thomas.orgis%uni-hamburg.de@localhost>:

> I think we should start with a concept along those lines and implement
> BLAS fun in pkgsrc The Right Way™, before we get into a mess with
> packages depending on differing sets of BLAS libraries.

If we start installing multiple variants of openblas next to each
other, we really should have a way to avoid accidental linkage of
more than one of them into the same program. Consider this example
scenario:

I wrote some trivial libraries:

shell$ cat liba.c 
#include <stdio.h>

void work(void)
{
	printf("This is library A working.\n");
}
shell$ cat libb.c 
#include <stdio.h>

void work(void)
{
	printf("This is library B working.\n");
}
shell$ cat libx.c 
#include <stdio.h>
#include "lib.h"

void x_work(void)
{
	printf("This is library X calling (libary A, hopefully).\n");
	work();
}
shell$ cat liby.c 
#include <stdio.h>
#include "lib.h"

void y_work(void)
{
	printf("This is library Y calling (libary B, hopefully).\n");
	work();
}

Observe how liba and libb both define the same function symbol work(),
just like any implementation of a BLAS library. Consider liba ==
libopenblas_openmp and libb == openblas_serial, or even liba == libblas
(netlib, slow)! The libraries libx and liby can be libsomestatistics and
libsomefancymath, both being used by the same program in the end.

Then an equally trivial program using them:

shell$ cat prog.c 
#include "libx.h"
#include "liby.h"

int main()
{
	x_work();
	y_work();
}

Working it out, assuming we all already know/suspect what should happen
…

shell$ make prog_xy prog_yx
gcc -O -Wl,-R/stuff/src/blastest -fPIC -shared  -o liba.so liba.c
gcc -O -Wl,-R/stuff/src/blastest -fPIC -shared  -o libx.so libx.c liba.so
gcc -O -Wl,-R/stuff/src/blastest -fPIC -shared  -o libb.so libb.c
gcc -O -Wl,-R/stuff/src/blastest -fPIC -shared  -o liby.so liby.c libb.so
gcc -O -Wl,-R/stuff/src/blastest -o prog_xy prog.c libx.so liby.so
gcc -O -Wl,-R/stuff/src/blastest -o prog_yx prog.c liby.so libx.so
shell$ ldd prog_xy 
	linux-vdso.so.1 (0x00007ffe0bba7000)
	libx.so => /stuff/src/blastest/libx.so (0x00007fb598003000)
	liby.so => /stuff/src/blastest/liby.so (0x00007fb597e01000)
	libc.so.6 => /lib/libc.so.6 (0x00007fb597a8d000)
	liba.so => /stuff/src/blastest/liba.so (0x00007fb59788b000)
	libb.so => /stuff/src/blastest/libb.so (0x00007fb597689000)
	/lib/ld-linux-x86-64.so.2 (0x00007fb598205000)
shell$ ldd prog_yx 
	linux-vdso.so.1 (0x00007ffdfb3f2000)
	liby.so => /stuff/src/blastest/liby.so (0x00007f9007afe000)
	libx.so => /stuff/src/blastest/libx.so (0x00007f90078fc000)
	libc.so.6 => /lib/libc.so.6 (0x00007f9007588000)
	libb.so => /stuff/src/blastest/libb.so (0x00007f9007386000)
	liba.so => /stuff/src/blastest/liba.so (0x00007f9007184000)
	/lib/ld-linux-x86-64.so.2 (0x00007f9007d00000)
shell$ ./prog_xy 
This is library X calling (libary A, hopefully).
This is library A working.
This is library Y calling (libary B, hopefully).
This is library A working.
shell$ ./prog_yx 
This is library X calling (libary A, hopefully).
This is library B working.
This is library Y calling (libary B, hopefully).
This is library B working.


Once we have several BLAS libraries just like that in $PREFIX/lib,
without any mechanism to ensure that packages consistently link to one
of them, possibly, but not necessarily decided at runtime via
LD_LIBRARY_PATH or symlinks by sysadmin, we are just begging for a
situation like that happening. What code will be called from libx
isjust depending on the link order of libx and liby in a dependent
package! This can go wrong in so many ways … even if it's just the
simple bug of “Why is my program so slow, I thought I linked it against
OpenBLAS!”.

So, if we have that possible ambiguity of many implementations of the
same API/ABI, we should either deal with it properly or avoid it
altogether.

So, if this is all too complex, a simple choice of exactly one variant
of BLAS (be it netlib, atlas, or openblas) per pkgsrc installation
(bulk build) is the sane thing to offer, including strict conflicts of
the different implementations to avoid ambiguous installations.

Which one shall it be? Take your pick:

[ ] parallel installation of separated BLAS implementations with
    symlinks and/or LD_LIBRARY_PATH/LD_RUN_PATH fun to choose one at link-
    and/or runtime or

[ ] just one global choice by the admin for one BLAS variant to build


I need _some_ way forward, as I am way behind schedule to get a fresh
pkgsrc install rolling here. I wanted to replace my local openblas hack
with something that is going to enter pkgsrc proper. This is your
chance to steal some (more) of my time to contribute;-)


Alrighty then,

Thomas

PS: Of course I can override what the libs pull in by linking directly to liba:

shell$ gcc -O -Wl,-R/stuff/src/blastest -o prog_yx prog.c liby.so libx.so liba.so
shell$ ./prog_yx
This is library X calling (libary A, hopefully).
This is library A working.
This is library Y calling (libary B, hopefully).
This is library A working.

All in all, this doesn't feel good. Without playing LD_PRELOAD games,
this is just not right. Don't multiply library symbols. It kills
kittens.

-- 
Dr. Thomas Orgis
Universität Hamburg
RRZ / Basis-Infrastruktur / HPC
Schlüterstr. 70
20146 Hamburg
Tel.: 040/42838 8826
Fax: 040/428 38 6270

Attachment: smime.p7s
Description: S/MIME cryptographic signature



Home | Main Index | Thread Index | Old Index