From: Gautier <gautier.demontmollin@maths.unine.ch>
Subject: Re: BLAS binding
Date: 2000/05/11
Date: 2000-05-11T00:00:00+00:00 [thread overview]
Message-ID: <391ACCA0.7EA82894@maths.unine.ch> (raw)
In-Reply-To: 8fdrdf$pag$1@upsn21.u-psud.fr
Marvelous! When I find some time I'll use your binding.
For now I'm using an excerpt, of course also with "digits <>"
genericity for float type and with hastly conception - see below.
Maybe the "BLAS_Precision" could be added as generic parametre
for equilibirum with the generic "digits <>" ? Another solution
would be to pass as generic:
1) the type you want to use, type Float_Type is digits <>;
2) the type which you know is single, type Single is digits <>;
3) the type which you know is double type Double is digits <>;
and automatically identify the type with the 'digits or another more
subtle criterion. Surely for Ada 95, the Interface.Fortran package
contains 2) and 3) so you can determine the "BLAS_Precision" only
with 1) as generic, but then you'd lose the Ada 83 compatibility.
Gautier
===========
-- Linear Algebra routines for Sparse package, mapped to BLAS library
generic
type real is digits <>;
type index is range <>;
type vector is array(index range <>) of real;
package SparseB1 is
procedure Copy( u: in vector; v: out vector );
function "*"(u,v: vector) return real;
procedure Add_scaled( factor: real; u: in vector; v: in out vector );
procedure Scale( factor: real; u: in out vector );
end SparseB1;
package body SparseB1 is
-- identify floating point type
-- wishful thinking about float=single, long_float=double!
is_single: constant boolean:=
real'digits = float'digits;
is_double: constant boolean:=
real'digits = long_float'digits;
procedure scopy(n: natural; x: in vector; incx: integer;
y: out vector; incy: integer);
procedure dcopy(n: natural; x: in vector; incx: integer;
y: out vector; incy: integer);
pragma Interface(FORTRAN, scopy);
pragma Interface(FORTRAN, dcopy);
function sdot(n: natural; x: in vector; incx: integer;
y: in vector; incy: integer) return real;
function ddot(n: natural; x: in vector; incx: integer;
y: in vector; incy: integer) return real;
pragma Interface(FORTRAN, sdot);
pragma Interface(FORTRAN, ddot);
procedure saxpy(n: natural; a: real; x: in vector; incx: integer;
y: in out vector; incy: integer);
procedure daxpy(n: natural; a: real; x: in vector; incx: integer;
y: in out vector; incy: integer);
pragma Interface(FORTRAN, daxpy);
pragma Interface(FORTRAN, saxpy);
procedure sscal(n: natural; a: real; x: in out vector; incx: integer);
procedure dscal(n: natural; a: real; x: in out vector; incx: integer);
pragma Interface(FORTRAN, sscal);
pragma Interface(FORTRAN, dscal);
procedure Copy( u: in vector; v: out vector ) is
begin
if is_single then
scopy(u'length, u,1,v,1);
elsif is_double then
dcopy(u'length, u,1,v,1);
else
v:= u;
end if;
end;
function "*"(u,v: vector) return real is
begin
if is_single then
return sdot(u'length, u,1,v,1);
elsif is_double then
return ddot(u'length, u,1,v,1);
else
declare uv: real:= 0.0;
begin
for i in u'range loop
uv:= uv + u(i)*v(i);
end loop;
return uv;
end;
end if;
end;
procedure Add_scaled( factor: real; u: in vector; v: in out vector ) is
begin
if is_single then
saxpy(u'length, factor, u,1,v,1);
elsif is_double then
daxpy(u'length, factor, u,1,v,1);
else
for i in u'range loop
v(i):= v(i) + factor * u(i);
end loop;
end if;
end;
procedure Scale( factor: real; u: in out vector ) is
begin
if is_single then
sscal(u'length, factor, u,1);
elsif is_double then
dscal(u'length, factor, u,1);
else
for i in u'range loop
u(i):= factor * u(i);
end loop;
end if;
end;
pragma inline("*", Add_scaled, Scale);
end SparseB1;
prev parent reply other threads:[~2000-05-11 0:00 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2000-05-11 0:00 BLAS binding Duncan Sands
2000-05-11 0:00 ` Gautier [this message]
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox