Fortran
Fortran variables don't readily lend themselves to transformation by C++View, but in some cases, such as when using a common block with Cray pointer variables, it is possible to set up a corresponding C structure and then use that type to push the transformation.
Example
Consider this test case using Cray pointers in a common block, including three parts:
The Fortran code
A common block defined in an include file
The C code containing the C++View code
The Fortran Code
Here, the Fortran code sets up a common block with a few variables and then assigns them some values.
program pointerp
call stuff
end
subroutine stuff
include 'foop.cmn'
foo = 42
ix = 11
iy = 12
iz = 13
call doit(ix)
call readit
return
end
subroutine doit(ix_x)
include 'foop.cmn'
ipxp = malloc(8*ix_x*foo)
ipyp = malloc(8*iy*iz)
xp = 3
yp = 5
return
end
subroutine readit
include 'foop.cmn'
xp = 4
return
end
The include File
The Fortran include file foop.cmn sets up a common block foo1 that corresponds to the C structure extern foo1_, both in bold below.
The include file, foop.cmn:
integer :: foo, ix, iy, iz
real(kind=8) :: xp, yp
pointer (ipxp, xp(foo,ix))
pointer (ipyp, yp(iy,iz))
common /foo1/ ix, iy, iz, foo, ipxp, ipyp
The C Code
The C code fortranTV.c defines structure extern foo1_, aligned to the Fortran common block foo1. Then, in the TV_ttf_display_type routine for the struct foo, the calls to TV_ttf_add_row follow the layout of the data in the common block, allowing us to view the data as we want to see it
The C code, fortranTV.c:
#include <stdio.h>
#include "tv_data_display.h"
#ifdef __cplusplus
extern "C" {
#endif
extern struct foo { int x ; } foo1_ ;
#ifdef __cplusplus
}
#endif
// Routine data display declaration
int TV_ttf_display_type(const struct foo *parameter)
{
// Assign 'data' to the start of the common block
int *data = (int *)parameter ;
// Pick up the Cray pointer
double **ptr = (double **) &data[4] ;
char typeName[64] ;
TV_ttf_add_row("ix", "int", &data[0]) ;
TV_ttf_add_row("iy", "int", &data[1]) ;
TV_ttf_add_row("iz", "int", &data[2]) ;
TV_ttf_add_row("foo", "int", &data[3]) ;
sprintf(typeName, "double[%d]", data[0]*data[3]) ;
TV_ttf_add_row("ipxp", typeName, ptr[0]) ;
sprintf(typeName, "double[%d]", data[1]*data[2]) ;
TV_ttf_add_row("ipyp", typeName, ptr[1]) ;
return TV_ttf_format_ok ;
}
Compiling and Linking
First compile the TotalView
tv_data_display.c routine, as described in
Compiling and linking tv_data_display.c.
Build the program and the C program to add in the C++View transform:
ifort -g -c pointerp.f
ifort -g -c fortranTV.c -I$TVINCLUDE
Finally, link the program:
ifort -g -o crayptr pointerp.o tv_data_display.o fortranTV.o
Debugging
When you debug, set a breakpoint on the return statement on line 20, in subroutine doit. Run to the breakpoint and then dive on the common block foo1.
To see the data transformed more clearly, expand the type information (downward arrow with the + sign) and change the language to C or C++.
Then change the type from
$void to
foo,
Figure 12.
Note that, while the original display of the common block shows the Cray pointers as integers (because a Cray pointer is actually an integer that holds only a memory address), the final, transformed display shows the data referenced by the pointers, or the arrays of doubles.