Comparing pointers in Cray Fortran and Fortran 90

by Jeanne Adams
(Reprinted from SCD Computing News , January/February 1993, Copyright 1993 University Corporation for Atmospheric Research)

Most scientific programs involve large amounts of data that the programmer is called upon to manage. If space is a problem, and it often is, using space efficiently becomes important. A pointer facility makes it possible to do this with efficiency and clarity. Versions of Fortran at most installations running large data codes have some form of pointers and a set of related memory-management functions as extensions to FORTRAN 77; the Cray pointer facility is one of these extensions. A pointer facility is also included in the Fortran 90 standard.

However, Cray pointers are not like Fortran 90 pointers. While converting from Cray pointers to Fortran 90 pointers is possible, you will have to modify your existing programs to conform with the Fortran 90 standard. FORTRAN 77 did not have a pointer facility, and Cray pointers were added as an extension responding to user needs at the time.

Cray pointers are supported in CF77, the Cray compiling system, and will be supported in Cray's Fortran 90 compiler (tentatively scheduled for release in early 1994). However, Cray pointers may not be available on new computer architectures. The Cray Fortran 90 compiler will support both Cray and Fortran 90 pointers. This will be possible because there is no ambiguity in having both types of pointers in the same compiler.

Fortran 90 pointers are not currently available in CF77, but are available on the IBM RS/6000 cluster and will be available on most computer architectures in the near future. The Fortran 90 pointer facility fits nicely into the new array features and extensions for declaring data in the new standard.

Because Cray pointers and Fortran 90 pointers are based on two different standards (FORTRAN 77 and Fortran 90), the syntax and semantics are different. In general, a Cray pointer is a new data type that does absolute addressing and address arithmetic. A Fortran 90 pointer is a data attribute and is a descriptor pointing to a named variable.

Cray pointers

The most common use of Cray pointers is to manage workspace efficiently and conveniently. A Cray pointer is an absolute memory-addressing facility that points to or addresses various work areas of an array, making it possible to use another name for space in memory. The pointer and its target, the pointee, are declared in the following statement:

 POINTER  (pointer,
$ pointee [(dimensions)]) [,...]

Examples might be:

 POINTER  (Pl,  A),  (P2,  B)
POINTER (PX, X(1:40))

A, B, and X(1:4()) are pointees--that is, targets pointed to by Pl, P2, and PX. A pointee may be a variable name, an array declarator, or an array name.

Example 1 demonstrates a simple memory management scheme for the array WORK. Simple pointer integer arithmetic changes the starting address of the array associated with the pointer, and therefore, the placement of the pointee in the array WORK. Example 2 shows output for the program in Example 1.

Example 1. A simple memory-management scheme for the arry WORK
 1        PROGRAM CRAY_POINTERS
2 COMMON WORK (20)
3 REAL PNTEE (5,2), X(5,2), Y(5,2), WORK
4 C The type and shape of pointer targets PNTEE, X, Y established
5 POINTER (PTR, PNTEE), (PX, X), (PY, Y)
6 C PNTEE, X and Y are pointees; PTR, PX and PY are pointers.
7 C
8 N = 10
9 C Next make PTR point to the WORK array in Common; that is,
10 C PNTEE (1.1) will be equivalenced to WORK(l), and effectively
11 C assigning space. LOC is a Cray function to obtain the address
12 C of the argument.
13 PTR = LOC(WORK)
14 C Next make PX point to 10 address locations beyond LOC(WORK).
15 PX = PTR + N
16 C
17 PNTEE = 1.0
18 X = 2.0
19 PRINT "(A/,(5F5.1))", "The WORK array", WORK
20 PRINT "(A/,(SF5.1))", "Arrays PNTEE and X", PNTEE, X
21 PRINT "(A,2I10)", "Value of Pointers", PTR, PX
22 C
23 PTR = PX
24 PRINT "(A/,(5F5.1))", "The WORK array", WORK
25 PRINT "(A/,(5F5.1))", "Arrays PNTEE and X after PTR=PX",PNTEE,X
26 PRINT "(A,2I10)", "Value of Pointers", PTR, PX
27 C
28 PNTEE (1:5, 1) = 3.0
29 PY = PX - 5
30 C
31 PRINT "(A/,(SFS.l))", "The WORK array", WORK
32 PRINT "(A/,(5F5.1))", "Arrays PNTEE and X after PNTEE reset", 33 *PNTEE, X
34 PRINT "(A/,(5F5.1))", "The Y array", Y
35 PRINT "(A.3I10)". "Final Value of PTR, PX, and PY", PTR, PX, PY
36 END

Figure 1 illustrates the targets PNTEE and X in the work array WORK after line 18 in Example 1. Figure 2 shows the targets PNTEE and X after the assignment statement PTR = PX (line 23 in Example 1). Figure 3 shows the targets Y, PNTEE, and X after the assignment statement PY = PX - 5 (line 29 in Example 1).

Cray pointers may point to variables of different types during execution. They are assigned absolute addresses, and while address arithmetic can be performed, there is no way to nullify the pointer status.

When porting code from the CRAY-MP8/864 (shavano) to the IBM RS/6000 cluster, note that the IBM RS/6000 is byte- and not word-oriented, so that in the program in Example 1, N should be 40 and not 10. If these pointers are used on the IBM compiler XLF, DO loops must be used instead of whole-array assignment.

Example 2. Output for the program in Example 1
The WORK array
1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0
2.0 2.0 2.0 2.0 2.0
2.0 2.0 2.0 2.0 2.0

Arrays PNTEE and X
1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0
2.0 2.0 2.0 2.0 2.0
2.0 2.0 2.0 2.0 2.0

Value of Pointers 85872 85882

The WORK array
1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0
2.0 2.0 2.0 2.0 2.0
2.0 2.0 2.0 2.0 2.0

Arrays PNTEE and X after PTR=PX
2.0 2.0 2.0 2.0 2.0
2.0 2.0 2.0 2.0 2.0
2.0 2.0 2.0 2.0 2.0
2.0 2.0 2.0 2.0 2.0

Value of Pointers 85882 85882

The WORK array
1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0
3.0 3.0 3.0 3.0 3.0
2.0 2.0 2.0 2.0 2.0

Arrays PNTEE and X after PNTEE reset
3.0 3.0 3.0 3.0 3.0
2.0 2.0 2.0 2.0 2.0
3.0 3.0 3.0 3.0 3.0
2.0 2.0 2.0 2.0 2.0

The Y array
1.0 1.0 1.0 1.0 1.0
3.0 3.0 3.0 3.0 3.0

Final Value of PTR, PX, and PY 85882 85882 85877

Figure 1

POINTERS     ADDRESSES  WORK SPACE IN MEMORY    NAMES OF POINTEES
-----------------------------------------------------------------
WORK (20)
------------------
PTR 85872-----> 1.0 1.0 1.0 1.0 1.0 PNTEE (5,2)
85877 1.0 1.0 1.0 1.0 1.0
-----------------
PX 85882-----> 2.0 2.0 2.0 2.0 2.0 X (5,2)
85887 2.0 2.0 2.0 2.0 2.0

Figure 2

                         WORK (20)
-----------------
85872 1.0 1.0 1.0 1.0 1.0 PNTEE (5,2)
85877 1.0 1.0 1.0 1.0 1.0
-----------------
PTR, PX 85882-----> 2.0 2.0 2.0 2.0 2.0 PNTEE (5,2), X(5,2)
85887 2.0 2.0 2.0 2.0 2.0

Figure 3

                          WORK (20)
-----------------
85872 1.0 1.0 1.0 1.0 1.0
PY 85877 ----> 1 0 1.0 1 0 1 0 1 0 Y(5,2)
-----------------
PTR, PX 85882 3.0 3.0 3.0 3.0 3.0 PNTEE (5,2), X(5,2)
85887 2.0 2.0 2.0 2.0 2.0

Fortran 90 pointers


In Fortran 90, a pointer is a variable that has the POINTER attribute. A pointer may be associated with or aliased to various data objects (targets) during execution, or it may be undefined or null (not aliased to any data object). The pointer and the target attributes must be declared in the specification part of the program in order for data to be used in this way. The pointer and its target must be of the same type; the pointer must have the POINTER attribute, and the target data must have the TARGET attribute.

For example:

REAL,  TARGET  ::  POINTEE
REAL, POINTER :: PTR

PTR => POINTEE

The pointer PTR points to the target POINTEE. This is done with the pointer-assignment statement and the new pointer-assignment operator =>. The target may be a scalar, an array, or an array section.

A new statement, the ALLOCATE statement, creates space for variables with the POINTER attribute or for arrays with the ALLOCATABLE attribute. Space may be subsequently deallocated. For example:

REAL,  POINTER ::  Pl(:)
ALLOCATE (Pl(100))
...
...
DEALLOCATE (Pl)

A pointer variable may be nullified--that is, cleared so that it does not point to anything. A NULLIFY statement removes the association of a pointer and a target. The pointer may then point to a different target later in the program. For example:

PTR => POINTEE
...
NULLIFY (PTR)
...

PTR => A

An important additional use of Fortran 90 pointers will be in processing linked lists.

Differences between Cray and Fortran 90 pointers


An informal report, "Fortran 90 Pointers vs. Cray Pointers" (Jeanne Martin, Lawrence Livermore National Laboratory, UCRL-ID 108534), provides additional insight into the difference.s between Cray and Fortran 90 pointers. The following discussion is taken from that report, with permission of the author.

Cray pointers and Fortran 90 pointers differ in the following ways:

There are two names associated with a Cray pointer: the name of the pointer and the name used to refer to the pointer target. There is only one name associated with a Fortran 90 pointer. The interpretation of this name is determined by context; that is, certain statements can refer only to pointers, while others can refer only to target objects.

Cray pointers are memory locations. The pointer is treated as an integer, and the type of the target can change during execution. Fortran 90 pointers, on the other hand, are a distinct type. They are descriptors containing both type and rank information. They point to specific kinds of data objects; that is, Fortran 90 pointers are "strongly typed." For example, if a given pointer is declared to point to a two-dimensional real array, it can never point to any other kind of data object. It may point to several different arrays, and the dimensions may vary; but it can never point to a scalar integer object, for instance.

A pointer is an attribute in Fortran 90. This attribute may be given to any data object, including an object of user-defined type. In some implementations of Cray pointers, it is not possible to point to objects of type CHARACTER. An implementer (that is, a writer of a Fortran 90 compiler) might find it equally difficult to extend Cray pointers to point to some of the new Fortran 90 data objects of user-defined type or nondefault kind. An implementer who added Cray pointers to a standard Fortran 90 compiler would have to decide whether to make the pointers pervasive throughout the language or to provide them only to aid code migration (that is, applying only to FORTRAN 77 features).

Cray pointers can be assigned absolute addresses; Fortran 90 pointers cannot.

A Fortran 90 pointer can be set to point to no object by a NULLIFY statement. There is no language-provided way to nullify a Cray pointer.

A compiler may assume that a Cray pointer target has no storage in common with another variable. This provides optimization at the expense of possibly unreliable code. A Fortran 90 compiler assumes that pointers and objects with the TARGET attribute may overlap. This provides reliable code at the expense of some optimizations.

Note

Differences between the two types of pointers can cause significant problems when porting code from Cray pointers to Fortran 90 pointers; however, a discussion of these problems is beyond the scope of this article. If you have questions about your code, contact the SCD consultant on duty by sending e-mail to consult1@ncar.ucar.edu or calling (303) 497-1278. For a more detailed discussion of Fortran 90 pointers, see Programmer's Guide to Fortran 90 or Fortran 90 Handbook (citations below).

Jeanne Adams is a member of SCD's Computational Support Section. She coauthored Programmer's Guide to Fortran 90 (New York: McGraw-Hill Book Company, 1990) and Fortran 90 Handbook (New York: McGraw-Hill, 1992.)