How To Call The Imsl Fortran Libraries From C by Jangwon Kim Linda M. Robertson Visual Numerics, Inc. IMSL Technical Report Series No. 8902
How To Call The Imsl Fortran Libraries From C by Jangwon Kim Linda M. Robertson Visual Numerics, Inc. IMSL Technical Report Series No. 8902
CONTACTS
Visual Numerics, Inc.
Sales Division
1300 W. Sam Houston Pkwy, Suite 150
Houston, Texas 77042, USA.
Trademark Acknowledgments
All terms mentioned in this report that are known to be trademarks or service marks are listed
below. Visual Numerics cannot attest to the accuracy of this information. Use of a term in this
report should not be regarded as affecting the validity of any trademark or service mark.
Jangwon Kim
Linda M. Robertson
Visual Numerics, Inc.
Abstract
This report discusses how to call the IMSL Fortran Numerical Libraries from a C
program. To use C with the IMSL Fortran Libraries, the C and Fortran compilers must
share the same object file format. Interfacing between C and Fortran is dependent on the
operating system, and on the compatibility of the compilers and runtime libraries.
This report begins with a discussion on how to overcome the syntax differences between
Fortran and C that are common to all the environments tested, followed by a discussion
on machine and system dependent differences including compiling and linking
procedures. It also provides a complete example for each environment tested.
2
Introduction
This report describes how to call the IMSL Fortran 90 MP Library from a C program. To
use C with the IMSL Fortran library, the C and Fortran compilers must share the same
object file format. If the C and Fortran compilers do not share the same object file format,
the programs will not link properly. There are many environments for which the IMSL
Libraries are available, but we have limited the discussion of our report to the following
environments.
HP UX 10.01
Cray T3E
The first section of this report discusses some general differences between C and Fortran.
Sections 2 through 5 discuss machine and system dependent differences between C and
Fortran. The environments tested in this report have been categorized into four groups.
Several unix operating systems are discussed in the first group, the CRAY UNICOS
environment is discussed in the second group, VMS is discussed in the third group, and
PC Windows in the fourth. This classification is based on the operating system, C and
Fortran compilers, and the runtime libraries. For each group, we discuss how to pass a
character string argument, how to pass a function as an argument, and how to compile a C
main program and link it with the IMSL Fortran Libraries. At the end of each group, a
complete listing of a C program that calls the IMSL linear solver, LSLRG, is provided.
This example covers most of the topics discussed in this report.
Section 6, "Other Environments," provides some suggestions for calling the IMSL Fortran
Libraries from C in environments not discussed in this report.
3
1. Syntax Differences Between C and Fortran
Programs that mix C and Fortran can be linked provided the syntax is understood by both
languages. If the syntax is not understood by both languages, the differences can usually
be overcome with some modifications to the program. This section discusses some
general syntax differences between C and Fortran and how to overcome these differences
when writing C programs that call the IMSL Fortran Libraries. In particular, data types,
data storage, and the argument passing mechanism are discussed.
The length of the data type is environment specific and should be considered when
declaring variables. C and Fortran declarations are related as follows:
C Fortran
char CHARACTER
short int INTEGER*2
long int INTEGER*4
float REAL*4
double REAL*8
The IMSL Fortran 90 Library routines use 32-bit integers (or larger) and thus, for C
compilers that specify the size of int as 16-bits, integers must be declared using long int.
• complex data
Complex and double complex data types are not defined in C. However, they are
frequently used in the IMSL Fortran 90 Library. To get around this problem, an
equivalent structure (at least for all environments in this report) can easily be defined as
follows:
4
1.2 Argument Passing Mechanism
Since Fortran receives an argument as its address (call by reference), the user's C program
should not pass the value of an argument (call by value). For character strings in the VMS
environment, another type, call by description, is used. Below, the argument passing
mechanism is explained for the different data storage types such as scalars, arrays, (double)
complex types, character strings, and function arguments.
A scalar variable should be passed by its address; therefore, use the prefix, &, unless it is
already declared as an address.
A constant should not be passed to a Fortran subroutine by value. Use its address instead. For
example, in order to pass 1 (one) in the Sun environment, use:
forsub_ ( . . ., &one, . . . );
The name of an array in C is a pointer to the first element of the array. Therefore, the prefix,
&, is not needed and the name itself is passed to the Fortran subroutine, unless a subset of the
array is to be passed.
For a two (or higher) dimensional array, Fortran is column major while C is row major.
Therefore, a two-dimensional array variable must be transposed before it is passed to a
Fortran subroutine. The following example transposes a two-dimensional array using the
IMSL routine, TRNRR, in the Sun environment.
5
double a[2] [3] = {11., 12., 13.,
21., 22., 23.};
main ()
{
Two-dimensional arrays can also be passed by using the transpose option if it exists for the
IMSL routine.
Another method of passing a two-dimensional array is to simply declare the transpose of the
two-dimensional array in the C code. For example, matrix a in the previous example could be
declared as follows:
Complex and double complex data types can be declared using the typedef statement
discussed earlier. The following example repeats the definition of a complex data type and
passes z = 1 + 2i to a Fortran subroutine. (This example is for the UNIX environment.)
main ()
{
complex z;
z.r = 1.;
z.i = 2.;
forsub_ (...,&z, ...);
}
6
A double complex data type can be defined and used analogously to a complex data type if
the Fortran compiler allows DOUBLE COMPLEX data type.
When a character string variable is passed from C to Fortran, it must be passed with
information about its length in addition to other attributes of the string. In C, a character
string variable (not a character variable) is terminated with the null character, \0. However, in
Fortran, the length of a character string is stated explicitly. Since the method for passing a
character string is system dependent, this is discussed in each environment section of this
report.
7
2. Unix Platforms
The topics discussed in this section have been tested with the IMSL Fortran 90 MP library
version 4.01, using the following environments:
Sun Solaris Release 2.5 with the Sun Workshop 5.0 compilers
Compaq Tru64 Unix Version 5.0 with Compaq C compiler version 6.1-019 and Compaq
Fortran version 5.3-915.
IBM RS/6000 AIX Version 4.1.2 with IBM C 3.6.6 and XL Fortran version 6.1.
Red Hat Linux 6.1 with GNU C egcs-2.91.66 and Portland Group pgf90 3.1-2
SGI 64 bit IRIX 6.5 with SGI Mipspro C and Fortran 90 version 7.2
The UNIX operating system is case sensitive by nature. Since the IMSL Fortran Libraries
were developed in lowercase for the environments specified in this section, all IMSL symbols
and identifiers, such as names of IMSL subroutines and functions, and common block
identifiers, should be in lowercase.
Also, on Solaris, Compaq Unix, AIX, SGI, and linux, the object file format requires a trailing
underscore (_) at the end of the identifiers. For example, the IMSL routine, DTRNRR is written
as dtrnrr_. The underscore is not required on the HP. All examples in this section are shown
for a Solaris system.
For HP systems, the examples would be identical to those shown except that the function calls
do not have an underscore appended as the last character of the function name.
When passing character string arguments in the environments in this section, explicitly
provide the lengths of the strings as additional arguments beyond the last argument of the
Fortran subprogram; otherwise, the length is hidden to Fortran. The following example
transposes a two dimensional array and prints the result. Note that lstr is provided as the
length of char title, which is ten characters long, even though it does not show up in IMSL
subroutines.
/*
8
* This example transposes a two dimensional matrix
* and prints it out.
*/
double a[2] [3] = {11., 12., 13.,
21., 22., 23.};
char title[] = ''2x3 matrix'';
main ()
{
extern void dtrnrr_(), dwrrrn_(); /* external subroutines */
long int nra=3, nca=2, lda=3; /* matrix a is nra by nca */
long int nrb=2, ncb=3, ldb=2; /* matrix b is nrb by ncb */
long int itring=0, lstr=10; /* triangle option and title length */
double b[3][2];
2x3 matrix
1 2 3
1 11 12 13
2 21 22 23
For the environments in this section, a C function can simply be passed to a Fortran
subroutine as an argument. The following example shows how to pass a function to IMSL
routine DQDNG. Note that myfunc references x as a pointer because Fortran will invoke
myfunc and pass the address of x.
/*
* This example shows how to integrate a user supplied function,
* myfunc, at the given interval [0,2].
*/
#include <stdio.h>
#include <math.h>
9
/*
* myfunc calculates and returns *x * exp(*x). x is a pointer
* since Fortran calls myfunc and passes the address of x.
*/
main ()
{
extern void dqdng_();
double exp(), fabs(), myfunc();
double lower=0.e0, upper=2.e0, errabs=0.e0, errrel=1.e-7;
double result, errest, exact;
10
The example in Section 2.4 was successfully compiled and linked with version 4.01 of the
IMSL Fortran 90 library, using the UNIX command cc, as shown for the following platforms:
cc -o main main.c $LINK_F90 –lfui –lfai –lfai2 –lfsumai –lfprodai –lfminlai –lfmaxlai \
–lfminvai –lfmaxvai –lfsu -lsunmath -lm
• IBM RS/6000 AIX 4.3 with IBM C 3.6.6.0 and XL Fortran 6.1.0.0
• Red Hat Linux 6.1 with GNU C egcs-2.91.66 and Portland Group pgf90 3.1-2
• SGI 64 bit IRIX 6.5 with SGI Mipspro C and Fortran 90 version 7.2
LINK_F90 and F90FLAGS are environment variables set by the cttsetup.csh shell script,
which is supplied with IMSL Fortran 90 MP Library version 4.01.
2.4 Example
/*
* This example solves a linear system of 100 by 100 using
* the IMSL routine dlslrg_.
*/
#include <stdio.h>
#include <math.h>
11
#include <string.h>
main ()
{
int i, nerr;
long int n=MAXN, nn=MAXN*MAXN, lda=MAXN;
long int ipath=2, seed=123457;
double ermax=1.e-12;
double a[MAXN][MAXN], b[MAXN], x[MAXN], ans[MAXN];
12
The output from Solaris is:
13
3. Cray
The Cray UNICOS environment has been tested using the CRAY T3E computer system
running the Cray operating system UNICOSMK Revision 2.0.0.42 with Revision 6.0.1.3 of
the Cray C compiler, Revision 3.0.1.2 of the Cray CF90 Fortran compiler, and version 3.0 of
the IMSL Fortran 90 MP Library. Since double in Cray C is 64-bits long by default, DOUBLE
PRECISION in Cray Fortran (128 bits) has no matching data type in Cray C. Therefore, the
single precision version of the IMSL Fortran Libraries is demonstrated in conjunction with
double precision of Cray C.
As in other UNIX systems, this environment is case sensitive. The IMSL Fortran Libraries are
written in uppercase for Fortran and compiled as they are. Therefore, the IMSL symbols and
identifiers, such as names of IMSL subroutines and functions, and common block identifiers,
should be in uppercase. Unlike the other UNIX systems however, the object file format does
not append an underscore (_) at the end of those identifiers (e.g., TRNRR should be typed as it
is).
The Cray C character pointer is incompatible with the Cray Fortran character type. Therefore,
character values should not be passed between Cray C and Cray Fortran routines (Cray
Research 1986). Instead, use the macro _cptofcp, which is defined in fortran.h, to describe the
structure of a C character string pointer, and give its length, so that it can be understood by
Fortran. The following example transposes the two-dimensional matrix, a, and prints the
result with a title.
/*
This example transposes a two dimensional matrix
and prints it out.
*/
#include <fortran.h>
#include <string. h>
2x3 matrix
1 2 3
1 11 12 13
2 21 22 23
#include <stdio.h>
#include <math.h>
#include <fortran.h>
/*
* myfunc calculates and returns *x * exp(*x). x is a pointer
* since Fortran calls myfunc and passes x as an address.
*/
double myfunc (x)
double *x;
{
double exp ();
return (*x * exp (*x));
}
15
main ()
{
cc -c main.c $LINK_F90
where main.c is a user written C program and LINK_F90 is an environment variable set by
the iptsetup.csh shell script, which is supplied with IMSL Fortran 90 Libraries version 3.0.
16
3.4 Example
/*
This example solves a linear system of 100 by 100
using the IMSL routine LSLRG.
*/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <fortran.h>
main()
{
int i, nerr;
long int n=MAXN, nn=MAXN*MAXN, lda=MAXN;
long int ipath=2, seed=123457;
double ermax=l.e-7;
double a[MAXN][MAXN], b[MAXN], x[MAXN], ans[MAXN];
18
4. OpenVMS
The OpenVMS environment has been tested using OpenVMS Version 7.2 with version 6.0 of
the Digital C compiler, version 7.2 of the Compaq Fortran compiler, and version 4.01 of the
IMSL Fortran 90 Library. Although the C language is inherently case sensitive, VMS allows
you to mix the cases in the common language environment (interlanguage environment). For
example, the name of the IMSL routine, DTRNRR, can be interchanged with dtrnrr.
VMS Fortran passes character string variables as descriptors (pass by descriptor); therefore, C
must pass character strings to Fortran only after inserting them in a descriptor structure. VMS
C provides a macro for this purpose called $DESCRIPTOR, which is defined in the #include
descrip header file (Digital Equipment Corporation 1987). The following example shows how
to use this macro to pass a character string (title) to the IMSL routine, DWRRRN, and print
the matrix.
/*
This example transposes a two-dimensional matrix
and prints it out.
*/
#include <string.h>
#include descrip
main ( )
1 2 3
1 11 12 13
2 21 22 23
Note that the header file, descrip, is not surrounded with < and > and the structure identifier,
name_desc, is declared, not defined by the macro.
#include <stdio.h>
#include <math.h>
/*
* myfunc calculates and returns *x * exp (*x). x is a pointer
* since Fortran calls myfunc and passes an address of x.
*/
main()
{
extern void dqdng ();
double exp(), fabs(), myfunc();
double lower=0.e0, upper=2.e0, errabs=0.e0, errrel=l.e-7;
double result, errest, exact;
/* IMSL dqdng
integrates a smooth function using a
nonadaptive rule. */
dqdng (myfunc, &lower, &upper, &errabs, &errrel, &result, &errest);
4.4 Example
/* This example solves a linear system of 100 by 100
* using the IMSL routine dlslrg.
*/
#include <stdio.h>
#include <math.h>
#include <string.h>
main ()
{
extern void dlslrg(), drnun(), dmurrv(), rnset();
int i, nerr;
long int n=MAXN, nn=MAXN*MAXN, lda=MAXN;
long int ipath=2, seed=123457;
double ermax=1.e-12;
double a[MAXN][MAXN], b[MAXN], x[MAXN], ans[MAXN];
22
5. WINDOWS
The Windows environment has been tested using Windows NT 4.0 and Windows 95. The
compilers used are Microsoft Visual C++ 6.0 and Compaq Visual Fortran 6.5. Version 4.01 of
the IMSL Fortran 90 MP Library was used.
Microsoft Visual C++ and Compaq Fortran handle stack bookkeeping for a module
differently. Microsoft C, for example, pushes the first argument of the argument list to the end
(first-in-first-out), which allows the implementation of one of the C features, the variable
length argument list. Compaq Fortran, meanwhile, uses the first-in-last-out scheme.
extern void __stdcall IVPRK (long *, long *, void * , float *, float *, float *, float *, float *);
Header files containing these declarations are provided with F90 4.01. If these header files are
included in the program, the programmer does not have to explicitly provide the “extern”
statement for each subroutine used. For example:
#include <maths.h> /* include this header file for all single precision subroutines used*/
#include <mathd.h> /* include this header file for all double precision subroutines used*/
Note also that the F90 library names must be referenced in upper case.
23
5.1 Passing a Character String Argument
To pass variable-length strings to Compaq Fortran from Microsoft Visual C++, you must pass
both the string and the length of the string to the Fortran subroutine as separate arguments.
The following example illustrates how to pass a character string, "2x3 matrix", to the IMSL routine.
/*
* This example transposes a two-dimensional matrix
* and prints it out.
*/
#include <mathd.h>
double a[2][3] = {11., 12., 13.,
21., 22., 23.};
char title[] = "2x3 matrix";
unsigned int lstr=10;
main ()
2x3 matrix
1 2 3
1 11.00 12.00 13.00
2 21.00 22.00 23.00
24
5.2 Passing a Function as an Argument
Microsoft Visual C++ and Compaq Fortran use different methods for passing function
arguments. Therefore, it is necessary to declare the C function with __stdcall so that it is
recognized by Fortran.
The following example uses the IMSL routine, QDNG, which integrates a smooth
function supplied by the user (myfunc is a function that the user supplies to be
integrated).
#include <stdio.h>
# include <math.h>
#include <mathd.h>
/*
* myfunc calculates and returns *x * exp(*x). x is a pointer
* since Fortran calls myfunc and passes an address of x.
*/
double __stdcall myfunc (x)
double *x;
{
double exp ();
return (*x * exp (*x));
}
main ()
{
double exp(), fabs();
double lower=0.e0, upper=2.e0, errabs=0.e0, errrel=1.e-7;
double result, errest, exact;
25
Exact answer = 8.38906
IMSL dqdng = 8.38906
Error = 1.77636e-015
This is the DOS command used to compile and link a program with the single precision math
library which is bundled with Compaq Visual Fortran 6.5:
Libraries dfor.lib and dfconsol.lib are supplied with Compaq Visual Fortran.
26
5.4 Example
/*
* This example solves a linear system of l00x100 by using IMSL dlslrg.
*/
#include <mathd.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
main ( )
{
int i, nerr;
long int n=MAXN, nn=MAXN*MAXN, lda=MAXN;
long int ipath=2, seed=123457;
doubleermax=1.e-12;
double a[MAXN] [MAXN], b[MAXN], x[MAXN], ans[MAXN];
28
6. Other Environments
This section discusses how to call the IMSL Fortran Libraries from C in environments not
discussed in the previous sections of this report.
The "Introduction" section of this report can be applied to most computing environments with
the exception of the following topics.
• case sensitivity
Although C is case sensitive for grammar, the operating system or the library manager may
not be case sensitive. If the external references of the IMSL Fortran Libraries are case
sensitive, then try switching case.
• naming conventions
As seen in previous sections, many UNIX systems append a trailing underscore ( _) at the end
of the routine referenced in order to share the same object file format. Some UNIX systems
and other operating systems may or may not have this requirement.
Even in an integer data type, the length of a data type in one language may not be the same as
in another. Therefore, short int and long int are preferred to int to ensure the data types match
(unless different optimizers are used that require a machine dependent data storage type).
When using INTEGER in Fortran, it is usually safer to use long int in C, rather than int.
Many C compilers handle character strings differently than Fortran compilers. C reads a
character string until it reaches the null character, \0, while Fortran generally specifies the
length of the character string in advance. In C, a structure is usually used to hold the
information of a character string passed by descriptor.
29
The user should compile C and Fortran modules separately before linking. When linking
object files and libraries, both C and Fortran runtime libraries must be explicitly specified
along with other necessary libraries, since the default libraries may or may not be linked.
For additional information on mixing C and Fortran, it is recommended that you refer to the C
and Fortran manuals provided with your operating system for a discussion on mixing
languages.
30
References
Cray Research, Inc. (1986), Cray C Reference Manual, Publication SR2024, Revision C,
Cray Research, Mendota Heights, Minnesota.
Kernighan, Brian W. and Dennis M. Ritchie (1978), The C Programming Language, Prentice
Hall, Inc., Englewood Cliffs, New Jersey.
31