This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
Re: [fortran,patch] BLAS-enabled matmul
- From: FX Coudert <fxcoudert at gmail dot com>
- To: Steve Kargl <sgk at troutmask dot apl dot washington dot edu>
- Cc: gfortran <fortran at gcc dot gnu dot org>, patch <gcc-patches at gcc dot gnu dot org>, bmoses at stanford dot edu, drow at false dot org, paolo dot bonzini at lu dot unisi dot ch
- Date: Tue, 04 Apr 2006 09:36:32 +0200
- Subject: Re: [fortran,patch] BLAS-enabled matmul
- References: <44319954.7010203@gmail.com> <20060403222352.GA99591@troutmask.apl.washington.edu>
Answering to most critics as they're all related...
All in all, I'm most favorable to Brooks' suggestion that we have
libgfortran_blas and libgfortran_external_blas, i.e. an additional
function call. The only thing that I don't yet see clearly how to
resolve is we can avoid the user supplying the -fblas="-lblas" extra
argument, and simply link in its blas library by "-lblas".
Steve Kargl wrote:
I won't have time to review this until Saturday. One quick question.
Will gfortran grab the optimized blas routines with the following
gfortran file.f90 -L/some/path/to/blas -loptimized_blas
Brooks Moses wrote:
> A couple of other related problems: What if someone just has a code
> that calls DGEMM, and _does_ remember to link in their favorite BLAS
> library? My impression is that your patch will break the way this
> would normally work, because the only way to link it without symbol
> clashes would be to go through explicitly wrapping it in
> -fexternal-blas, rather than simply linking it as they would
> any other library.
Humpf, using blas this way actually leads to very confusing situations:
[b.f90 calls matmul and dgemm]
$ gfortran b.f90 -llapack -lcblas -lf77blas -latlas
libgfortran_blas.a(libgfortran_blas.o): In function `dgemm_':
libgfortran_blas.c:(.text+0x551): multiple definition of `dgemm_'
libf77blas.a(dgemm.o):dgemm.f:(.text+0x0): first defined here
/usr/bin/ld: Warning: size of symbol `dgemm_' changed from 716 in
libf77blas.a(dgemm.o) to 1358 in libgfortran_blas.a(libgfortran_blas.o)
collect2: ld returned 1 exit status
$ gfortran b.f90 -llapack -lcblas -lf77blas -latlas -fexternal-blas=
libgfortran.so: undefined reference to `cgemm_'
libgfortran.so: undefined reference to `sgemm_'
libgfortran.so: undefined reference to `zgemm_'
collect2: ld returned 1 exit status
This is clearly not something we want.
Steve Kargl wrote:
The driver should build a list of libraries of the form
"-loptimized_blas -lgfortranbegin -lgfortran -lgfortran_blas -lgfortran -lm"
with -L/some/path/to/blas in the search path.
That can't be, since libgfortran needs symbols from liboptimized_blas,
the external BLAS really needs to be used after "usercode.o -lgfortran"
Brooks Moses wrote:
> Also, this libgfortran_called_blas variable doesn't sound especially
> thread-safe.
Right.
Brooks Moses wrote:
> To avoid all possible conflicts with user calls to dgemm_ and the
> like, don't use the BLAS names in our library. Instead, use names
> like dgemm_libgfortran (or something more appropriate) instead, and
> have our library call those.
>
> Then, create two different libraries that provide these symbols.
> One of them is based on yours, and provides a minimal BLAS-like
> implementation. The other (called libgfortran_external_blas.c,
> perhaps) just passes the calls through to a "real" BLAS. If the
> -fexternal_blas option is used, the latter library is linked in,
> otherwise, the former is linked in.
>
> This does have the disadvantage of adding another level of indirection
> to any calls to an external BLAS library, though.
I don't think the extra function call will impact performance here. The
matmul/BLAS crossover is for large arrays, whose matmultiplication would
take at least a few seconds anyhow.
So, you'd have either "usercode.o -lgfortran -lgfortran_blas" or
"usercode.o -lgfortran -lgfortran_external_blas -lblas -L/path/to/blas
-lgfortran", depending wether -fexternal-blas="-lblas -L/path/to/blas"
was provided or not.
Daniel Jacobowitz wrote:
> This is pretty nasty. If I were designing a command line interface
> for this, it would just be "-fexternal-blas disables inclusion of the
> default libgfortran_blas.a". Can't we get that to work? Maybe with
> --start-group and --end-group?
That would work, but only for the GNU ld, doesn't it? Is there a way in
gfortranspec.c to know whether we'll talk to a GNU ld or another beast?
In any case, that would mean overriding the user's possibly fine-tuned
link order, which is not a light decision.
Paolo Bonzini wrote:
> Then, instead of having -fexternal-blas="aaa", just have -fblas
> (linking -lgfortran_blas) vs. -fno-blas (linking -lgfortran). It's up
> to the user to link in a suitable BLAS library, or he/she will get
> undefined references.
But that won't work because, if someone says "gfortran a.f90 -fblas
-lblas", it will end up as "gfortran a.f90 -lblas -lgfortran_blas",
which contanis undefined references to libblas in libgfortran_blas.
Other than that, I think it's a good idea if implemented with only a
part of libgfortran, like Brooks suggested. The libgfortran is too big
to duplicate.
FX