Skip to content. Skip to navigation

ICTP Portal

Sections
You are here: Home Manuals on-line PGI Compiler pghpf_ref PGHPF Workstation Reference Manual - D PGI Language Extensions
Personal tools
Document Actions

PGHPF Workstation Reference Manual - D PGI Language Extensions

<< << " border=0> >> > " border=0> Title Contents Index Home Help

D PGI Language Extensions


D.1 PGI Structures and Records @

D.1.1 Structures @

A structure is a user-defined aggregate data type having the following form:

STRUCTURE [/structure_name/][field_namelist]
field_declaration
[field_declaration]
... [field_declaration]
END STRUCTURE
Where:
structure_name
is unique and is used both to identify the structure and to allow its use in subsequent RECORD statements.
field_namelist
is a list of fields having the structure of the associated structure declaration. A field_namelist is allowed only in nested structure declarations.
field_declaration
can consist of any combination of substructure declarations, typed data declarations, union declarations or unnamed field declarations.
Fields within structures conform to machine-dependent alignment requirements. Alignment of fields also provides a C-like "struct" building capability and allows convenient inter-language communications.

Field names within the same declaration nesting level must be unique, but an inner structure declaration can include field names used in an outer structure declaration without conflict. Also, because records use periods to separate fields, it is not legal to use relational operators (for example, .EQ., .XOR.), logical constants (.TRUE. or .FALSE.), or logical expressions (.AND., .NOT., .OR.) as field names in structure declarations.

Fields in a structure are aligned as required by hardware; therefore a structure's storage requirements are machine-dependent. Because explicit padding of records is not necessary, the compiler recognizes the %FILL intrinsic, but performs no action in response to it.

Data initialization can occur for the individual fields.

D.1.2 Records @

A record is a user-defined aggregate data item having the following form:

RECORD /structure_name/record_namelist
[,/structure_name/record_namelist]
... [,/structure_name/record_namelist]
Where:
structure_name
is the name of a previously declared structure.
record_namelist
is a list of one or more variable or array names separated by commas.
You create memory storage for a record by specifying a structure name in the RECORD statement. You define the field values in a record either by defining them in the structure declaration or by assigning them with executable code.

You can access individual fields in a record by combining the parent record name, a period (.), and the field name (for example, recordname.fieldname). For records, a scalar reference means a reference to a name that resolves to a single typed data item (for example, INTEGER), while an aggregate reference means a reference that resolves to a structured data item.

Scalar field references may appear wherever normal variable or array elements may appear with the exception of COMMON, SAVE, NAMELIST, DATA and EQUIVALENCE statements. Aggregate references may only appear in aggregate assignment statements, unformatted I/O statements, and as parameters to subprograms.

The following is an example of RECORD and STRUCTURE usage.

	STRUCTURE /person/    ! Declare a structure to define a person
INTEGER id
LOGICAL living
CHARACTER*5 first, last, middle
INTEGER age
END STRUCTURE
! Define population to be an array where each element is of
! type person. Also define a variable, me, of type person.
RECORD /person/ population(2), me
...
me.age = 34 ! Assign values for the variable me to
me.living = .TRUE. ! some of the fields.
me.first = 'Steve'
me.id = 542124822
...
population(1).last = 'Jones' ! Assign the "last" field of
! element 1 of array population.
population(2) = me ! Assign all the values of record
! "me" to the record population(2)

D.1.3 UNION and MAP Declarations @

A UNION declaration is a multi-statement declaration defining a data area that can be shared intermittently during program execution by one or more fields or groups of fields. It declares groups of fields that share a common location within a structure. Each group of fields within a union declaration is declared by a MAP declaration, with one or more fields per MAP declaration.

Union declarations are used when one wants to use the same area of memory to alternately contain two or more groups of fields. Whenever one of the fields declared by a union declaration is referenced in a program, that field and any other fields in its map declaration become defined. Then, when a field in one of the other map declarations in the union declaration is referenced, the fields in that map declaration become defined, superseding the fields that were previously defined.

A union declaration is initiated by a UNION statement and terminated by an END UNION statement. Enclosed within these statements are one or more map declarations, initiated and terminated by MAP and END MAP statements, respectively. Each unique field or group of fields is defined by a separate map declaration. The format of a UNION statement is as follows:

UNION
map_declaration
[map_declaration]
...
[map_declaration]
END UNION
The format of the map_declaration is as follows:
MAP
field_declaration
[field_declaration]
...
[field_declaration]
END MAP
where field_declaration is a structure declaration or RECORD statement contained within a union declaration, a union declaration contained within a union declaration, or the declaration of a typed data field within a union.

Data can be initialized in field declaration statements in union declarations. Note, however, it is illegal to initialize multiple map declarations in a single union.

Field alignment within multiple map declarations is performed as previously defined in structure declarations.

The size of the shared area for a union declaration is the size of the largest map defined for that union. The size of a map is the sum of the sizes of the field(s) declared within it plus the space reserved for alignment purposes.

Manipulating data using union declarations is similar to what happens using EQUIVALENCE statements. However, union declarations are probably more similar to union declarations for the language C. The main difference is that the language C requires one to associate a name with each "map" (union). Fortran field names must be unique within the same declaration nesting level of maps.

The following is an example of RECORD, STRUCTURE, MAP and UNION usage. The size of each element of the recarr array would be the size of typetag (4 bytes) plus the size of the largest MAP, the employee map (24 bytes).

        STRUCTURE /account/
INTEGER typetag ! Tag to determine defined map.
UNION
MAP ! Structure for an employee
CHARACTER*12 ssn ! Social Security Number
REAL*4 salary
CHARACTER*8 empdate ! Employment date
END MAP
MAP ! Structure for a customer
INTEGER*4 acct_cust
REAL*4 credit_amt
CHARACTER*8 due_date
END MAP
MAP ! Structure for a supplier
INTEGER*4 acct_supp
REAL*4 debit_amt
BYTE num_items
BYTE items(12) ! Items supplied
END MAP
END UNION
END STRUCTURE RECORD /account/ recarr(1000)

D.2 Cray Pointer Variables @

D.2.1 Pointer Variables

The POINTER statement declares a scalar variable to be a pointer variable (of data type INTEGER), and another variable to be its pointer-based variable.

The syntax of the POINTER statement is:

POINTER (p1, v1) [, (p2, v2) ...]
v1 and v2
are pointer-based variables. A pointer-based variable can be of any type, including STRUCTURE. A pointer-based variable can be dimensioned in a separate type, in a DIMENSION statement, or in the POINTER statement. The dimension expression may be adjustable, where the rules for adjustable dummy arrays regarding any variables which appear in the dimension declarators apply.
p1 and p2
are the pointer variables corresponding to v1 and v2. A pointer variable may not be an array. The pointer is an integer variable containing the address of a pointer-based variable. The storage located by the pointer variable is defined by the pointer-based variable (for example, array, data type, etc.). A reference to a pointer-based variable appears in Fortran statements like a normal variable reference (for example, a local variable, a COMMON block variable, or a dummy variable). When the based variable is referenced, the address to which it refers is always taken from its associated pointer (that is, its pointer variable is dereferenced).
The pointer-based variable does not have an address until its corresponding pointer is defined. The pointer is defined in one of the following ways:
  • By assigning the value of the LOC function.
  • By assigning a value defined in terms of another pointer variable.
  • By dynamically allocating a memory area for the based variable. If a pointer-based variable is dynamically allocated, it may also be freed.
The following code illustrates the use of pointers:
	REAL XC(10)
COMMON IC, XC
POINTER (P, I)
POINTER (Q, X(5))
P = LOC(IC)
I = 0 ! IC gets 0
P = LOC(XC)
Q = P + 20 ! same as LOC(XC(6))
X(1) = 0 ! XC(6) gets 0 ALLOCATE (X) ! Q locates an allocated memory area

D.2.2 Restrictions

The following restrictions apply to the POINTER statement:

  • No storage is allocated when a pointer-based variable is declared.
  • If a pointer-based variable is referenced, its pointer variable is
    assumed to be defined.
  • A pointer-based variable may not appear in the argument list of a
    SUBROUTINE or FUNCTION and may not appear in COMMON,
    EQUIVALENCE, DATA, NAMELIST, or SAVE statements.
  • A pointer-based variable can be adjusted only in a SUBROUTINE or FUNCTION subprogram. If a pointer-based variable is an adjustable array, it is assumed that the variables in the dimension declarator(s) are defined with an integer value at the time the SUBROUTINE or FUNCTION is called. For a variable which appears in a pointer-based variable's adjustable declarator, modifying its value during the execution of the SUBROUTINE or FUNCTION does not modify the bounds of the dimensions of the pointer-based array.
  • A pointer-based variable is assumed not to overlap with another
    pointer-based variable.

D.3 Octal and Hexadecimal Constants - Alternate Form @

The pghpf compiler supports an alternate form for octal constants, outside of DATA statements. The form for an octal constant is:

'c1c2...cn'O
The form of a hexadecimal constant is:
'a1a2...an'X
where ci is a digit in the range 0 to 7 and ai is a digit in the range 0 to 9 or a letter in the range A to F or a to f (case mixing is allowed). You can specify up to 64 bits (22 octal digits or 16 hexadecimal digits).

Octal and hexadecimal constants are stored as either 32-bit or 64-bit quantities. They are padded on the left with zeroes if needed and assume data types based on how they are used.

The following are the rules for converting these data types:

  • A constant is always either 32 or 64 bits in size and is typeless. Sign-extension and type-conversion are never performed. All binary operations are performed on 32-bit or 64-bit quantities. This implies that the rules to follow are only concerned with mixing 32-bit and 64-bit data.
  • When a constant is used with an arithmetic binary operator (including the assignment operator) and the other operand is typed, the constant assumes the type and size of the other operand.
  • When a constant is used in a relational expression such as .EQ., its size is chosen from the operand having the largest size. This implies that
    64-bit comparisons are possible.
  • When a constant is used as an argument to the generic AND, OR, EQV, NEQV, SHIFT, or COMPL function, a 32-bit operation is performed if no argument is more than 32 bits in size; otherwise, a 64-bit operation is performed. The size of the result corresponds to the chosen operation.
  • When a constant is used as an actual argument in any other context, no data type is assumed; however, a length of four bytes is always used. If necessary, truncation on the left occurs.
  • When a specific 32-bit or 64-bit data type is required, that type is assumed for the constant. Array subscripting is an example.
  • When a constant is used in a context other than those mentioned above, an INTEGER*4 data type is assumed. Logical expressions and binary arithmetic operations with other untyped constants are examples.
  • When the required data type for a constant implies that the length needed is more than the number of digits specified, the leftmost digits have a value of zero. When the required data type for a constant implies that the length needed is less than the number of digits specified, the constant is truncated on the left. Truncation of nonzero digits is allowed.
  • In the example below, the constant I (of type INTEGER*4) and the constant J (of type INTEGER*2) will have hex values 1234 and 4567, respectively. The variable D (of type REAL*8) will have the hex value x4000012345678954 after its second assignment:
	I = '1234'X       ! Leftmost Pad with zero.
J = '1234567'X ! Truncate Leftmost 3 hex digits
D = '40000123456789ab'X
D = NEQV(D,'ff'X) ! 64-bit Exclusive Or

D.4 Non-character Format Specifiers @

If a format specifier is not of type CHARACTER, the compiler accepts it and treats it as if the contents were character.

For example, below sum is treated as a format descriptor:

        sum = 4h()
print sum
and is roughly equivalent to
        character*4 ch
ch = '()'
print ch

D.5 Built-in Functions @

The built-in functions perform inter-language utilities for argument passing and location calculations. The following built-in functions are available:


%LOC(arg)

Compute the address of the argument arg.


%REF(a)

Pass the argument a by reference.


%VAL(a)

Pass the argument as a 32-bit immediate value (64-bit if a is double precision.) A value of 64-bits is also possible if supported for integer and logical values.

D.6 PGI Statement Extension Reference @


MAP @

A union declaration is initiated by a UNION statement and terminated by an END UNION statement. Enclosed within these statements are one or more map declarations, initiated and terminated by MAP and END MAP statements, respectively. Each unique field or group of fields is defined by a separate map declaration.

Syntax

MAP
field_declaration
[field_declaration]
...
[field_declaration]
END MAP
field_declaration
is a structure declaration or RECORD statement contained within a union declaration, a union declaration contained within a union declaration, or the declaration of a typed data field within a union.

Description

Data can be initialized in field declaration statements in union declarations. Note, however, it is illegal to initialize multiple map declarations in a single union.

The size of the shared area for a union declaration is the size of the largest map defined for that union. The size of a map is the sum of the sizes of the field(s) declared within it plus the space reserved for alignment purposes.

Manipulating data using union declarations is similar to what happens using EQUIVALENCE statements. However, union declarations are probably more similar to union declarations for the language C. The main difference is that the language C requires one to associate a name with each map (union). Fortran field names must be unique within the same declaration nesting level of maps.

Example

The following is an example of RECORD, STRUCTURE and UNION usage. The size of each element of the recarr array would be the size of typetag (4 bytes) plus the size of the largest MAP - the employee map (24 bytes).

STRUCTURE /account/
INTEGER typetag ! Tag to determine defined map.
UNION
MAP ! Structure for an employee
CHARACTER*12 ssn ! Social Security Number
REAL*4 salary
CHARACTER*8 empdate ! Employment date
END MAP
MAP ! Structure for a customer
INTEGER*4 acct_cust
REAL*4 credit_amt
CHARACTER*8 due_date
END MAP
MAP ! Structure for a supplier
INTEGER*4 acct_supp
REAL*4 debit_amt
BYTE num_items
BYTE items(12) ! Items supplied
END MAP
END UNION
END STRUCTURE RECORD /account/ recarr(1000)


RECORD @

The RECORD statement defines a user-defined aggregate data item.

Syntax

RECORD /structure_name/record_namelist
[,/structure_name/record_namelist]
... [,/structure_name/record_namelist] END RECORD
structure_name
is the name of a previously declared structure.
record_namelist
is a list of one or more variable or array names separated by commas.

Description

You create memory storage for a record by specifying a structure name in the RECORD statement. You define the field values in a record either by defining them in the structure declaration or by assigning them with executable code.

You can access individual fields in a record by combining the parent record name, a period (.), and the field name (for example, recordname.fieldname). For records, a scalar reference means a reference to a name that resolves to a single typed data item (for example, INTEGER), while an aggregate reference means a reference that resolves to a structured data item.

Scalar field references may appear wherever normal variable or array elements may appear with the exception of the COMMON, SAVE, NAMELIST, DATA and EQUIVALENCE statements. Aggregate references may only appear in aggregate assignment statements, unformatted I/O statements, and as parameters to subprograms.

Records are allowed in COMMON and DIMENSION statements.

Example

	STRUCTURE /PERSON/    ! Declare a structure to define a person
INTEGER ID
LOGICAL LIVING
CHARACTER*5 FIRST, LAST, MIDDLE
INTEGER AGE
END STRUCTURE
! Define population to be an array where each element is of
! type person. Also define a variable, me, of type person.
RECORD /PERSON/ POPULATION(2), ME
...
ME.AGE = 34 ! Assign values for the variable me to
ME.LIVING = .TRUE. ! some of the fields.
ME.FIRST = 'Steve'
ME.ID = 542124822
...
POPULATION(1).LAST = 'Jones' ! Assign the "LAST" field of
! element 1 of array population.
POPULATION(2) = ME ! Assign all the values of record
! "ME" to the record population(2)

RECORD @

The STRUCTURE statement defines an aggregate data type.

Syntax

STRUCTURE [/structure_name/][field_namelist]
field_declaration
[field_declaration]
... [field_declaration]
END STRUCTURE
structure_name
is unique and is used both to identify the structure and to allow its use in subsequent RECORD statements.
field_namelist
is a list of fields having the structure of the associated structure declaration. A field_namelist is allowed only in nested structure declarations.
field_declaration
can consist of any combination of substructure declarations, typed data declarations, union declarations or unnamed field declarations.

Description

Fields within structures conform to machine-dependent alignment requirements. Alignment of fields also provides a C-like "struct" building capability and allows convenient inter-language communications.

Field names within the same declaration nesting level must be unique, but an inner structure declaration can include field names used in an outer structure declaration without conflict. Also, because records use periods to separate fields, it is not legal to use relational operators (for example, .EQ., .XOR.), logical constants (.TRUE. or .FALSE.), or logical expressions (.AND., .NOT., .OR.) as field names in structure declarations.

Fields in a structure are aligned as required by hardware and a structure's storage requirements are therefore machine-dependent. Note that VAX/VMS Fortran does no padding. Because explicit padding of records is not necessary, the compiler recognizes the %FILL intrinsic, but performs no action in response to it.

Data initialization can occur for the individual fields.

The UNION and MAP statements are supported.

The following is an example of record and structure usage.

STRUCTURE /account/
INTEGER typetag ! Tag to determine defined map.
UNION
MAP ! Structure for an employee
CHARACTER*12 ssn ! Social Security Number
REAL*4 salary
CHARACTER*8 empdate ! Employment date
END MAP
MAP ! Structure for a customer
INTEGER*4 acct_cust
REAL*4 credit_amt
CHARACTER*8 due_date
END MAP
MAP ! Structure for a supplier
INTEGER*4 acct_supp
REAL*4 debit_amt
BYTE num_items
BYTE items(12) ! Items supplied
END MAP
END UNION
END STRUCTURE RECORD /account/ recarr(1000)


STRUCTURE @

A union declaration is a multistatement declaration defining a data area that can be shared intermittently during program execution by one or more fields or groups of fields. It declares groups of fields that share a common location within a structure. Each group of fields within a union declaration is declared by a map declaration, with one or more fields per map declaration.

Syntax

UNION
map_declaration
[map_declaration]
...
[map_declaration]
END UNION
The format of the map_declaration is as follows:
MAP
field_declaration
[field_declaration]
...
[field_declaration]
END MAP
field_declaration
is a structure declaration or RECORD statement contained within a union declaration, a union declaration contained within a union declaration, or the declaration of a typed data field within a union.

Description

Union declarations are used when one wants to use the same area of memory to alternately contain two or more groups of fields. Whenever one of the fields declared by a union declaration is referenced in a program, that field and any other fields in its map declaration become defined. Then, when a field in one of the other map declarations in the union declaration is referenced, the fields in that map declaration become defined, superseding the fields that were previously defined.

A union declaration is initiated by a UNION statement and terminated by an END UNION statement. Enclosed within these statements are one or more map declarations, initiated and terminated by MAP and END MAP statements, respectively. Each unique field or group of fields is defined by a separate map declaration. The format of a UNION statement is as follows:

Data can be initialized in field declaration statements in union declarations. Note, however, it is illegal to initialize multiple map declarations in a single union.

The size of the shared area for a union declaration is the size of the largest map defined for that union. The size of a map is the sum of the sizes of the field(s) declared within it plus the space reserved for alignment purposes.

Manipulating data using union declarations is similar to what happens using EQUIVALENCE statements. However, union declarations are probably more similar to union declarations for the language C. The main difference is that the language C requires one to associate a name with each map (union). Fortran field names must be unique within the same declaration nesting level of maps.

The following is an example of RECORD, STRUCTURE and UNION usage. The size of each element of the recarr array would be the size of typetag (4 bytes) plus the size of the largest MAP - the employee map (24 bytes).

STRUCTURE /account/
INTEGER typetag ! Tag to determine defined map.
UNION
MAP ! Structure for an employee
CHARACTER*12 ssn ! Social Security Number
REAL*4 salary
CHARACTER*8 empdate ! Employment date
END MAP
MAP ! Structure for a customer
INTEGER*4 acct_cust
REAL*4 credit_amt
CHARACTER*8 due_date
END MAP
MAP ! Structure for a supplier
INTEGER*4 acct_supp
REAL*4 debit_amt
BYTE num_items
BYTE items(12) ! Items supplied
END MAP
END UNION
END STRUCTURE RECORD /account/ recarr(1000)

UNION @

The compiler option -Mcmf provides limited support for CM Fortran compatibility (Thinking Machines Corporation version of Fortran). This includes support for the intrinsics DOTPRODUCT, DLBOUND, DUBOUND, and DSHAPE which have calling sequences identical to their Fortran 90 counterparts. It also includes support for the CM Fortran method of using square brackets in the definition of array constructors and the use of the ARRAY keyword in place of the Fortran 90 standard DIMENSION keyword.

There are three CM Fortran intrinsics which have names identical to their Fortran 90 counterparts but whose calling sequences differ. These are CSHIFT, EOSHIFT, and RESHAPE. If pghpf is invoked with the compiler switch -Mcmf these three intrinsics will be interpreted using the CM Fortran convention rather than the standard Fortran 90 convention. It's worth noting that there are 6 additional non-standard intrinsics in CM Fortran: PROJECT, LASTLOC, FIRSTLOC, RANK, DIAGONAL, and REPLICATE. These non-standard intrinsics are not supported by pghpf. Other features of CM Fortran that are not supported are the layout directives and the utility routines.

D.7 CM Fortran Intrinsics @

Perform a circular shift on the specified array.

Synopsis

CSHIFT(ARRAY, DIM, SHIFT )

Arguments

The argument ARRAY is the array to shift. It may be an array of any type. The argument DIM is an integer representing the dimension to shift. The argument SHIFT is an integer or an array of integers with rank n-1 where n is the rank of ARRAY.

Return Value

The shifted array with the same size and shape as the argument ARRAY.


CSHIFT @

Perform an end-off shift on the specified array.

Synopsis

CSHIFT(ARRAY, DIM, SHIFT, BOUNDARY )

Arguments

The argument ARRAY is the array to shift. It may be an array of any type. The argument DIM is an integer representing the dimension to shift. The argument SHIFT is an integer or an array of integers with rank n-1 where n is the rank of ARRAY. The optional argument BOUNDARY is of the same type as the array, it may be scalar or of rank n-1 where n is the rank of ARRAY. BOUNDARY is the value to fill in the shifted out positions. By default it has the following values for integer, 0, for real, 0.0, for complex, (0.0,0.0), for logical false, for character, the default is blank characters.

Return Value

The shifted array with the same size and shape as the argument ARRAY.


EOSHIFT @

Reconstructs an array with the specified shape using the elements of the source array.

Synopsis

RESHAPE(SHAPE, SOURCE, PAD, ORDER)

Arguments

The argument SHAPE is of type integer, rank one. It must not have more than 7 elements and no values can be negative. The argument SOURCE is an array of any type. The optional argument PAD must be the same size and type as SOURCE. The optional argument ORDER must be of type integer and must have the same shape as SHAPE.

Return Value

The return value is an array of shape SHAPE, with the same type as SOURCE. Array elements are filled into the new array in array element order.


RESHAPE @

The following extensions to the PARAMETER statement are supported:

  • Its list is not bounded with parentheses.
  • The form of the constant (rather than the implicit or explicit typing of the symbolic name) determines the data type of the variable.
The form of the alternate PARAMETER statement is:
	PARAMETER p=c [,p=c]...
where p is a symbolic name and c is a constant, symbolic constant, or a compile time constant expression.


<< << " border=0> >> > " border=0> Title Contents Index Home Help

Powered by Plone This site conforms to the following standards: