Loading in 5 sec....

Mixed Language Programming on SeaborgPowerPoint Presentation

Mixed Language Programming on Seaborg

- By
**Jimmy** - Follow User

- 520 Views
- Updated On :

Download Presentation
## PowerPoint Slideshow about '' - Jimmy

**An Image/Link below is provided (as is) to download presentation**

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript

Overview

- Matching variable types
- Mixing C and FORTRAN
- Mixing C++ and FORTRAN
- Mixing C and FORTRAN modules
- Character arguments
- Mixed-case names
- Other issues
- Mixed-language library use
- Further References

2

Calling C from FORTRAN

- Calling by reference expected by FORTRAN
- Lowercase C routine name easiest (since Fortran by default not case-sensitive)
- No change in routine name
- –qextname option to xlf and –brename option to ld provide other options

4

!

PROGRAM f_calls_c

IMPLICIT NONE

REAL :: p1_x, p1_y, p2_x, p2_y

EXTERNAL calc_dist

p1_x = 0.0

p1_y = 0.0

p2_x = 3.0

p2_y = 4.0

CALL calc_dist(p1_x,p1_y,p2_x,p2_y)

END PROGRAM f_calls_c

/* FILENAME: calc_c.c

*/

#include <math.h>

void calc_dist(float *x1, float *y1, float *x2, float *y2)

{

float dxsq, dysq, distance;

dxsq = (*x2-*x1)*(*x2-*x1);

dysq = (*y2-*y1)*(*y2-*y1);

distance = sqrt( dxsq + dysq );

printf("The distance between the points is %13.5e\n",

distance);

}

Calling C from FORTRAN (example)5

Calling C from FORTRAN (running)

> cc -c calc_c.c

> xlf90 -o f_calls_c f_main.f calc_c.o

** f_calls_c === End of Compilation 1 ===

1501-510 Compilation successful for file f_main.f.

> ./f_calls_c

The distance between the points is 5.00000e+00

6

Calling FORTRAN from C

- Again, calling by reference most straightforward
- Must specify –lxlf90 –lm in cc command
- Or use xlf90 to load

7

Shows how to call a FORTRAN routine from C

*/

extern void calc_dist(float*, float*, float*, float*);

void main()

{

float p1_x,p1_y,p2_x,p2_y;

p1_x = 0.0;

p1_y = 0.0;

p2_x = 3.0;

p2_y = 4.0;

calc_dist(&p1_x,&p1_y,&p2_x,&p2_y);

}

! FILENAME: calc_f.f

!

SUBROUTINE calc_dist(x1,y1,x2,y2)

IMPLICIT NONE

REAL :: x1,y1,x2,y2

REAL :: distance

distance = SQRT( (x2-x1)**2 + (y2-y1)**2 )

WRITE(6,1) distance

1 FORMAT("The distance between the points is ", 1pe13.5)

END SUBROUTINE calc_dist

Calling FORTRAN from C (example)8

Calling FORTRAN from C (running)

> xlf90 -c calc_f.f

** calc_dist === End of Compilation 1 ===

1501-510 Compilation successful for file calc_f.f.

> cc -o c_calls_f c_main.c calc_f.o -lxlf90 -lm

> ./c_calls_f

The distance between the points is 5.00000E+00

9

Calling C++ from FORTRAN

- Must have C wrapper function
- C++ compiler mangles routine names

- C wrapper name handled just like C
- Also any C++ that is “just like” C

- xlCcommand must be used to link

10

This is the C++ routine.

*/

#include <iostream.h>

#include <math.h>

template<class T> class calc {

public:

calc() {cout <<"Inside C++ constructor"<<endl;}

~calc() {cout <<"Inside C++ destructor"<<endl;}

void calc_dist(T *x1, T *y1, T *x2, T *y2)

{

T dxsq, dysq, distance;

dxsq = (*x2-*x1)*(*x2-*x1);

dysq = (*y2-*y1)*(*y2-*y1);

distance = sqrt( dxsq + dysq );

cout <<"The distance between the points is "

<<distance<<" \n"<<endl;

}

};

Calling C++ from FORTRAN (C++ code)11

Calling C++ from FORTRAN (C wrapper)

/* Filename: calc_cwrapper.C */

#include <stdio.h>

#include "calc_c++.h"

extern "C" void calc_dist(float *x,float *y,float *X,float *Y);

void calc_dist(float *x,float *y,float *X,float *Y) {

printf("Inside C function, creating C++ object\n");

calc<float>* c=new calc<float>();

c->calc_dist(x,y,X,Y);

printf("Back in C function, will delete C++ object\n");

delete c;

}

12

Calling C++ from FORTRAN (running)

> xlf90 -c f_main.f

** f_calls_c === End of Compilation 1 ===

1501-510 Compilation successful for file f_main.f.

> xlC -c calc_cwrapper.C

> xlC -o f_calls_c++ calc_cwrapper.o f_main.o -lm -lxlf90

> ./f_calls_c++

Inside C function, creating C++ object

Inside C++ constructor

The distance between the points is 5

Back in C function, will delete C++ object

Inside C++ destructor

13

Calling FORTRAN from C++

- Can simply declare FORTRAN subroutine like C:
extern "C" void fortran_routine_name

- Or with FORTRAN function:
extern "C" return_typefortran_routine_name

14

Calling F90 module routines from C

- Refer to FORTRAN routine as __modulename_MOD_routinename
- There is apparently a way for C to read prototype info out of .mod files

15

Calling F90 module routines from C (module code)

! FILENAME: calc_mod_f.f

!

MODULE CALCULATION

CONTAINS

SUBROUTINE CALC_DIST(x1,y1,x2,y2)

IMPLICIT NONE

REAL :: x1,y1,x2,y2

REAL :: distance

distance = SQRT( (x2-x1)**2 + (y2-y1)**2 )

WRITE(6,1) distance

1 FORMAT("The distance between the points is ", 1pe13.5)

END SUBROUTINE CALC_DIST

END MODULE CALCULATION

16

Calling F90 module routines from C (C code)

/* FILENAME: c_main_mod.c

Shows how to call a FORTRAN routine from C

In this case the FORTRAN routine, named CALC_DIST,

is in the FORTRAN module named calculation

*/

extern void __calculation_MOD_calc_dist(float *, float *,

float *, float *);

void main()

{

float p1_x,p1_y,p2_x,p2_y;

p1_x = 0.0;

p1_y = 0.0;

p2_x = 3.0;

p2_y = 4.0;

__calculation_MOD_calc_dist(&p1_x,&p1_y,&p2_x,&p2_y);

}

17

Calling F90 module routines from C (running)

> xlf90 -c calc_mod_f.f

** calculation === End of Compilation 1 ===

1501-510 Compilation successful for file calc_mod_f.f.

> cc -o c_calls_f_mod c_main_mod.c calc_mod_f.o -lxlf90 -lm

> ./c_calls_f_mod

The distance between the points is 5.00000E+00

18

Handling character arguments

- FORTRAN passes (by value) an extra argument with the length of the string
- C assumes strings are a null-terminated sequence of bytes
- Can process this argument at the C end
- Can null-terminate strings at the FORTRAN end
- CALL TAKE_CHARS(b // CHAR(0))
- may also want %REF

19

Mixed case names

- -U option in xlf
- All functions, variables, and names become case-sensitive

- @PROCESS MIXED compiler directive
- on a specific compiler unit

20

Design Issues

- Porting an existing code
- make and version control recommended

- Designing a new code
- FORTRAN for numbers
- C for strings
- (or avoid entirely)

- Maintaining portability
- Wrappers/shims useful
- make (but try to avoid “code schism”)
- Maybe -qextname

21

Miscellaneous Issues

- Compiler options are frequent pitfall (or helper)
- including: -qalign, -q32, -q64, -qautodbl, -qintsize, -qnullterm, -qrealsize

- Name conflicts can occur (e.g., main)
- -qextname can help (but with added complexity…)
- Ditto -brename

- %VAL and %REF built-in functions

22

Miscellaneous Issues (cont’d)

- -qextchk can help find errors; ditto –qsigtrap, xl__trbk and -g
- “Funny” FORTRAN function return values not supported
- pointer, array, or character of nonconstant length
- (not that I can make this work even with simple examples)

- pointer, array, or character of nonconstant length
- Can share data structures CFORTRAN
- Cross-language I/O: Just say no!

23

Cross-language library calls

- No particular tricks; as described above
- For C, function prototypes may be a challenge
- Can simply roll your own

- Load with xlf90 for FORTRAN libraries
- 64-bit or 32-bit uniformity; ditto thread-safe
- Column-major (FORTRAN) vs. row-major (C) array order

24

!

! Gives an example of wrapping a

! Fortran function into a

! subroutine that can be called

! by even the most incompetent

! cross-language programmer, viz.

! - Mark Durst

subroutine wrap_s01baf(x,y,i)

double precision :: x, y

integer :: i

y = s01baf(x,i)

end subroutine wrap_s01baf

/* FILENAME: c_nag.c

Shows how to call a FORTRAN wrapper

for a NAG routine from C

*/

#include <stdio.h>

#include <math.h>

extern void wrap_s01baf(double*,double*, int*);

main(int argc, char *argv[]){

double x, y;

int ifail;

x =1.0;

y = 0.0;

wrap_s01baf(&x,&y, &ifail);

printf("%f\n",y);

}

Cross-language library call(example)25

Cross-language library call (running)

> xlf90 -c wrap_s01baf.f

** wrap_s01baf === End of Compilation 1 ===

1501-510 Compilation successful for file wrap_s01baf.f.

> cc -c c_nag.c

> module load nag

> xlf90 -o c_nag c_nag.o wrap_s01baf.o $NAG

> ./c_nag

0.693147

26

Further References

- Examples and most content are from
http://www.nersc.gov/nusers/resources/software/ibm/c_and_f.php

- More details in XL Fortran User’s Guide, Ch. 10
http://www.nersc.gov/vendor_docs/ibm/xlf/html

- HPC Users Seaborg Software Compilers xlf vendor User’s Guide

27

Download Presentation

Connecting to Server..