The following code is intended to illustrate possible failure when a processor receives a subnormal number, but may not itself (by default) handle such numbers.
The example constructs a one by two grid with process identifiers (0,0) and (0,1), and assumes that process (0,0) is running on a processor that generates IEEE subnormal numbers. For (possible) failure to occur process (0,1) should be running on a processor that does not support subnormal numbers.
We have observed failure when (0,0) is running on a Sun4 (which handles subnormal numbers correctly), and process (0,1) is running on a DEC Alpha under Unix, which by default flushes subnormal numbers to zero. (The non-default compiler flag -fpe1 will trap to software emulation.)
The program utilizes the BLACS. See [&make_named_href('', "node12.html#DW:UTK-cs:95","[8]")] for further details on the BLACS.
PROGRAM SUBNRM * * .. Local Scalars .. INTEGER IAM, ICNTXT, MYCOL, MYROW, NPCOL, NPROCS, NPROW REAL TWO * .. Local Arrays .. REAL X( 1 ) * .. External Subroutines .. EXTERNAL BLACS_EXIT, BLACS_GET, BLACS_GRIDINFO, $ BLACS_GRIDINIT, BLACS_PINFO, BLACS_SETUP, $ SGERV2D, SGESD2D * .. * * Determine my process number and the number of processes in * machine * * .. Executable Statements .. CALL BLACS_PINFO( IAM, NPROCS ) * * If underlying system needs additional setup, do it now * IF( NPROCS.LT.1 ) THEN IF( IAM.EQ.0 ) THEN NPROCS = 2 END IF CALL BLACS_SETUP( IAM, NPROCS ) END IF * * Set up a 1 by 2 process grid * NPROW = 1 NPCOL = 2 * * Get default system context, and initialize the grid * CALL BLACS_GET( 0, 0, ICNTXT ) CALL BLACS_GRIDINIT( ICNTXT, 'Row-major', NPROW, NPCOL ) CALL BLACS_GRIDINFO( ICNTXT, NPROW, NPCOL, MYROW, MYCOL ) * * If I am in the grid perform some computation * IF( MYROW.GE.0 .AND. MYROW.LT.NPROW ) THEN * TWO = 2.0E+0 IF( MYROW.EQ.0 .AND. MYCOL.EQ.0 ) THEN X( 1 ) = 7.52316390E-37 X( 1 ) = X( 1 ) / 128.0E+0 * X(1) = 0.58774718E-38, which is subnormal on IEEE machines * * This call to SGESD2D sends X(1) to process (0,1) CALL SGESD2D( ICNTXT, 1, 1, X, 1, 0, 1 ) WRITE( *, FMT = '(A,E16.8)' )'X00 = ', X( 1 ) X( 1 ) = X( 1 ) / TWO WRITE( *, FMT = '(A,E16.8)' )'X00 / 2 = ', X( 1 ) * ELSE IF( MYROW.EQ.0 .AND. MYCOL.EQ.1 ) THEN * * This call to SGERV2D receives X(1) from process (0,0) CALL SGERV2D( ICNTXT, 1, 1, X, 1, 0, 0 ) WRITE( *, FMT = '(A,E16.8)' )'X01 = ', X( 1 ) X( 1 ) = X( 1 ) / TWO WRITE( *, FMT = '(A,E16.8)' )'X01 / 2 = ', X( 1 ) * END IF END IF * * Exit the BLACS cleanly * CALL BLACS_EXIT( 0 ) * STOP END