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.)