Porting |
7 |
![]() |
Note - Porting issues bear mostly upon Fortran 77 programs. The Sun Fortran 90 compiler, f90, incorporates few nonstandard extensions, and these are described in the Fortran User's Guide.
The following time functions are not supported directly in the Sun Fortran libraries, but you can write subroutines to duplicate their functions:
The time functions supported in the Sun Fortran library are listed in Table 7-1:
For details, see Fortran Library Reference or the individual man pages for these functions.
The routines listed in Table 7-2 provide compatibility with VMS Fortran system routines idate and time. To use these routines, you must include the -lV77 option on the f77/f90 command line, in which case you also get these VMS versions instead of the standard f77 versions.
The error condition subroutine errsns is not provided, because it is totally specific to the VMS operating system.
Running this program produces the following results:
demo% TimeTest Hello, Time Now Is: Mon Feb 12 11:53:54 1996 See how long 'sleep 4' takes, in seconds Elapsed time for sleep 4 was: 5 seconds atan(q) 1000 times took: 2.26550E-03 seconds demo% |
Formats
Some f77 format edit descriptors may behave differently on other systems. Here are some format specifiers that f77 treats differently than some other implementations:
10 FORMAT( SU, 16R, I4 ) 20 FORMAT( SU, 8R, I4 ) |
OPEN( 6, FORM='PRINT') |
Example: Redirecting stdin to redir.data (using csh(1)):
See Chapter 2, Fortran Input/Output, for more on redirection and working with files.
Data Representation
The Fortran 77 Language Reference and the Sun Numerical Computation Guide discuss in detail the hardware representation of data objects in Fortran. Differences between data representations across systems and hardware platforms usually generate the most significant portability problems.
-dbl or -r8 flags are used to promote integers, logicals and reals to eight bytes
CHARACTER data type was provided for this purpose and its use is recommended. You can still initialize variables with the older Fortran Hollerith (nH) feature, but this is not standard practice. Table 7-3 indicates the maximum number of characters that will fit into certain data types. (In this table, boldfaced data types indicate default types subject to promotion by -dbl, -r8, or -xtypemap= .)|
|
Maximum Number of Standard ASCII Characters | ||||
|
Data Type |
No -i2, -i4, -r8, -dbl |
-i2 |
-i4 |
-r8 |
-dbl |
|
BYTE |
1 |
1 |
1 |
1 |
1 |
|
COMPLEX |
8 |
8 |
8 |
16 |
16 |
|
COMPLEX*16 |
16 |
16 |
16 |
16 |
16 |
|
COMPLEX*32 |
32 |
32 |
32 |
32 |
32 |
|
DOUBLE COMPLEX |
16 |
16 |
16 |
32 |
32 |
|
DOUBLE PRECISION |
8 |
8 |
8 |
16 |
16 |
|
INTEGER |
4 |
2 |
4 |
4 |
8 |
|
INTEGER*2 |
2 |
2 |
2 |
2 |
2 |
|
INTEGER*4 |
4 |
4 |
4 |
4 |
4 |
|
INTEGER*8 |
8 |
8 |
8 |
8 |
8 |
|
LOGICAL |
4 |
2 |
4 |
4 |
8 |
|
LOGICAL*1 |
1 |
1 |
1 |
1 |
1 |
|
LOGICAL*8 |
8 |
8 |
8 |
8 |
8 |
|
REAL |
4 |
4 |
4 |
8 |
8 |
|
REAL*4 |
4 |
4 |
4 |
4 |
4 |
|
REAL*8 |
8 |
8 |
8 |
8 |
8 |
|
REAL*16 |
16 |
16 |
16 |
16 |
16 |
When storing standard ASCII characters with normal Fortran:
Example: Initialize variables with Hollerith:
If you pass Hollerith constants as arguments, or if you use them in expressions or comparisons, they are interpreted as character-type expressions.
Nonstandard Coding Practices
As a general rule, porting an application program from one system and compiler to another can be made easier by eliminating any nonstandard coding. Optimizations or work-arounds that were successful on one system may only serve to obscure and confuse compilers on other systems. In particular, optimized hand-tuning for one particular architecture may turn out to cause degradations in performance elsewhere. This is discussed later in the chapters on performance and tuning. However, the following issues are worth considering with regards to porting in general. Uninitialized Variables
Some systems automatically initialize local and COMMON variables to zero or some not-a-number value. However, there is no standard practice, and programs should not make assumptions regarding the initial value of any variable. To assure maximum portability, a program should initialize all variables. Aliasing Across Calls
Aliasing occurs when the same storage address is referenced by more than one name. This happens when actual arguments to a subprogram overlap between themselves or between COMMON variables within the subprogram. For example, arguments X and Z refer to the same storage locations, as do B and H:
COMMON /INS/B(100) REAL S(100), T(100) ... CALL SUB(S,T,S,B,100) ... SUBROUTINE SUB(X,Y,Z,H,N) REAL X(N),Y(N),Z(N),H(N) COMMON /INS/B(100) ... |
Aliasing in this manner should be avoided in all portable code. The results on some systems and with higher optimization levels could be unpredictable.
Obscure Optimizations
Legacy codes may contain source-code restructurings of ordinary computational DO loops intended to cause older vectorizing compilers to generate optimal code for a particular architecture. In most cases, these restructurings are no longer needed and may degrade the portability of a program. Two common restructurings are strip-mining and loop unrolling. Strip-Mining
Fixed-length vector registers on some architectures led programmers to manually "strip-mine" the array computations in a loop into segments:
REAL TX(0:63) ... DO IOUTER = 1,NX,64 DO IINNER = 0,63 TX(IINNER) = AX(IOUTER+IINNER) * BX(IOUTER+IINNER)/2. QX(IOUTER+IINNER) = TX(IINNER)**2 END DO END DO |
DO IX = 1,N TX = AX(I)*BX(I)/2. QX(I) = TX**2 END DO |
Loop Unrolling
Unrolling loops by hand was a typical source-code optimization technique before compilers were available that could perform this restructuring automatically. A loop written as:
should be rewritten the way it was originally intended:
DO K = 1,N DO J = 1,N DO I = 1,N A(I,J) = A(I,J) + B(I,K) * C(K,J) END DO END DO END DO |
Troubleshooting
Here are a few suggestions for what to try when programs ported to Sun Fortran do not run as expected. Results Are Close, but Not Close Enough
Try the following:
-9.9992112e-33, especially if this number is the difference between two large numbers, such as the distance across the continent in feet, as calculated on two different computers.
real*4 x,y x=99999990e+29 y=99999996e+29 write (*,10), x, x 10 format('99,999,990 x 10^29 = ', e14.8, ' = ', z8)
write(*,20) y, y 20 format('99,999,996 x 10^29 = ', e14.8, ' = ', z8)
end |
99,999,990 x 10^29 = 0.99999993E+37 = 7cf0bdc1 99,999,996 x 10^29 = 0.99999993E+37 = 7cf0bdc1 |
-O1). If the program then works, compile only selective routines with higher optimization levels.