|
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
Slide 1
1 Title Page Mix Fortran77 & C - Title Page
R.K. Owen,Ph.D.
KooZ Software
email:rk@owen.sj.ca.us
email:rkowen@nersc.gov
Slide 2
2 Fortran & C Mix Fortran77 & C - Fortran & C
- Fortran :
- Passes by address
- Routine names are case insensitive
- Arrays are column-major
- Strings contain length
- C :
- Passes by value
- Names are case sensitive
- Arrays are row-major
- ``Strings'' are null terminated
Slide 3
2.1 IBM SP2 Mix Fortran77 & C - IBM SP2 F77 & C
Fortran C size(bits) INTEGER*1signed char8 INTEGER*2short16 INTEGERint32 REALfloat32 DOUBLE PRECISIONdouble64 COMPLEX2 float struct64 DOUBLE COMPLEX2 double struct128 SUBROUTINE SUBR( )void subr( )FUNCTION FN( )float fn( )COMMON /CB/data(10)?
Slide 4
2.2 CRI C90 Mix Fortran77 & C - Cray F77 & C
Fortran C size(bits) INTEGERint46/64 cft77 -i64 cc -nofastmd INTEGERlong64 REALdoubleorfloat64 DOUBLE PRECISIONlong double128 COMPLEXfloat complex
ordouble complex128 SUBROUTINE SUBR( )void SUBR( )FUNCTION FN( )double FN( )COMMON /CB/data(10)struct common {
double data[10];
} CB;
Slide 5 Note Differences
2.2 Mix Fortran77 & C - F77 & C - more
- Cray Y-MP/J90/C90
- Fortran names are UPPERCASE
- C preprocess defines
_CRAY- Special C header to handle Fortran strings
- IBM SP2
- Fortran names are lowercase
- C preprocess defines
_AIX- Common blocks from C (?)
- No problem passing strings
- Typical Workstation
- Fortran names are generally lowercase and `
_' is appended- Usually no problem passing strings
Slide 6
2.3 Fortran to C Mix Fortran77 & C - F77 & C example
PROGRAM F2C C CHARACTER*32 NAME INTEGER AGE REAL TEMP C NAME = "Knut" C add null character at end for portable & safe handling by C NAME(LEN(NAME):LEN(NAME)) = CHAR(0) C note that LEN(NAME) = 32 in this case AGE = 4 TEMP = 98.6 CALL NAMEAGE(NAME, AGE, TEMP) END
#include <string.h> #ifdef _CRAY # include <fortran.h> # define nameage NAMEAGE #else # ifndef _AIX # define nameage nameage_ # endif # define _fcd char * # define _fcdtocp(a) (a) # define _fcdlen(a) strlen(a) #endif void nameage(_fcd name, int *age, float *temp) { char *cp; size_t len; cp = _fcdtocp(name); /* convert to C char* */ len = _fcdlen(name); /* strip trailing blanks */ while (cp[len-1] == ' ' || cp[len-1] == '\0') --len; printf("Hello %.*s, who is %d years old, " "has a temperature of %4.1f\n", len, cp, *age, *temp); }
- Cray - PVPs - UNICOS
cc -c f2cfn.ccf77 f2c.f f2cfn.o- (or substitute f90 for cf77)
- IBM - SP2 - AIX
xlc -c f2cfn.cxlf f2c.f f2cfn.o- SGI - IRIX
gcc -c f2cfn.cf77 f2c.f f2cfn.o- SUN - SunOS
gcc -c f2cfn.cf77 f2c.f f2cfn.o- PC - Linux
gcc -c f2cfn.cg77 f2c.f f2cfn.o
Slide 7
2.4 C to Fortran Mix Fortran77 & C - F77 & C example
#include <string.h> #ifdef _CRAY # include <fortran.h> # define nameage NAMEAGE #else # ifndef _AIX # define nameage nameage_ # endif # define _fcd char * # define _cptofcd(a,b) (a) # define _fcdlen(a) strlen(a) #endif void nameage(_fcd name, int *nlen, int *age, float *temp); int main() { char *name = "Knut"; _fcd fp; int nlen,age = 4; float temp = 98.6; nlen = strlen(name); fp = _cptofcd(name, nlen); /* convert to Fortran string */ nameage(fp, &nlen, &age, &temp); return 0; }
SUBROUTINE NAMEAGE(NAME, NLEN, AGE, TEMP) CHARACTER*(*) NAME INTEGER NLEN,AGE REAL TEMP C WRITE(6,1000) NAME(1:NLEN),AGE,TEMP 1000 FORMAT(1X,'Hello ',A,', who is ',I2, . ' years old, has a temperature of ', f4.1) RETURN END
To discover which libraries are necessary for Fortran modules, compile a short Fortran test program and add the-Voption (or equivalent) to get a verbose execution listing.
- Cray - PVPs - UNICOS
cf77 -c c2ffn.fcc -c c2f.ccf77 c2f.o c2ffn.o- (or substitute f90 for cf77)
- IBM - SP2 - AIX
xlf -c c2ffn.fcc c2f.c c2ffn.o -lxlf90 -lxlf -lm- SGI - IRIX
f77 -c c2ffn.fgcc c2f.c c2ffn.o -lF77 -lm -lU77 -lI77 -lisam -lmpc -lc- SUN - SunOS
f77 -c c2ffn.fgcc c2f.c c2ffn.o -L/usr/lang/SC0.0 -lF77 -lm -lc- PC - Linux
g77 -c c2ffn.fgcc -c c2f.cg77 c2f.o c2ffn.o