next up previous
Next: Batch Processing Up: User's Guide to the Previous: File Management

Subsections

Porting Codes

This section provides some helpful information on porting codes to the IBM p690 Regatta system.

Tips for FORTRAN programmers

Useful compiler options

The following compiler options may be useful when porting your code to the IBM p690 Regatta system:

compiler option effect
-initauto initialises variables all variables to zero at compile time
-eI equivalent to having IMPLICIT NONE throughout the code

Timers

It is often useful to include time keeping routines within your code. This section describes the timing routines available on the IBM p690 Regatta system.

Fortran codes

The Fortran 90 specific SYSTEM_CLOCK offers good portability, however due to its implementation as 32-byte integer we recommend it for simple tasks only.

  integer :: clock0, clock1, clockmax, clockrate, ticks
  real    :: secs
  call system_clock(count_max=clockmax, count_rate=clockrate)
  call system_clock(clock0)

  ! code to be timed

  call system_clock(clock1)

  ticks = clock1-clock0
  ticks = mod(ticks+clockmax, clockmax)   ! reset negative numbers
  secs = float(ticks)/float(clockrate)
  write(*,*) 'Code took ', secs, ' seconds'

MPI also defines a timer, namely MPI_Wtime() which returns a double precision number of seconds, representing elapsed wall-clock time since some time in the past. MPI_Wtime() provides a good and portable solution for Fortran codes using MPI.

Note this does not involve clock ticks, so use of this timer does not need to determine the clock rate. If one wishes to determine the resolution of MPI_WTime, then the routine MPI_Wtick() should be employed, which returns the number of seconds between successive clock ticks as a double precision value.

  DOUBLE PRECISION :: start, end
  start = MPI_Wtime()
 
  ! code to be timed
 
  end   = MPI_Wtime()
  print*,'That took ',end-start,' seconds'

Note that the times returned are local to the node that called them. There is no requirement that different nodes return ``the same time''. MPI provides a boolean variable, namely MPI_Wtime_is_global, which indicates whether clocks are synchronised.

Lastly, the following table gives a list of IBM SP vendor-specific calls which may be of use when timing FORTRAN codes. NB. these routines are non-portable.

Name Function
clock_ returns current time, in ASCII hh:mm:ss format
date returns the current date, in ASCII mm/dd/yy format
idate_ returns date in numerical form
irtc returns real-time clock
itime_ returns time in numerical form
jdate returns the current Julian day-number
rtc returns real-time clock
timef returns elapsed wall-clock time
time_ returns the value of time in seconds

Here is an example of a timing module which uses irtc:

module time_tool
  
contains
  function now_time()
    real(kind=8) now_time
    integer(kind=8) nano_time ,irtc
    external irtc

    nano_time=irtc()
    now_time = real(nano_time,kind=8) * 1.0e-9_8
  end function now_time
end module time_tool

C/C++ codes

ANSI C

The clock() function returns clock ticks.

#include <time.h>

clock_t start, end;
double elapsed;

start = clock();
 <code to be timed>
end = clock();
elapsed = ((double) (end - start)) / CLOCKS_PER_SEC;

The gettimeofday() function has a resolution of microseconds.

C++

#include <sys/time.h>
struct timeval *Tps, *Tpf;
void *Tzp;
Tps = (struct timeval*) malloc(sizeof(struct timeval)):
Tpf = (struct timeval*) malloc(sizeof(struct timeval));
Tzp = 0;
gettimeofday (Tps, Tzp);
 <code to be timed>
gettimeofday (Tpf, Tzp); 
printf("Total Time (usec): %ld\n",
(Tpf->tv_sec-Tps->tv_sec)*1000000
             + Tpf->tv_usec-Tps->rvr_usec);

As with FORTRAN codes, MPI_Wtime() may also be used with C/C++ codes to determine the time since a particular date.

C++ example

#include <mpi.h>
double start, finish;

start = MPI_Wtime();
 <code to be timed>
finish = MPI_Wtime();

printf("Final Time: %f", finish-start);
/* Time is in milliseconds since a particular date */

Java codes

For Java codes, the System.currentTimeMillis() may be used to determine the time since a particular date.

long start = System.currentTimeMillis();
 <code to be timed>
long finish = System.currentTimeMillis();
printf("Final Time: %f", finish-start);
/* Time is in milliseconds since a particular date */

Default sizes

FORTRAN codes

The default sizes and available datatypes of the SP are as follows

Type Length (bytes)
character 1
complex 2 x 4
double complex 2 x 8
double precision 8
integer/logical 4
real 4

NB. double complex is not standard FORTRAN.

The SP XL Fortran compiler flag -qrealsize=8 can be used to promote all default reals, and real constants, to 8 bytes. Integers and logicals can be similarly promoted using -qintsize=8.

A portable alternative is to use the Fortran 90 KIND syntax.

Type KIND * Length (bytes)
complex 4 8 2 x 4
  8 16 2 x 8
  16 32 2 x 16
integer/logical 1 1 1
  2 2 2
  4 4 4
  8 8 8
real 4 4 4
  8 8 8
  16 16 16

C/C++ codes

These are the default sizes of the standard C/C++ datatypes on the IBM SP.

Type Length (bytes)
bool 1
char 1
wchar_t 4
short 2
int 4
long 4/8
float 4
double 8
long double 8/16

NB. bool is C++ only.
The second number given for both long and long double applies when the code is compiled in 64 bit mode.

MPI Datatypes

The default sizes of MPI datatypes are different on the different machines:

Fortran

Type Length (bytes)
MPI_CHARACTER 1
MPI_COMPLEX 2 x 4
MPI_DOUBLE_COMPLEX 2 x 8
MPI_DOUBLE_PRECISION 8
MPI_INTEGER 4
MPI_LOGICAL 4
MPI_REAL 4

NB: If the associated compiler flags are employed to increase the precision of default reals, then the interpretation of MPI_REAL is NOT changed.

MPI defines additional datatypes with explicit sizes. These can be used to provide some portability:

Type Length (bytes) Type Length (bytes)
MPI_COMPLEX8 2 x 4 MPI_LOGICAL1 1
MPI_COMPLEX16 2 x 8 MPI_LOGICAL2 2
MPI_COMPLEX32 2 x 16 MPI_LOGICAL4 4
MPI_INTEGER1 1 MPI_LOGICAL8 8
MPI_INTEGER2 2 MPI_REAL4 4
MPI_INTEGER4 4 MPI_REAL8 8
MPI_INTEGER8 8 MPI_REAL16 16

C

Type Length (bytes) Type Length (bytes)
MPI_CHAR 1 MPI_SHORT 2
MPI_DOUBLE 8 MPI_SIGNED_CHAR 1
MPI_FLOAT 4 MPI_UNSIGNED 4
MPI_INT 4 MPI_UNSIGNED_CHAR 1
MPI_LONG 4 MPI_UNSIGNED_LONG 4
MPI_LONG_DOUBLE 8 MPI_UNSIGNED_LONG_LONG 8
MPI_LONG_LONG 8 MPI_UNSIGNED_SHORT 2
MPI_LONG_LONG_INT 8 MPI_WCHAR 2


next up previous
Next: Batch Processing Up: User's Guide to the Previous: File Management
Andrew Turner
2010-01-14