Totalview® for HPC Reference Guide : PART I CLI Commands : Chapter 6 Creating Type Transformations : C++View : Fortran
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.
Figure 10 – Using C++ View with Fortran, diving on the Fortran pointer data
if
To see the data transformed more clearly, expand the type information (downward arrow with the + sign) and change the language to C or C++.
 
Figure 11 – Using C++ View with Fortran, changing language to 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.
 
Figure 12 – Using C++ View with Fortran, transform the type