UK National HPC Service

Computer Services for Academic Research Logo
Home | Helpdesk | Machine Status | Search | Apply
 

Porting Codes 1

Default Data Sizes

The following tables show the default data sizes, in terms of the number of bits or bytes, of Fortran and C/C++ standard data types. The Fortran table also shows the changes to the default data sizes when applying the compiler flags -r8 and -i8 on any of the machines in order to change the default data sizes.

Data sizes for Fortran on Origin and Altix machines
Data TypeDefault size in bytesNew size in bytes with -r8 flagNew size in bytes with -i8 flag
Real48No effect
Double Precision88No effect
Complex816No effect
Integer4No effect8
Logical4No effect8

Data sizes for C and C++ on Origin and Altix machines
Data TypeSize in bytes
float4
double8
int4
short2
long8

In Fortran 90, the difference in default sizes of real and integer variables between machines can be overcome by using parameterised data types. For example if you create a module with the following:


Module precision
 Integer, Parameter :: int6 = Selected_Int_Kind(6)
 Integer, Parameter :: int12 = Selected_Int_Kind(12)
 Integer, Parameter :: real6 = Selected_Real_Kind(6)
 Integer, Parameter :: real12 = Selected_Real_Kind(12)
End Module precision

and use this as follows:


Program main
 Use precision
 Implicit None
 Integer(int6) :: short_int
 Real(real12) :: long_real
 ...

short_int will always have a type which permits integers of at least 10**6 and

long_real will always a precision of at least 12 decimal places

no matter which architecture you are using.

However if you are converting codes which make calls to external libraries, you may still need to change the names in calls to those library routines, such as changing the BLAS routine SGEMM for (Single precision) matrix multiplication on a Cray T3E to (Double precision) DGEMM on the CSAR machines as single precision Real numbers are 8 bytes by default on the older Cray architecture. Another set of libraries where there are porting issues related to the use of default or explicit typed real and integer variables are the message passing libraries (the Fortran 90 parameterised data type feature does not map well on to the existing message passing libraries - MPI 2 will be better).

Changing the Default Sizes in Fortran

Many Fortran codes, particularly legacy codes, have been written with Real as the floating point data type for numerical computations. Since these codes may now be solving much larger problems than those for which they were originally designed, more numerical rounding error may be introduced into the calculation, and consequently it is often desirable to increase the size of the floating point numbers from 32 bit (4 byte) Real variables to 64 bit (8 byte) Double Precision variables.

In order to make it easier to change the precision of floating point calculations in Fortran codes, most compilers, including the MIPSpro and Intel compilers on the Origin and Altix machines, use a standard compiler flag of -r8 to increase the accuracy from 32 bit to 64 bit arithmetic. Similar changes can be made for integer calculations using the compiler flag -i8.

It should be noted that on modern processors 64 bit arithmetic is as fast as 32 bit arithmetic when carrying out floating point addition, subtraction and multiplication. Division and hardware square root calculations may be slower, but the impact on the execution time of an entire code of increasing precision from 32 bit to 64 bit floating point arithmetic is usually only one or two per cent.

Furthermore, on some computers, such as the Cray T3E, Fortran Real variables are themselves represented as 64 bit floating point numbers, so that porting a Cray code to the Origin or Altix machines would require the use of the -r8 compiler flag in order to maintain the same accuracy as the Cray version of the code.

One other aspect of data which should be mentioned is the transfer of large amounts of binary information between different architectures and the endian nature of the data. Endian refers to the byte ordering of data such as integers and floating point numbers and can be little or big endian depending on whether the least or most significant byte is stored first. This concept is best illustrated by an example.

Endian Example

If we have the 4 byte hexadecimal number 0x12345678 then we could store this in memory as the 4 byte sequence 0x12, 0x34, 0x56, 0x78 or it could be stored as the 4 byte sequence 0x78, 0x56, 0x34, 0x12, or any other combination. The first of these two sequences shows the byte ordering as big-endian whereas the second ordering is little-endian.

Since either big-endian or little-endian storage is equally valid (although proponents of one or other storage system would say theirs is the best) , different manufactures of computer chips have selected one or the other storage mechanism and this is one of the main reasons why data can lose portability between machines. It should be noted that there are other differences between storage formats, particularly in how to delimit Fortran records, but the endian nature of storage is usually the most significant difference.

On the Origin's MIPS processors, data is stored in a big-endian format, while on the Itanium chips on the Altix the format is little-endian, and this means that it is not straightforward to transfer binary files between the two systems.

In order to aid in the transfer of binary files between different architectures where the intention is to use Fortran programs to read or write the data, the compiler vendors have devised methods of modifying the behaviour of the input/output routines on their systems. On the Origin machines it is possible to use the assign command before executing your program in order to change the properties of the Fortran program - see man assign for more details. On the Altix it is possible to use environment variables to change the behaviour of Intel's runtime input/output library to read in a different format. For the version 7 compilers this is restricted to changing the endian nature of the data, but in the version 8 compilers extra changes can be made which enable a program to read or write data in a variety of native formats such as those defined by Cray or IBM.

Standard Precision in Fortran

A good way of writing new Fortran code in a manner which allows a quick change of precision between standard Real and Double Precision numbers is to write a module such as


Module working_precision
 Integer, Parameter :: sp = Kind(0.0E0)
 Integer, Parameter :: dp = Kind(0.0D0)
 Integer, Parameter :: wp = dp
End Module working_precision

which defines the parameter sp to be refer to single precision (i.e. Real) numbers and dp to refer to Double Precision numbers and wp can then easily be changed to be sp or dp. Then it is just left to the code author to write their code so that floating point numbers are always defined as wp variables and constants as in:-


Program my_prog
 Use working_precision
 Implicit None
 Real(wp) :: scalar_var
 Real(wp), Parameter :: one=1.0_wp
 Real(wp), Dimension(10,10) :: square_array
 ...

Page maintained by This page last updated: Tuesday, 17-Aug-2004 15:32:54 BST