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.
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
subroutine stuff
include 'foop.cmn'
foo = 42
ix = 11
iy = 12
iz = 13
call doit(ix)
call readit
subroutine doit(ix_x)
include 'foop.cmn'
ipxp = malloc(8*ix_x*foo)
ipyp = malloc(8*iy*iz)
xp = 3
yp = 5
subroutine readit
include 'foop.cmn'
xp = 4
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" {
extern struct foo { int x ; } foo1_ ;
#ifdef __cplusplus
// 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
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
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