
                 LAPADA: An Ada95 binding to LAPACK
                          Wasu Chaopanon

Introduction
============

LAPADA is an Ada95 binding to LAPACK, the  widely used portable library for
linear algebra.  LAPADA is a series of Ada95 packages whose specification is
generated from the LAPACK source code.  The advantages of such an interface
are obvious enough:

 o  It makes Ada95 usable as the glue language for numeric applications, 
instead of FORTRAN, C or C++.

 o  Overloading allows us to reduce the number of routine names by an 
order of magnitude, thereby simplifying programming.
  
 o  exceptions may be used to replace error code returns.

 o  An enormous legacy of FORTRAN code becomes accessible from Ada.


LAPACK 
======

LAPACK (Linear Algebra PACKage) is a set of drivers and routines for high
level matrix operations.  It supersedes the earlier LINPACK and EISPACK
libraries.  LAPACK also contains code for the Basic Linear Algebra
Subprograms (the Level 1, 2, and 3 BLAS).  However this code is intended for
use only if there is no other implementation of the BLAS already available
on a given platform; the efficiency of LAPACK depends very much on the
efficiency of the BLAS implementation.

These packages have been originally written in Fortran.  There is a C
version of LAPACK named CLAPACK, all sources generated through f2c.  There
is also a C++ version which adds a high level layer, with classes,
overloading and a set of new drivers, named LAPACK++.

The complete package, including test code and timing programs for four
Fortran data types (real, complex, double precision, double complex)
contains some 735,000 lines of Fortran source and comments, and about 1000
functions.

LAPACK has been thoroughly tested on many different platforms.  A number of
technical reports were written during the development of LAPACK and
published as LAPACK Working Notes, initially by Argonne National Laboratory
and later by the University of Tennessee.  Most of these working notes are
available in postscript form from netlib.

The Ada95 standard defines an interface package to FORTRAN (Annex B.5 of 
the Ada RM), whose purpose is to simplify mixed-language programming in 
numeric applications.  The types declared in this package together with 
the pragma convention FORTRAN, are the basic tools we use in the LAPACK 
binding.  

Our first interface is a one-to-one mapping of LAPACK routines to Ada95 
routines.  This interface allows the user who is familiar with LAPACK to 
translate his programs into Ada with the least effort.  On top of this 
interface we create a smaller one, that uses overloading to reduce the 
number of primitives that the Ada user has to know.

Using LAPACK
=============

To use a given LAPACK subroutine in Ada, one needs to do the following:

  o  Write Ada subprogram specification of LAPACK subprogram.      
Define the data types of its parameters as Fortran data types, given by 
Interfaces.Fortran package.

  o  Declare the Ada subprogram to be imported from, and following the     
convention of, FORTRAN, by means of the corresponding pragmas.  

In order to link, the following switches must be used:

	"-llapack" for the LAPACK library itself,
	"-lblas" for the BLAS routines needed by LAPACK,
	"-ftn" or "-lf2c" or "-F77" for standard Fortran libraries which 
is used to create LAPACK library.

The linker switch can be embedded in the program by means of pragma
Linker_Option.  The specially compiler and linker switch may be required
depend on system.

Interface Testing
=================

The current ACVC suite does not provide any tests for multilanguage
programming.  The ANNEX B testing suite tests only Ada programs. 
We have created a small test suite, written in FORTRAN and Ada, to
exercise some of the  functionality of LAPACK, We have tested
the following aspects of our bindings:

1) Passing parameter from/to Fortran and Ada for the following data 
types
	a) Scalar types, including 
		Integer, Real, Double_Precision, Complex, Complex_Star_16,
		Character and Logical
	b) The array of each of the above data types (matrices)
	c) String type (only fixed size strings)

2) Passing access of functions to Fortran.

Note that multidimensional array types constructed in Ada and
passed to LAPACK routines must be declared to have Convention Fortran,
to insure that they are stored in column-major order. Subtypes of such
types automatically inherit the same convention.

Our bindings required a change to Interfaces.Fortran by adding a size 
clause for type Logical (which is absent from the published  ANNEX B).

The package Interfaces.Fortran does not define the equivalent of the 
FORTRAN type COMPLEX*16.  For completeness, we have added it to our 
package, which is explicitly allowed of an implementation of Ada95.

Link names for subprograms.
===========================

The symbolic names of the compiled subprograms depend on the compiler.  
In our work on SunOS, we used a Fortran compiler, F77, that generates 
link names according to a different convention than that used by GNAT.  
Fortunately, we can use the pragma Import to specify the correct link 
name.

Parameter Modes.
================

For scalar parameters of mode In-Out, Ada semantics requires copy-
in/copy-out.  There is no specification for the binding of In 
parameters, because the compiler can insure that they are never assigned 
to, and can therefore choose either copy or reference for them.  If the 
Ada code interfaces to a foreign routine, there is of course no 
enforceable guarantee that an In parameter will not be modified by the 
foreign code.  This is mentioned in the ARM:

  RM95;5.95 B.1(44) 
  "An Interfacing pragma might result in an effect that violates Ada 
semantics"

  RM95;5.95 B.5(25) implementation advice 
  
  "An Ada parameter of an elementary, array, or record type T is passed 
as a TF argument to a Fortran procedure, where TF is the Fortran type 
corresponding to the Ada type T, and where the INTENT attribute of the 
corresponding dummy argument matches the Ada formal parameter mode; The 
Fortran implementation's parameter passing conventions are used.  For 
elementary types, a local copy is used if necessary to ensure by-copy 
semantics."
 
In the presence of old FORTRAN code, it might be simplest to declare all
parameters as In-Out to indicate that there is no certainty that constants
are respected.  Fortunately, LAPACK is well-documented.  All formal parameters
have declared modes in comments in source code, which makes the choice of
In parameters in the interface safe for use.  We must reiterate that the
parameter mode specification is not necessary reliable, and the user should
inspect the LAPACK code when in doubt.

The construction of  LAPADA
===========================

The current implementation required the following steps:

	1.  Gnat support
		Debuging the important pragmas in GNAT 

	2.  Building the Ada bindings

		2.1 basic binding 
		2.2 Use of overloading
		2.3 handling of specialized matrix formats.
		2.4 Reduce number of parameters by using attributes.
		2.5 Use Exception, to signal error, rather than the
                    conventional status variable INFO.

	3.  Testing
                3.1  Basic interface testing.
                3.2  Exercise of LAPACK test programs from Ada.

1.) We tested interfacing between the GNAT Ada95 compiler, and F77 Fortran
compiler on Sun platform, and with G77 on  Linux. Release 3.04 of GNAT
(to become the official release in late March 1996) supports the Fortran
interface pragmas in full.  

2.1) Basic binding is in one-to-one correspondence with LAPACK subroutines.  
It is found in packages labase, laaux, lacmp, and labaseio.

a) The labase package is a collection of Fortran data types that use in LAPACK. 
The basic elementary data types are already pre-defined in interface.fortran
standard library.  We defined Complex_Star_16 to correspond to COMPLEX*16 in
Fortran.  The vector and matrix data abstraction are provided in this base
package.  Four access_to_function types are  also defined.

b) The laxxx packages are divided into three packages ladrv, lacmd, laaux
packages corresponding to driver, computational and auxiliary routines of
LAPACK.  These packages are extracted from LAPACK Fortran source code.  To
create the Ada specification of LAPACK subroutine, we collect the following
information:

	a) The subroutine name, function name and parameters list from the 
SUBROUTINE and FUNCTION declaration.
	b) The parameter type comes the declaration part of subroutine in 
Fortran.  
	c) The parameter mode from comments in the source.

The pragma import is added for each routine.  All subprogram declarations
and pragmas are generated automatically from the LAPACK source, by means of
a small perl script.  We use perl because it is suitable to text processing
and ideal for fast developement.

This script may be modified to provide more general Fortran bindings, but
is currently specialized for LAPACK. The users should feel free to modify
for other applications. More sophisticated interfaces may require 
more detailed knowledge of Fortran syntax and semantics. Currently the
script does the following;

- distinguishes between Fortran IV, Fortran 77 and Fortran 90 by means
  of a  command line option.
- parses out comments
- recognizes continuation lines 
- estracts subprogram name, parameters, and return type if it is a function
- extracts parameter type information and matches it to ada pre-defined
  type, or creates a new type when needed, e.g. for multidimensional arrays.

- Parameter mode: In Fortran 90, the intent attribute can be used. For
  older versions of Fortran, the default is in-out mode.

- generate ada specification from all the above information.

c) The basic_io consists of some output procedures for Fortran data types, 
for use with testing programs.

2.2) Overloading is one advantage of Ada over FORTRAN, helping to reduce
name space.  The LAPACK subroutine name scheme uses first character as
indicator of matrices and major parameters type.  Other parameters are 
the same for each functional group.  From these, we can do simple
overloading by renaming all four procedures to the single common name
without the type tag character.  Thus the second level interface
is considerably smaller.

For example:

SGESV, DGESV, CGESV and ZGESV are routine for solving linear equation.  The
major parameter data types are Real, Double precision, Complex and COMPLEX*16
respectively.  Other parameters are all the same.  We rename each routine to
GESV by means of  the proper renaming declarations.

2.3) A higher level interface may be possible.  Many LAPACK functional
groups are designed to accept six different matrix representations (packed
storage, band storage, etc.).  The abstraction of these matrices can be
defined as new data types.  Then we have to write short procedure to extract
attribute from each data type and call the base binding routine.  From this
work, the Simple linear driver routines in Fortran will be reduced from 33
subroutine names to single entry procedure by overloading.  This principle
is used in the implementation of LAPACK++.

2.4) The Ada array data type is self-describing, unlike it FORTRAN 
countrpart.  In FORTRAN, bounds are typically specified by additional
parameters.  In the Ada interface, it is reasonable
to use default values for these as often as possible.  In addition, array
attributes simplify the interface by omitting explicit parameters in the
specification.  However, these method reduce flexibility of routines that work
on portions of a  matrix.  We can overload these reduced parameter routines 
with full version to maintain capability.  Using default expression for
these cases is illegal.

For example, one series of LAPACK procedures computes A x = B.  The
corresponding FORTRAN routines have 8 parameters, 2 for the arrays involved,
and 4 for their dimensions.  In Ada, we only need to specify the 2 array
types, and in the body of the interface procedure there is a call to the
LAPACK subroutine with all bounds made explicit.

2.5) In LAPACK, the INFO parameter is used for data error status.  It is more
convenient in Ada to use an exception mechanism to handle error conditions. 
However, INFO parameter value encodes the  error type and the  position of data
at which the error occurred, which cannot be conveyed by  an exception.

----------------------------------------------------------------------------

3.) Testing is done in two stages.  First we must test interfacing, to
insure that the binding supports the coomon data types. For more
substantial testing, call the LAPACK-supplied testing programs from
Ada drivers. We have written such programs for simple linear driver,
simple linear least squares driver and simple Eigen value problem).  

Because of time limitations, the current implementation only provides
basic binding and overloading.  We have not implemented yet the handling
of specialized matrix  representations.

Conclusion
==========

LAPADA is not perfect yet, but it is already eminently usable.
Higher level binding (i.e. smaller interfaces)  may be possible.
More intensive testing is required. We hope that the users will
provide us with the feedback necessary to enhance these bindings,
and report on their successes in using it.

References
==========

LAPACK information:http://www.netlib.org/lapack/

LAPACK Users' Guide, Second Edition: E. Anderson [et al], SIAM,
Philadelphia, US, 1995.  
also in eletronic form at
http://www.netlib.org/lapack/lug/lapack_lug.html

LAPACK++: A Design Overview of Object-Oriented Extension for High 
Performance Linear Algebra: Jack J. Dongarra, Roldan Pozo, and David W. 
Walker.

Ada reference manual, language and standard libraries, version 5.95,
International standard ISO/IEC 8652:1995(E)-RM95;5.95.

American National Standard programming language Fortran approved April 
3,1978; American National Standard Institute, New York, ANSI c1978.

Miscellaneous Notes.
====================

(1)  Link names in g77 and f77 use different conventions.

g77 creates a symbolic name by adding two
underscore after a name, if that name already contains an underscore
anywhere, while f77 adds only one in all cases.

Ex.  For fortran code:

	subroutine finc 

   g77 and f77 create symbol "finc_" 

BUT
	subroutine f_inc 

   g77 will create symbol "f_inc__"
   f77 will create symbol "f_inc_"

So, the corresponding pragma Import in Ada program must be written 
taking into account  the Fortran compiler in use.

Fortunately, these problem does not effect to any LAPACK code because 
LAPACK does not use underscore in subprogram names.  They are however
used in BLAS.  

(2) ANSI FORTRAN 77: Logical storage size is equal to integer.

(3) Static option for linker step: In SunOS, linker step require linker
option -static.  That is we can not use lapack as shared library.  The
reason is when shared Fortran object code return, it looked for main
re-entry point but GNAT did not create this entry.

(4) The function ZGEESX is not working yet because of a seeming incompatibility
between Gnat and F77 in passing COMPLEX*16 data type. This only occurs when
passing an access_to_Function, whose parameters have that type (simple
values of that type cross the interface without problems).

