Skip to main content

Software  >  Software Development  >  IBM Fortran Compilers  >  

Porting Fortran between the CRAY and the RS/6000

 Technote (troubleshooting)
 
Problem(Abstract)
XL Fortran includes several extensions that allow you to port your CRAY Fortran code to the RISC System/6000 with minimal recoding
 
Resolving the problem
Since the IBM AIX XL Fortran compiler was first released in 1990, customers have been requesting features to help meet their porting needs from different platforms, including CRAY. All references to CRAY in this article refer to the Y-MP hardware line and/or the CF77 and CF90 Fortran compilers. XL Fortran includes several extensions that enable you to port your CRAY Fortran code with minimal recoding. Use the compiler options and routines described below to make your move between CRAY and the RISC System/6000 as easy as possible.

With Fortran 90 (ISO/IEC 1539:1991(E)) and Fortran 95 (ISO/IEC 1539:1997), most of the extensions discussed below can now be coded using standard-conforming language. When you are writing new code, this method is preferable because it ensures portability across any platform that supports Fortran 90 or Fortran 95. Fortran 90/95 alternatives are discussed at the end of each section. Of course, to port code that has already been written, using the extensions would likely require fewer changes.

The features covered in this article are:



-qintsize option

The -qintsize compiler option sets the default size of integer and logical data entities whose sizes are not explicitly declared. This option lets you easily port code from 16-bit and 64-bit machines.
For example, the declaration

    integer(8) x

explicitly specifies that x has a size of 8 bytes. But the declaration

    integer x

specifies that the compiler should provide the default integer size for x. For XL Fortran, the default size of integer/logical entities is 4 bytes, while for CRAY it is 8 bytes.

If you specify -qintsize=8 at compile time, x is declared as a 64-bit entity. This ensures that very large numbers (i.e., larger than the maximum integer(4) value) are not inadvertently truncated because of a different default size.

-qintsize affects:

  • integer/logical literals that do not specify kind type parameters
  • default integer/logical data objects and functions
  • intrinsic function results of type default integer/logical
  • typeless constants in integer contexts

Fortran 90/95 alternative

The Fortran 90/95 KIND intrinsic function returns the kind type parameter of an argument. It specifies the representation method for the argument. You can then use the kind type parameter when declaring entities. For example,
integer (kind=kind(0)) x

indicates that the size of x is the default integer size for the compiler. Compiled by a CRAY product, x is 8 bytes long; compiled by XL Fortran, x is 4 bytes long.

To ensure that entities have similar value ranges without specifying platform-specific information during type declaration (i.e., a kind type parameter), use the Fortran 90/95 SELECTED_INT_KIND intrinsic function. This function returns a kind type parameter value of an integer data type that represents all integer values n in the range -10**R < n < 10**R.

    integer (kind=selected_int_kind(18)) x
      ! XL Fortran kind type parameter: 8
      ! CRAY kind type parameter: 8


-qrealsize option

Similar to -qintsize, the -qrealsize compiler option sets the default size of real and complex entities whose sizes are not explicitly declared. The default real size in XL Fortran is 4 bytes, while the default on the CRAY products is 8 bytes.

Keep in mind that the precision of entities of type DOUBLE PRECISION is twice that of the default real size. Thus, if you specify -qrealsize=8, entities of type DOUBLE PRECISION have a default size of 16 bytes. Similarly, the size of complex and double complex entities is affected because they are formed from parts of type real.

Fortran 90/95 alternative

As discussed for integer entities, the KIND intrinsic function is also an alternative way to ensure portability for real entities:

    real (kind=kind(0.0)) r

KIND(0.0) always returns the kind type parameter of the processor's default real size.

Similarly, the SELECTED_REAL_KIND intrinsic function returns the kind type parameter value of a real data type with a minimal decimal precision and exponent range.



-qautodbl option

Use the -qautodbl compiler option to convert single-precision entities to double-precision entities and double-precision entities to extended-precision entities. Select from a variety of suboptions:



NONE

Does not promote or pad any objects that share storage. This is the default for -qautodbl.


DBL4

Promotes 4-byte floating-point objects, including objects composed of these objects, to 8-byte objects. For example, a complex(4) object is promoted to complex(8).


DBL8

Promotes 8-byte floating-point object, including objects composed of these objects, to 16-byte objects.


DBL

Performs the promotions done by both DBL4 and DBL8.

To help maintain proper storage relationships when code is ported, some suboptions will pad as well as promote objects:



DBLPAD4

Performs DBL4 promotion, and also pads objects of other types (except character) if they possibly share storage with promoted objects.


DBLPAD8

Performs DBL8 promotion, and also pads objects of other types (except character) if they possibly share storage with promoted objects.


DBLPAD

Performs the promotions done by both DBL4 and DBL8.

Note: If you compile with both the -qautodbl and -qrealsize options, -qrealsize is disregarded.

The following example illustrates promotion and padding using -qautodbl=dblpad:

@process autodbl(dblpad)
      complex(4) x8      /(1.123456789e0,2.123456789e0)/
      real(16) r16(2)    /1.123q0,2.123q0/
      integer(8) i8(2)   /1000,2000/
      character*5 c(2)   /"abcde","12345"/
      common /named/ x8,r16,i8,c
      end

@process autodbl(none)
      subroutine s()
         complex(8) x8
         real(16) r16(4)
         integer(8) i8(4)
         character*5 c(2)
         common /named/ x8,r16,i8,c
           x8 = (1.123456789d0,2.123456789d0)
                                  ! promotion occurred
           r16(1) = 1.123q0       ! padding occurred
           r16(3) = 2.123q0       ! padding occurred
           i8(1) = 1000           ! padding occurred
           i8(3) = 2000           ! padding occurred
           c(1) = "abcde"         ! no padding occurred
           c(2) = "12345"         ! no padding occurred
      end subroutine s


Integer pointers

Integer pointers are the XL Fortran version of CRAY pointers. XL Fortran integer pointers provide a means of referencing the address of a variable, which lets you step through a piece of storage or overlay pieces of storage. Given the statement:

    pointer (p,x)

p is the integer pointer, which references the address of x, a variable, or array declarator (generally called the pointee)

An integer pointer is a scalar variable of type integer(4) that cannot have a type explicitly assigned to it. The integer pointer can be used in any expression or statement in which an integer(4) can be used.

The compiler does not allocate storage for the pointee. Storage is associated with the pointee at execution time by assigning the address of a block of storage to the pointer.

When porting Fortran code between CRAY and the IBM RISC System/6000, you must consider some differences:

Pointer size

XL Fortran integer pointers are 4 bytes in size, whereas CRAY pointers are 8 bytes. If an absolute address is assigned to a pointer, ensure that:
1. the address can fit in 4 bytes of storage
2. the address is valid on an IBM RISC System/6000 platform

Incrementing/decrementing pointers

Adding or subtracting an integer n to an integer pointer increments (or decrements) the value of the pointer by n bytes. Adding or subtracting an integer n to a CRAY pointer increments (or decrements) the value of the pointer by n words. To maintain compatibility when porting, multiply the value of n (i.e., CRAY words) by the size of the RISC System/6000 machine word (e.g., 8).

     pointer (p,a)
     p = p+1

     +- initial memory position of p
     |
     V   1   2   3   4               8
     +----------------------------------- ...
     |   |   |   |   |               |
     +----------------------------------- ...
         |                           |
         |                           |
  position of p+1             position of p+1
  with XL Fortran                with CRAY

To port the code above to XL Fortran, modify the assignment statement:


    integer, parameter :: word_size = 8
    p = p + (word_size*1)


LOC intrinsic

The LOC intrinsic function returns the address of a pointee. This function is useful for finding the address of a variable and assigning it to the integer pointer of another pointee (overlaying the storage of the two variables).

The following examples show the modifications required when you are porting code from CRAY to XL Fortran.

Original Code:

  integer big_array(100)
 integer element, dim_size
 integer array1(5), array2(5), array3(10)

  pointer (p1,array1)
 pointer (p2,array2)
 pointer (p3,array3)

 ! Assign storage to array1
 p1 = loc(big_array)

 ! Initialize array1
 array1 = (/1,3,5,7,9/)

  ! Assign storage to array2
 p2 = p1 + 5

 ! Initialize array2
 array2 = (/2,4,6,8,10/)

 ! array3 holds data of array1 and array2
 p3 = loc(big_array)
 if ((array3(3) .ne. 5) .or. (array3(8) .ne. 6)) stop 1

 ! Increment storage loc where array1 begins by 2 words
 p1 = p1 + 2
 element = array1(5)
 if (element .ne. 4) stop 2

  end



Ported Version:

  @process intsize(8)           ! <----- Added code
 integer big_array(100)
 integer element, dim_size
 integer array1(5), array2(5), array3(10)

 pointer (p1,array1)
 pointer (p2,array2)
 pointer (p3,array3)

  integer word                  ! <----- Added code
 parameter (word = 8)          ! <----- Added code

 ! Assign storage to array1
 p1 = loc(big_array)

 ! Initialize array1
 array1 = (/1,3,5,7,9/)

 ! Assign storage to array2
 p2 = p1 + 5*word              ! <----- Modified code

 ! Initialize array2
 array2 = (/2,4,6,8,10/)

 ! array3 holds data of array1 and array2
 p3 = loc(big_array)
 if ((array3(3) .ne. 5) .or. (array3(8) .ne. 6)) stop 1

 ! Increment storage loc where array1 begins by 2 words
 p1 = p1 + 2*word              ! <----- Modified code
 element = array1(5)
 if (element .ne. 4) stop 2

 end

Fortran 90/95 alternative

To dynamically dimension arrays in Fortran 90/95, use deferred-shape array specifications, and then explicitly allocate memory for the arrays:


    integer, dimension(:), allocatable :: array
    i = 5
    allocate(array(5))
    array = (/1,2,3,4,5/)
    deallocate(array)
    end




Service and utility procedures

XL Fortran supports several CRAY procedures that are industry extensions. A subset of these are described below. These procedures (except for clock_) have the same names as the corresponding CRAY routines.

clock_

The clock_ function returns the time in hh:mm:ss format. (Note: the XL Fortran routine is clock_, not clock, because the libc library of AIX already contains a clock routine)

    character(8) c,clock_
    c = clock_()          ! c = "13:30:56"


date

The date function returns the system date in mm/dd/yy format.

    character(8) d,date
    d = date()            ! d = "06/21/94"


itrc

The irtc function returns an integer(8) value of the number of nanoseconds elapsed since the initial value of the machine's real-time clock.

    integer(8) :: a,b,elapsed,irtc,x=3
    a = irtc()
    do m = 1,20000
     x = x**2
    end do
    b = irtc()
    elapsed = b-a     ! elapsed = 33052928


rtc

The rtc function returns a real(8) value of the number of seconds elapsed since the initial value of the machine's real-time clock.

    real(8) :: a,b,elapsed,rtc,x=2.0
    a = rtc()
    do m = 1,20000
     x = x**2
    end do
    b = rtc()
    elapsed = b-a   ! loop required 0.846355768456422978e-02


timef

The timef function returns the elapsed time in milliseconds since the first instance timef was called. The first instance timef is called, the value 0.0d0 is returned.

    real(8) elapsed, timef
    elapsed = timef()     ! elapsed = 0.0d0
    do m = 1,20000
     a = a**2
    end do
    elapsed = timef()     ! elapsed = 15.2616500997857362


jdate

The jdate function returns the system Julian date in yyddd format.

    character(5) d,jdate
    d = jdate()           ! d = '94172'


Fortran 90/95 alternatives

You can use the DATE_AND_TIME intrinsic function to access date and time information, and the SYSTEM_CLOCK intrinsic function to inquire on your system clock.

Fortran 95 alternative

You can use the CPU_TIME intrinsic function to return the time, in seconds, taken by a process from the start of a program.



CVMGx procedures

XL Fortran supports conditional vector merge functions similar to CRAY's conditional vector merge functions. These functions take three arguments. The values returned by these functions depend on the result of the test that is done on the third argument. The first argument is returned if the test done on the third argument is true. The second argument is returned if the test done on the third argument is false. When the arguments are arrays, testing is done on an element-by-element basis.

The conditional vector merge functions are:

CVMGP test for positive values or zero
CVMGM test for negative values
CVMGZ test for zero values
CVMGN test for nonzero values
CVMGN test for logical true values
One point of caution if you are porting code to XL Fortran: although the CVMGx routines accept integer and real arguments, these arguments and the function return type are interpreted as Boolean data types on a CRAY. Since XL Fortran does not have a Boolean data type, the argument and function return types are treated as integer, logical, or real intrinsic data types. The only place you would see a difference between the behavior of XL Fortran and that of CRAY is if the function is referenced in an assignment or expression where type conversion is expected to occur.

    ! CRAY
    r = cvmgp(1.0,2.0,3.0)

                  ! r = 32-bit representation of 1.0
    i = cvmgp(1.0,2.0,3.0)

                  ! i = 32-bit representation of 1.0
                 ! i = 1065353216

    ! XL Fortran
    r = cvmgp(1.0,2.0,3.0)

                  ! r = 32-bit representation of 1.0
    i = cvmgp(1.0,2.0,3.0)

                  ! i = int(1.0)
                 ! i = 1


Fortran 90/95 alternative

Use the Fortran 90/95 MERGE intrinsic function instead of the CVMGx intrinsic functions.

    ! Original Code
    integer i
    integer i_a(3)
    integer array_t(3), array_f(3), mask(3)

    i = cvmgp(1.0,2.0,3.0)            ! i = 1

    array_t(1) = 1
    array_t(2) = 2
    array_t(3) = 3

    array_f(1) = 4
    array_f(2) = 5
    array_f(3) = 6

    mask(1) = 7
    mask(2) = 0
    mask(3) = 8

    i_a = cvmgz(array_t,array_f,mask)

                         ! i_a(1)=4, i_a(2)=2, i_a(3)=6
    end


    ! Fortran 90/95 Alternative
    integer :: i
    integer, dimension(3) :: i_a
    integer, dimension(3) :: array_t, array_f, mask

    i = merge(1.0,2.0,3.0 >= 0.0)     ! i = 1

    array_t = (/1,2,3/)
    array_f = (/4,5,6/)

    mask = (/7,0,8/)
    i_a = merge(array_t,array_f,mask == 0)

                         ! i_a = (/4,2,6/)
    end



Summary

XL Fortran Versions 7.1 and 8.1 support a variety of features to help you port code, including several industry extensions found in CRAY products. Also, because XL Fortran fully supports Fortran 90 and Fortran 95, you can modify your code so that it is portable to any platform that supports these Fortran standards.

For more information on porting, contact AIX Support Family at 1-800-CALL-AIX (US and Canada only).

Do you need more help?

For additional assistance, contact IBM Rational Client Support:
Submit a Service Request (SR)

 
 
 

Copyright and trademark information
IBM, the IBM logo and ibm.com are trademarks of International Business Machines Corp., registered in many jurisdictions worldwide. Other product and service names might be trademarks of IBM or other companies. A current list of IBM trademarks is available on the Web at "Copyright and trademark information" at www.ibm.com/legal/copytrade.shtml.
Rate this page
Please take a moment to complete this form to help us better serve you.
This material provides me with the information I need.




This material is clear and easy to understand.




Did the information help you to achieve your goal?
What updates, improvements, or related information would you like to see in this document?
Your response will be used to improve our document content. Requests for assistance, if applicable, should be submitted through your normal support channel as we cannot respond from this site.
Input the verification number to submit feedback:
Document information
 Product categories:
 Software
 Software Development
 Traditional Progamming Language & Compilers
 XL Fortran
 Compiler
 Operating system(s):
  AIX, AIXL
 Software version:
  7.1.0, 7.1.1, 8.1.0, 8.1.1, 9.1, 10.1
 Reference #:
  1030759
 IBM Group:
 Software Group
 Modified date:
 2004-09-19

Translate My Page
 
 

Rate this page

Help us improve this page. Your response will be used to improve our document content. Requests for assistance, if applicable, should be submitted through your normal support channel as we cannot respond from this site.