comp.lang.ada
 help / color / mirror / Atom feed
* Ada-FORTRAN Interfacing
@ 1998-02-24  0:00 Andy Willey
  1998-02-25  0:00 ` Laurent Guerby
  0 siblings, 1 reply; 3+ messages in thread
From: Andy Willey @ 1998-02-24  0:00 UTC (permalink / raw)



I am attempting to link Ada and FORTRAN modules together.  I am using
GNAT Ada and the GNU FORTRAN compiler.  If anyone knows of any
documentation or examples that specifically address the Ada-FORTRAN
interface, please let me know.

Thanks -- Andy
willeya@dr-inc.com





^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Ada-FORTRAN Interfacing [longish -- source excerpts]
  1998-02-25  0:00 ` Laurent Guerby
@ 1998-02-25  0:00   ` John M. Mills
  0 siblings, 0 replies; 3+ messages in thread
From: John M. Mills @ 1998-02-25  0:00 UTC (permalink / raw)



Laurent Guerby <guerby@pauli.cnam.fr> writes:

>Andy Willey <willeya@dr-inc.com> writes:
>> I am attempting to link Ada and FORTRAN modules together.  I am using
>> GNAT Ada and the GNU FORTRAN compiler.  If anyone knows of any
>> documentation or examples that specifically address the Ada-FORTRAN
>> interface, please let me know.
>   I know there are some quite active people doing Ada/FORTRAN things,
>   may be they don't read comp.lang.ada anymore?

I exchanged notes on this with a c.l.a. reader, and here is a summary of my
linking Ada through Fortran from Ada.  I think this may fairly be called a
"worst case scenario" &;^) Essentially the same summary is on my anon-ftp
site:
     ftp://jmills.gtri.gatech.edu/pub

This built on various platforms with various Fortran compilers, though I have
no guarantees to offer.  The application will be familiar to many readers of
_Numerical Recipes in *_:

****
Date: Fri, 25 Jul 1997 09:49:50 -0400 (EDT)
From: "MILLS,JOHN M." <jm59@prism.gatech.edu>
To: ****
Subject: Re: Fortran Interfacing
Reply-To: john.mills@gtri.gatech.edu

> Can anybody tell me how to EXPORT from Ada to fortran.  I have 
> a large program written in fortran and wish to include it in an Ada 
> program.  I think I can manage the import quite easily (there are 
> plenty of examples around, and I have managed on a test program), 
> but I cannot manage the export (there are NO examples I can find and 
> I can't manage a test program).
> 
> If someone could write/ or explain how I could write, a small test 
> program that called a Fortran subroutine that in turn called an Ada 
> program I would be very grateful.  

<Reader> --

I coded a case where I called a Fortran subroutine from a GNAT-3.05
Ada main, and passed to the subroutine pointers ('access procedure') to
both Fortran and Ada subroutines.  The Ada pointer was in its turn passed
to the Fortran subroutine identified by its pointer.  Vectors of LONG_FLOATs
were also passed from Fortran to Ada and back.  There are probably a few
more possible paths, but I would say that was a start.  I took four steps
to do this:
1) I provided an Ada specification for the Fortran routines, and
2) I provided a "shim" called by Fortran which called my Ada with appropriate
   data types,
3) I exported the entries of the Ada routines as Fortran, and
4) I had to provide a global Ada variable as a "selector" which was set in
   Ada before calling the Fortran, then checked in Ada called from Fortran.
   (This was due to my Ada code design, and allowed the passing of strictly
   numerical data arrays among the players -- I can't guarantee re-entrancy
   of the result, but I was trying to trap competing calls from possible
   other GIMBAL objects.)

You may recognize that I am using a Runge-Kutta integration patterned on
the example in _Numerical_Recipes_ -- no modifications were needed in the
precompiled Fortran library which was widely used by other applications.
 
Here are the wrappers in the Ada spec for the Fortran subroutine package:

******< from ode.ads >******

with  DATA_TYPES;
use   DATA_TYPES;
 
package ODE is
 
  -- NMAX must stay in sync with <BLAH, BLAH>
  NMAX  : constant INTEGER := 20;
 
type VAR_ARRAY is array (1 .. NMAX) of LONG_FLOAT;
 
type DERIV_ACCESS is access   -- access to Ada, used from Fortran
      PROCEDURE(  X     : in out LONG_FLOAT;
                  Y     : in out VAR_ARRAY;
                  DYDX  : in out VAR_ARRAY);
pragma CONVENTION(FORTRAN, DERIV_ACCESS);
 
type STEPPER_ACCESS is access   -- access to Fortran, used from Fortran
      PROCEDURE(  Y         : in out  VAR_ARRAY;
                  DYDX      : in out  VAR_ARRAY;
                  N         : in out  INTEGER;
                  X         : in out  LONG_FLOAT;
                  HTRY      : in out  LONG_FLOAT;
                  EPS       : in out  LONG_FLOAT;
                  YSCAL     : in out  VAR_ARRAY;
                  HDID      : in out  LONG_FLOAT;
                  HNEXT     : in out  LONG_FLOAT;
                  THE_DERIVS: DERIV_ACCESS);
pragma CONVENTION(FORTRAN, STEPPER_ACCESS);
 
procedure RKQC( Y         : in out  VAR_ARRAY;  -- Fortran used from Fortran
                DYDX      : in out  VAR_ARRAY;
                N         : in out  INTEGER;
                X         : in out  LONG_FLOAT;
                HTRY      : in out  LONG_FLOAT;
                EPS       : in out  LONG_FLOAT;
                YSCAL     : in out  VAR_ARRAY;
                HDID      : in out  LONG_FLOAT;
                HNEXT     : in out  LONG_FLOAT;
                THE_DERIVS: DERIV_ACCESS);
pragma IMPORT(Fortran, RKQC, "rkqc_");
 
procedure ODEINT( YSTART        : in out  VAR_ARRAY;  -- Fortran used from Ada
                  NVARS         : in out  INTEGER;
                  X1            : in out  LONG_FLOAT;
                  X2            : in out  LONG_FLOAT;
                  EPS           : in out  LONG_FLOAT;
                  H1            : in out  LONG_FLOAT;
                  HMIN          : in out  LONG_FLOAT;
                  NOK           : in out  INTEGER;
                  NBAD          : in out  INTEGER;
                  THE_DERIVS    : DERIV_ACCESS;
                  THE_STEPPER   : STEPPER_ACCESS);
pragma IMPORT(Fortran, ODEINT, "odeint_");                     
 
*********

Here is the Ada "shim" which was actually called from Fortran:

******< from my_app.adb >******
--------------------------------------------------------------------------------
-- procedure GIMBAL_DERIVS (RK_X  : in out LONG_FLOAT;                        --
--          RK_Y   : in out array (1..GIMBAL_DERIVATIVE'SIZE) of LONG_FLOAT;  --
--          RK_DYDX : in out array (1..GIMBAL_DERIVATIVE'SIZE) of LONG_FLOAT) --
-- Computes derivatives of specified gimbal in its current state.             --
-- GIMBAL_DERIVS provides a wrapper for GET_DERIVS for use by Fortran RK4     --
-- ODE integration library routine ODEINT2DP.                                 --
--------------------------------------------------------------------------------
procedure GIMBAL_DERIVS (RK_X  : in out LONG_FLOAT;
         RK_Y   : in out VAR_ARRAY;
         RK_DYDX : in out VAR_ARRAY) is
 
  PEDESTAL_STATE        : DIRCM_STATE_VECTOR  := (others => 0.0);
  ESTIMATED_DERIVATIVES : GIMBAL_DERIVATIVE   := (others => 0.0);
 
begin
  PEDESTAL_STATE.AZIMUTH        := RK_Y(1);
  PEDESTAL_STATE.ELEVATION      := RK_Y(2);
  PEDESTAL_STATE.AZIMUTH_DOT    := RK_Y(3);
  PEDESTAL_STATE.ELEVATION_DOT  := RK_Y(4);
  ESTIMATED_DERIVATIVES :=
   GET_DERIVS( SELECTED_GIMBAL, PEDESTAL_STATE, RK_X);
  RK_DYDX(1) :=  ESTIMATED_DERIVATIVES.AZIMUTH_DOT;
  RK_DYDX(2) :=  ESTIMATED_DERIVATIVES.ELEVATION_DOT;
  RK_DYDX(3) :=  ESTIMATED_DERIVATIVES.AZIMUTH_DOT_DOT;
  RK_DYDX(4) :=  ESTIMATED_DERIVATIVES.ELEVATION_DOT_DOT;
 
end GIMBAL_DERIVS;
pragma EXPORT (Fortran, GIMBAL_DERIVS, "gimbal_derivs_");
 
--------------------------------------------------------------------------------
********

Here is the actual Ada call to the nested Fortran:

******< also from my_code.adb >*******

--------------------------------------------------------------------------------
-- procedure INTEGRATE_GIMBAL_MOTION(  THE_GIMBAL  : in out  GIMBAL;          --
--                                 THE_STATE   : in out  DIRCM_STATE_VECTOR)  --
-- wraps and invokes Fortran routines performing Runge-Kutta integration of   --
-- the gimbal equations of motion in pedestal (AZ, EL) axes.                  --
--------------------------------------------------------------------------------
procedure INTEGRATE_GIMBAL_MOTION(THE_GIMBAL  : in out  GIMBAL;
                                  THE_STATE   : in out  DIRCM_STATE_VECTOR) is
 
  YSTART          : VAR_ARRAY := (others => 0.0);
  NVARS           : INTEGER := NMAX;
  X1              : LONG_FLOAT := 0.0;
  X2              : LONG_FLOAT := 0.0;
  EPS             : LONG_FLOAT := 1.0;
  H1              : LONG_FLOAT := 0.0;
  HMIN            : LONG_FLOAT := 0.0;
  NOK             : INTEGER := 0;
  NBAD            : INTEGER := 0;
  THE_STEPPER     : constant STEPPER_ACCESS := RKQC'ACCESS;
  THE_DERIVATIVES : constant DERIV_ACCESS := GIMBAL_DERIVS'ACCESS;
 
begin    
  -- check for interfering thread
  if SELECTED_GIMBAL /= NULL then
    raise CHAINING_ERROR;
  end if;
  -- select gimbal being updated, for GET_DERIVS use
  SELECTED_GIMBAL := THE_GIMBAL;
 
  -- set up calling arguments for ODEINT
  YSTART(1) :=THE_STATE.AZIMUTH;
  YSTART(2) :=THE_STATE.ELEVATION;
  YSTART(3) :=THE_STATE.AZIMUTH_DOT;
  YSTART(4) :=THE_STATE.ELEVATION_DOT;
  NVARS := 4;
  X2        := THE_GIMBAL.TIME_STEP;
  EPS       := 0.01;
  H1        := THE_GIMBAL.TIME_STEP;
  HMIN      := 0.0;
  
  ODEINT( YSTART, NVARS, X1, X2, EPS, H1, HMIN, NOK, NBAD,
          THE_DERIVATIVES, THE_STEPPER);
 
  -- return new state of gimbal
  THE_STATE.AZIMUTH       :=  YSTART(1);
  THE_STATE.ELEVATION     :=  YSTART(2);
  THE_STATE.AZIMUTH_DOT   :=  YSTART(3);
  THE_STATE.ELEVATION_DOT :=  YSTART(4);
 
  -- reset gimbal selection
  SELECTED_GIMBAL := null;
 
end INTEGRATE_GIMBAL_MOTION;
--------------------------------------------------------------------------------
*********
 
Note:  These vectors are passed in jointly acceptable format, but if you are
passing _higher_dimension_arrays_, you need to define the Ada side of the
argument with a subscripting order appropriate to Fortran.  This is covered
in the Ada 95 LRM, and I believe the pragma is "Convention"  -- I don't have
it at hand to give you a reference.  The same problem may arise passing data
between Fortran and C, I believe, as I understand Ada95 uses the same subscript
ordering as C -- the reverse of Fortran.
 
Regards -- jmm --

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

-- 
 John M. Mills, Senior Research Engineer   --   john.mills@gtri.gatech.edu
   Georgia Tech Research Institute, Georgia Tech, Atlanta, GA 30332-0834
        Phone contacts: 404.894.0151 (voice), 404.894.6258 (FAX)
           "Lies, Damned Lies, Statistics, and Simulations."




^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Ada-FORTRAN Interfacing
  1998-02-24  0:00 Ada-FORTRAN Interfacing Andy Willey
@ 1998-02-25  0:00 ` Laurent Guerby
  1998-02-25  0:00   ` Ada-FORTRAN Interfacing [longish -- source excerpts] John M. Mills
  0 siblings, 1 reply; 3+ messages in thread
From: Laurent Guerby @ 1998-02-25  0:00 UTC (permalink / raw)



Andy Willey <willeya@dr-inc.com> writes:
> I am attempting to link Ada and FORTRAN modules together.  I am using
> GNAT Ada and the GNU FORTRAN compiler.  If anyone knows of any
> documentation or examples that specifically address the Ada-FORTRAN
> interface, please let me know.

   Have a look in cs.nyu.edu:/pub/gnat/contrib, there is a full
   binding for the LAPACK FORTRAN libraries, I think it has been tested out
   with g77. Ada 95/Fortran interface is very easy, you just need to know
   about the Convention pragma for arrays and look at Interfaces.FORTRAN
   for the types to use. No pointer mess here ;-).

   I know there are some quite active people doing Ada/FORTRAN things,
   may be they don't read comp.lang.ada anymore?

> Thanks -- Andy
> willeya@dr-inc.com

-- 
Laurent Guerby <guerby@gnat.com>, Team Ada, Linux/GNU addict
   "Use the Source, Luke. The Source will be with you, always (GPL)."




^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~1998-02-25  0:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-02-24  0:00 Ada-FORTRAN Interfacing Andy Willey
1998-02-25  0:00 ` Laurent Guerby
1998-02-25  0:00   ` Ada-FORTRAN Interfacing [longish -- source excerpts] John M. Mills

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox