Vous êtes sur la page 1sur 19

A General Approach to

Creating FORTRAN Interface


for C++ Application Libraries
Yang Wang, R. Reddy, R. Gomez, Junwoo Lim, and S. Sanielevici
Pittsburgh Supercomputing Center, Carnegie Mellon University,
Pittsburgh, PA 15213

Jaideep Ray, James Sutherland, and Jackie Chen


Sandia National Laboratories, Livermore, CA 94550-0969
Outline
 Motivation

 FORTRAN/C inter-language calling convention

 Challenges

 Our approach to the solution

 Applications

 Conclusion
Motivation

Driver (C/C++)

Scientific/Engineering Applications
(FORTRAN 90/95)

Numerical Library Numerical Library Graphics Library


(C/C++) (FORTRAN 77/90) (C/C++)
FORTRAN/C Inter-language
Calling Convention
 Most FORTRAN compilers convert the name of its routines and
common blocks to low case letters and extend the name with
an underscore
• In C, put an underscore at the end of a FORTRAN routine
name in low case letters to call it from C.
• In C, declare the name of a routine in low case letters and
extend the name with an underscore to make the routine
callable from FORTRAN.
 FORTRAN passes arguments by reference
• For a variable name in a routine call from FORTRAN, the
corresponding C routine receives a pointer to that variable.
• When calling a FORTRAN routine, the C routine must
explicitly pass addresses (pointers) in the argument list.
FORTRAN/C Inter-language
Calling Convention - continued
 C routines expect that character strings are
delimited by the null character.
• From FORTRAN to C, the length of each character string is
passed as an implicit additional INTEGER (KIND=4) value,
following the explicit arguments.
• From C to FORTRAN, when a function returns a character
string, the address of the space to receive the result is
passed as the first implicit argument to the function, and
the length of the result space is passed as the second
implicit argument, preceding all explicit arguments.
 Arrays in FORTRAN are stored in a column-major
order, whereas in C they are stored in a row-major
order.
FORTRAN/C Inter-language
Calling Convention - example
FORTRAN calling C

FORTRAN 90 C

extern “C” {
SUBROUTINE example() void sum_(long *x, long
INTEGER, PARAMETER :: N=10 *n, long *y) {
INTEGER :: x(N), y *y = 0;
x(1:N) = 1 for (long i=0; i<*n;
CALL SUM(x,N,y) i++) {
PRINT *,’Sum of array ’, & *y += *(x+i);
’elements = ’,y }
END SUBROUTINE example }
}
FORTRAN 90: work1.f90 C++: Mesh.h
class Mesh {
SUBROUTINE work1()
public:
USE MeshModule, ONLY : &
void Mesh(long *,
initMesh,getGrid,deleteMesh
long *, long *,
INTEGER:: n1, n2, n3
double *);
REAL*8:: geometry(3,3)
void ~Mesh();
REAL*8, pointer:: grid(:,:,:)
double *getGrid()
... ... const;
READ(*,*)n1, n2, n3, & long getSizeX() const;
geometry(1:3,1:3) long getSizeY() const;
CALL initMesh(n1, n2, n3, & long getSizeZ() const;
geometry)
private:
grid => getGrid()
double *grid;
... ...
long nx, ny, nz;
CALL deleteMesh()
double geometry[9];
END SUBROUTINE work1
};
Challenges
For making a C++ numerical library usable by a
FORTRAN application, we need to know:
 How to construct and destruct a C++ object via
FORTRAN routine calls?

 How to access the public member functions of a


C++ object via FORTRAN routine calls?

 How to make a memory space of basic data type


allocated in C++ routine that is accessible by a
FORTRAN pointer?

 How to make a multi-dimensional FORTRAN


pointer an alias of a one dimensional array
allocated in C++ routine?
Possible Ways to Get Around

 The driver, in C++, calls the constructor and the


destructor.
• The life of the objects spans over the entire job
process

 “Wrap" the C++ member function with a C-style


function and calls the constructor and the destructor
in the “wrapper”.
• Frequent creation and destruction of an object can
be costly
Possible Ways to Get Around
- continue
 CNF library (www.starlink.rl.ac.uk/static_www/soft_further_CNF.html)
• C macros to hide the different ways that computers pass
information between subprograms
• C functions to handle the difference between FORTRAN and C
character strings, logical values, and pointers to dynamically
allocated memory

 Nonstandard FORTRAN pointers (CRAY, Compaq, etc.)


• Limited portability

 Babel (a Scientific Interface Definition Language


compiler)
• Tedious
• FORTRAN 90 support is still in testing

 FORTRAN 2003 (?)


Our Approach to the Solution
 Build a “wrapper” for the C++ library that allows us
to
• hide the implementation details of the numerical library
from the FORTRAN code;
• handle the request from FORTRAN calls to create and
destroy the objects defined in the C++ library;
• return FORTRAN pointer aliased to the memory allocated
in the C++ library;
• support function overloading.

 The “wrapper” is made of two components: a “C”


component and a FORTRAN 90 component
• Written in “standard” C++ and FORTRAN 90, together with
the conventional inter-language calling method.
• Changes to the application source code is minimal and can
be automated.
Our Approach to the Solution
- continue
 The “C” component
• Contains a pointer to the C++ object, which
needs to be created and destroyed via
FORTRAN calls, in its global space.
• Provides a “C” interface between the
FORTRAN 90 component and the public
functions defined in the C++ library.
• Calls the alias function provided by the
FORTRAN 90 component to make the
FORTRAN pointer aliased to the memory
allocated dynamically in the C++ library.
Our Approach to the Solution
- continue
 The FORTRAN 90 component
• Contains a FORTRAN 90 module that provides a set of
public functions for the FORTRAN application to call.
• Each of these public functions corresponds to a function
implemented in the C++ library, and it calls the
corresponding function via the C++ component.
• The FORTRAN 90 module also holds one- or multi-
dimensional FORTRAN pointers in its global space.
• Provides an alias function for the C++ component to call
that makes the one- or multi- dimensional FORTRAN
pointer aliased to the memory space allocated
dynamically in the C++ library.
Outside FORTRAN 90 “C” Allocated
World Component Component Memory

Pointer :: *p_obj
FORTRAN Application

p(:,:,:)

C++
FORTRAN Object in
Module the Library

Alias
Function

Alias
Function
MeshModule.f90
PUBLIC : initMesh, getGrid, deleteMesh, aliasGrid
PRIVATE : INTEGER :: nx, ny, nz
PRIVATE : REAL*8, pointer :: grid(:,:,:)
CONTAINS
SUBROUTINE initMesh(L,M,N,g) SUBROUTINE aliasGrid(n1, &
INTEGER :: L,M,N n2,n3,a)
REAL*8 :: g(9)
CALL c_initMesh(L,M,N,g) INTEGER :: n1,n2,n3
END SUBROUTINE initMesh REAL*8, TARGET :: &
a(n1,n2,n3)
SUBROUTINE deleteMesh()
CALL c_deleteMesh() nx = n1
END SUBROUTINE deleteMesh ny = n2
nz = n3
FUNCTION getGrid() result(p)
REAL*8, POINTER:: p(:,:,:) grid => a(1:nx,1:ny,1:nz)
CALL c_getGrid()
p => grid(1:nx,1:ny,1:nz) END SUBROUTINE aliasGrid
END FUNCTION getGrid
aliasArray.f90
SUBROUTINE aliasArray(nx, ny, nz, a)
USE MeshModule, only: aliasGrid

INTEGER, INTENT(IN) :: nx,ny,nz


REAL*8, INTENT(IN) :: a(nx*ny*nz)

CALL aliasGrid(nx, ny, nz, a)

END SUBROUTINE aliasArray


Applications
 Building a FORTRAN 90 interface for GrACE
• GrACE is a C++ library for grid generation, load balance
maintenance, grid function update, and adaptive mesh
refinement
• S3D code, written in FORTRAN 90, is a 3D direct
numerical simulation package for flow-combustion
interactions
 Building CCA component for FORTRAN modules,
subroutines, and/or functions
• CCA (Common Component Architecture) components
are the basic units of software that can be combined to
form applications, and ports are the abstract interfaces
of the components.
• Instances of components are created and managed
within a framework, which also provides basic services
for component interoperability and communication.
Conclusion
 The procedure to build a FORTRAN interface for
a C++ library:
• A FORTRAN 90 module
• A FORTRAN alias routine
• A “C” wrapper to mediate between the FORTRAN 90
module and the C++ library
 Advantages:
• Portable
• Low overhead cost
• The need for changing the legacy code is minimal
 Extension
• The same technique can be applied to build a C++
interface for FORTRAN 90 libraries.
Acknowledgement

The work is supported in part by U.S.


Department of Energy, “Terascale
High-Fidelity Simulations of Turbulent
Combustion with Chemistry” project
under SciDAC program, Contract No.
DE-FC02-01ER25512

Vous aimerez peut-être aussi