This section provides some helpful information on porting codes to the IBM p690 Regatta system.
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 |
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.
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
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 */
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 */
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 |
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.
The default sizes of MPI datatypes are different on the different machines:
| 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 |
| 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 |