Chapter 2. Using Listing and Temporary Files

This chapter has the following major topics:

Selecting Files to Generate

Power Fortran generates the types of output files shown in Table 2-1.

Table 2-1. Output Files

File Contents

Suffix

Driver Option Required

Listing of program structure and message

.L

-pfalist or -pfakeep

Transformed Fortran source file

.m

-pfakeep

Input file for WorkShop Pro MPF

.anl

-pfakeep

Suppose that the file sample.f90 contains the tiny subroutine in Example 2-1.

Example 2-1. Contents of File sample.f90


subroutine sample (a,b,c)
   dimension a(1000),b(1000),c(1000)
   do i = 1, 1000
       a(i) = b(i) + c(i)
   end do
end

When sample.f is compiled using the following command:

f90 -64 -pfakeep -c sample.f

the output includes the following files:

  • sample.L contains the listing file

  • sample.m contains the transformed source

  • sample.anl contains the WorkShop Pro input file

Using the Transformed Source File

The transformed source file contains the original source lines plus parallel-execution directives generated by Power Fortran. The sample.m file produced from Example 2-1 contains the lines shown in Example 2-2.

Example 2-2. Transformed Source File


C     KAP/SGI_F90 MP        00.00 k240000 190195o5r0so3  20-Jun-1995 14:54:32
# 1 "pfa1.f90"
      subroutine SAMPLE ( A, B, C )
       integer I
       real A(1000), B(1000), C(1000)
C$PAR parallel shared (A,B,C) local (I)
CSGI$ startloop 3
C$PAR pdo
       do 2 I=1,1000
        A(I) = B(I) + C(I)
    2   continue
C$PAR end pdo nowait
CSGI$ endloop 3
C$PAR end parallel
      end

The transformed file contains numerous generated directives. These directives, such as C$PAR, direct the parallel execution of the compiled program. Many of these directives are documented in the MIPSpro Fortran 90 Programmer's Guide (for example, C$PAR is a PCF directive that marks the start and end of a parallel work unit). However, some directives are not intended for general use and are not documented (for example, C$SGI is not documented).

You use the transformed source file for information only. The transformed source uses fixed format and loops in the Fortran 77 style, instead of the Fortran 90 syntax. As a result, it might not compile correctly if your were to change its suffix to .f90 and compile it.

Using the Workshop Pro MPF File

The WorkShop Pro MPF Parallel Analyzer View cvpav helps you understand the structure and operation of parallelized applications by providing an interactive, visual comparison of their original source with transformed, parallelized code. The Parallel Analyzer View reads the .anl analysis files generated by Power Fortran and displays editable parameters for each DO loop. These parameters are easily customized and explored with the help of the Parallel Analyzer View's user-friendly graphical interface.

A sample of a .anl file is shown in Example 2-3.

Example 2-3. Workshop Pro MPF Analysis File


product "KAP/SGI_F90 MP                          "
version "00.00 k240000 190195"
routine "SAMPLE" line 2 - 7
begin_orig_loop_section "SAMPLE"
orig_loop 1 "SAMPLE" do nest 1 range 4 - 6
 index "I"
loop_option 1 optimize 5
loop_option 1 roundoff 0
loop_option 1 scalar_optimize 3
loop_option 1 limit 20000
loop_option 1 arc_limit 5000
loop_option 1 minconcurrent 1000
loop_option 1 unroll 4
loop_option 1 unroll_weight 100
loop_option 1 max_invariant_if_growth 500
loop_option 1 each_invariant_if_growth 20
variable_list 1 "C":r , "B":r , "A": w, "I":rw
end_orig_loop 1
end_orig_loop_section "SAMPLE"
begin_transformed_loop_section "SAMPLE"
transformed_loop 3 1 "SAMPLE" ordinary
workload 5
schedtype simple "Default"
mode parallel
nest 1
line_range 4 - 6
end_transformed_loop 3 "SAMPLE"
end_transformed_loop_section "SAMPLE"
begin_vln
file_name 1 "pfa1.f90"
vln_translation 1  1  1
vln_translation 1  2  1
end_vln

Controlling the Power Fortran Listing File

The Power Fortran listing file shows the input source statements and how Power Fortran treated them. It is your primary tool for judging the effect of parallelization, and for discovering how to make Power Fortran more effective. The listing file produced by Example 2-1 is shown in Example 2-4.

Example 2-4. Generated Listing File


 Footnotes     Actions        DO Loops    Line

               DIR                           1   # 1 "pfa1.f90"
                                             1   subroutine sample (a,b,c)
                                             2   dimension a(1000),b(1000),c(1000
               C              +---------     3   do i = 1, 1000
                              *              4     a(i) = b(i) + c(i)
                              *_________     5   end do
                                             6   end
 Abbreviations Used
  DIR      directive 
  C        concurrentized 

     Loop Summary
              From    To      Loop       Loop       at
      Loop#   line    line    label      index      nest    Status
      1       3       5       Do         I          1       concurrentized

The page-heading lines and some blank lines have been deleted from Example 2-4. The output in Example 2-4 is the result of using default listing options. A listing with more details is shown under “Interpreting the Listing”.


Note: The first line 1, containing a number directive, was actually added by cpp. The source file passes through cpp prior to Power Fortran.


Paginating the Listing

The driver option –lines=n (or –ln=n) paginates the listing at n lines per page. When you specify –lines=0, the listing is paginated at subroutine boundaries.

If you do not specify the –lines option, Power Fortran writes 55 lines per page.

Specifying Optional Information

The driver option –listoptions=list option (or –lo=list) specifies the information to include in the listing file. The list is any combination of the option letters in Table 2-2. The default is –listoptions=ol.

Table 2-2. Listing File Include Options

Letter

Controls This Information

c

Calling tree at the end of the program listing.

i

Transformed program file annotated with line numbers in the source program. Error messages and debugging information can refer to the original source rather than the transformed source. This argument is specified by default.

k

List of the Power Fortran options used at the end of each program unit.

l

Loop-by-loop optimization table.

n

Program unit names, as processed, to the standard error file. This option is added automatically as part of an f90 –v compilation.

o

Annotated listing of the original program.

p

Processing performance statistics.

s

Summary of optimizations performed.

t

Annotated listing of the transformed program.

The following command compiles the program source.f90 with Power Fortran and includes an annotated listing of the original program and a summary of the optimizations performed in the listing file:

% f90 -pfa -lo=ls source.f90

Disabling Message Classes

Use the –suppress=list option (or –su=list) to disable individual classes of Power Fortran messages that are normally included in the listing. These messages range from syntax warnings and error messages to messages about the optimizations performed. list is any combination of the option letters summarized in Table 2-3.

Table 2-3. Listing File Message Disabling Options

Value

Message Class Disabled

d

Data dependence

e

Syntax error

i

Information

n

Unable to run loop in parallel

q

Questions

s

Standard messages

w

Warning of syntax error (Power Fortran adds the –suppress=w option automatically if you use the –w option to f77)

If you do not specify this option, Power Fortran prints messages of all classes.

Viewing the Listing File

The listing file is in 132-column format. To view the file, open a window with 132 columns and the number of rows in a page by entering an xwsh command with specific geometry.

% xwsh -geometry 132x55

Optionally you can include a font specification in order to reduce the size of the window while retaining readability.

% xwsh -fn "-*-screen-medium-r-normal--12" -geometry 132x40

When you want to display the listing file from a shell script or makefile, you can consider other options described in the xwsh(1) reference page. The command fragments in Example 2-5 might appear in a shell script. This xwsh starts up quickly because it does not open a shell. The user browses the listing using the xwsh scroll buffer, whose size is set to 5000 lines in order to accommodate large listings.

Example 2-5. Use of xwsh From a Shell Script


f90 ... -pfalist -lines=40 ... -c $FILENAME.f90
xwsh -fn "-*-screen-medium-r-normal--12" \
     -geometry 132x40 \
     -sl 5000 \
     -title "$FILENAME listing" \
     -nokeyboard -nomenu -hold \
     -e cat $FILENAME.L

Interpreting the Listing

The listing file generated by Power Fortran lists the changes Power Fortran made to the code, and shows where and why the code was not changed. For example, a message could say that, although three loops could have run in parallel, Power Fortran converted only the one it determined most profitable. When you understand the information in the Power Fortran listing, you can recognize where small changes to the source code will make a difference in which code is run in parallel.

Default Listing Fields

Any Power Fortran listing that includes the includes the default list options o and l (as described under “Specifying Optional Information”) contains the following fields:

  • source lines with line numbers

  • DO loop annotations

  • action summary

  • footnotes

  • syntax errors/warning messages

The listing fragment in Example 2-6 illustrates these fields.

Example 2-6. Listing Fragment Showing Common Fields


Footnotes  Actions       DO Loops    Line
                                       16
                                        17   integer,parameter::adim = 1000
                                        18   real ra(adim),rb(adim),rc(adim)
                                        19
                                        20   ! load the arrays -- suboptimal i/o for example
                                        21      open (unit=11,action="READ",file="pfa1.data")
 1        NO NCS         +---------     22      do i = 1,adim
 2        NO NCS         !              23         read (unit=11,fmt="2E15.8") ra(i),rb(i)
                         !_________     24      end do
                                        25
                                        26   ! swizzle the contents
                                        27   ! function has no side-effects
          DIR                           28   !*$* ASSERT CONCURRENT CALL
          C              +---------     29      do i = 1,adim
                         *              30         rc(i) = swizzle(ra(i),rb(i))
                         *_________     31      end do
                                        32
                                        33   ! un-swizzle in subroutine
                                        34      call subber(ra,rb,rc)
                                        35
                                        36   end
 Abbreviations Used
  NO       not optimized           
  DIR      directive               
  NCS      non-concurrent-stmt     
  C        concurrentized          
 Footnote List
   1: not optimized   This loop contains unoptimizable input or output statements.
   2: not optimized   This input or output statement inhibits loop optimization. 

Line Numbers

A statement in the listing with a line number, such as 21, is either that line from the original source file, or else it is derived from that line. Line numbers are useful when inspecting the transformed program listing and when debugging.

Power Fortran sometimes generates several lines of code from a single line of the original program. In this case, each generated line is labeled with the same number as the line of the original source from which it was generated.

DO Loop Marking

The listing displays the boundaries of DO loops graphically in the column headed “DO Loops.” Power Fortran surrounds each loop (up to a nesting level of 10) with a loop delimiter character. The delimiters form brackets around each loop nest level. The delimiter characters are listed in Table 2-4.

Table 2-4. Listing File DO Loop Delimiters

Character

Denotes

|

Generic DO loop

*

Power Fortran can run loop in parallel

!

Problem preventing optimization

A statement contained within n DO loops has n of these loop delimiters on that line. You can use the delimiters to trace the extent of each loop, and to quickly learn which loops were parallelized.

Action Summary

When Power Fortran translates or modifies a statement, it places abbreviations in the “Actions” column of the listing to explain what was done to that statement. The abbreviations used in this column are expanded at the bottom of each page. Table 2-5 lists and explains the values that can appear in the Actions column.

Table 2-5. (Continued) Power Fortran Action Abbreviations

Value

Meaning

C

Concurrentized: This statement will execute on multiple CPUs.

DD

Data Dependence: Data dependence prevents Power Fortran from running this statement in parallel.

DEL

Deleted: ?

DIR

Directive: This statement recognized as a directive. If you code a directive and that line does not have the DIR abbreviation, Power Fortran did not recognize the directive. Check the setting of the –directives driver option and the syntax of the directive.

E

Error: Error found in this statement. The message can refer to missing or extra characters, illegal keywords, or text placed in the wrong column. The transformed source file (.m) contains an unmodified copy of this line.

EX

Extension: A construct in the original program is a Fortran language extension not supported in the language that Power Fortran generates..

I

Inserted statement.

INF

Information message. See the related listing footnote..

INL

Inlined: Statement inserted in the inlining process.

IPA

Interprocedural analysis: Statement inserted or modified during inlining or IPA.

LM

Label modification: Loop target label generated or modified.

LR

Loop Reordering: This DO statement has been moved in an nterchange with a nested or containing loop.

MIS

Miscellaneous: Unspecific message. This message does not always mean that something is wrong with the program.

NC
NCS

Not Concurrentized: this statement could not be made concurrent for the reason shown in another code.

NO

Not Optimized: some Power Fortran internal data structure or table has overflowed. To process this source, you must split the file into smaller sections.

NT
NTS

Not Tiled: This statement could not be optimized for cache performance.

NV
NVS

Not Vectorized: This statement could not be optimized for vector performance.

OE

Option Error: An error detected in Power Fortran driver option. This error does not stop processing of a program unit.

OPT

Optimized: This statement modified by scalar optimization.

OT
OTF

Output Translation Failure: This statement cannot be represented in the Fortran language generated by Power Fortran.

OW

Option Warning: A questionable condition detected in a Power Fortran driver option.

Q

Question: This statement cannot be optimized unless more information is given. The question is given in a footnote line. You can usually answer this question with an appropriate assertion.

SC
SO

Scalar Optimization: This statement modified by scalar optimization..

STD

Standardized: This statement was transformed into a standard Fortran form in order to improve the changes of being able to optimize it.

T

Tiled: This statement transformed to improve cache memory performance.

TE

Translator Error: Indicates an internal Power Fortran error. Power Fortran writes the notification to the standard error file and writes a trace back to the output file. Notify Silicon Graphics if you see this message.

TL

Too Large: The source program is too large; Power Fortran can only process it in smaller sections.

V

Vectorized: This statement modified for vector performance.

W

(Warning) Contains syntax warnings.


Footnotes

The “Footnotes” column gives details concerning the actions or nonactions taken. Power Fortran numbers and prints the footnotes at the bottom of each program unit under the Footnote List heading. For example, the following line from a listing contains the footnote number 13.

13     DD            1790     IF (B(I) .LE. 6) IB(J*I) = I+J

In the Footnote List displayed at the end of the program unit, the footnote appears.

13: data dependence Data dependence involving this line due
                         to variable IB.

In this example, 13 is the footnote number, DD (data dependence) is the explanation for the action (in this case, nonaction).

Syntax Errors/Warning Messages

When a program has errors, the listing contains the error text following the line in error. The same messages are printed to stderr during the compile. The following example displays a listing with an error.

Footnotes Actions   DO Loops   Line
                                 1      SUBROUTINE Z(A,B,N)
                                 2      REAL A(N), B(N)
                    +-------     3      DO 20 I=1,N
                    !            4      X=A(I)
                    !            5      Y=B(I)
                    ! ______     6   20 C(I)=X+Y
### line (6) 
### error    Array not declared or statement function declared 
             after executable statements.
### error    A do loop ends on a non-executable statement.
                                 7      PRINT *,X
                                 8      END

Sample Listings

This section contains a few simple examples of Fortran code and the corresponding Power Fortran output. An actual source program would be much larger, and a single loop could contain several of the cases illustrated here. However, even in a large loop, you can deal with each problem individually.

Indirect Indexing

Power Fortran cannot determine if it can run a loop in parallel when the code uses indirect indexing. A loop is indirectly indexed when it uses the value from some auxiliary array as the index value rather than the DO loop variable. The code in Example 2-7 illustrates indirect indexing.

Example 2-7. Loop With Indirect Indexing


subroutine indirex(a,b,index,n)
real a(n), b(n)
integer index(n)
   do i = 1, n
      a(index(i)) = a(index(i)) + b(i)
   end do
end

When Example 2-7 is submitted to Power Fortran, it produces the listing shown in Example 2-8.

Example 2-8. Listing of Loop With Indirect Indexing


Footnotes     Actions        DO Loops    Line

               DIR                            1   # 1 "pfa3.f90"
                                              1         subroutine INDIREX ( A, B, INDEX, N )
               I                              1          integer N, I
               I                              1          real A(N), B(N)
               I                              1          integer INDEX(N)
               I                              4   CSGI$ startloop 2
 1             Q              +---------      4          do   I=1,N
 2             DD             !               5           A(INDEX(I)) = A(INDEX(I)) + B(I)
                              !_________      6          end do
               I                              6   CSGI$ endloop 2
                                              7         end

 Abbreviations Used
  DD       data dependence         
  Q        question                
  I        inserted                
  DIR      directive               

 Footnote List
   1: question                   Is "INDEX" a permutation vector?
   2: data dependence            Data dependence involving this line due to variable "A".

DD in the Actions column for statement 6 warns that the variable A might carry a dependency. A dependency exists when one iteration of the loop writes to a location that is used by a different iteration of the loop. In this example, if the values in index are not unique, different iterations might write to the same element of A.

The question given in footnote 1 asks if index is a permutation of the integers 1..n. (Since all elements index(i) are used as subscripts of a, Power Fortran assumes they are all taken from the set 1..n; however only a permutation of 1..n contains no duplicate values.)

If you are sure that index is a permutation vector, there can be no data dependence between elements of A. You inform Power Fortran of this by adding an assertion, as shown in Example 2-9.

Example 2-9. Loop Asserting Indirect Indexing Through a Permutation


subroutine indirex(a,b,index,n)
real a(n), b(n)
integer index(n)
!*$* assert permutation (index)
   do i = 1, n
      a(index(i)) = a(index(i)) + b(i)
   end do
end

The listing in Example 2-10 shows that Power Fortran finds the loop safe to run in parallel.

Example 2-10. Listing of Loop With Asserted Permutation


 Footnotes     Actions        DO Loops    Line
               DIR                            1   # 1 "pfa3.f90"
                                              1         subroutine INDIREX ( A, B, INDEX, N )
               I                              1          integer N, I
               I                              1          real A(N), B(N)
               I                              1          integer INDEX(N)
               DIR                            4   C*$* assertpermutation ( INDEX )
               I                              5   C$PAR parallel if (N .gt. 142) shared (N,INDEX,A,B) local (I)
               I                              5   CSGI$ startloop 3
               I                              5   C$PAR pdo 
               LM I C         +---------      5          do 2 I=1,N
                              *               6           A(INDEX(I)) = A(INDEX(I)) + B(I)
               I              *_________      7       2   continue
               I                              7   C$PAR end pdo nowait
               I                              7   CSGI$ endloop 3
               I                              7   C$PAR end parallel 
                                              8         end
 Abbreviations Used
  LM       label modification      
  I        inserted                
  DIR      directive               
  C        concurrentized          


Note: Power Fortran cannot verify the truth of this, or any, assertion. When you make an assertion, it is up to you to be certain that it is true for all possible input data.


Function Call

The code in Example 2-11 contains a call to an external function.

Example 2-11. Loop With Call to External Function


subroutine caller(a,b,c,n)
   real a(n), b(n), c(n)
   external force
   do i = 1,n
      a(i) = force(b(i),c(i))
   end do
end

The Power Fortran listing for this code is shown in Example 2-12.

Example 2-12. Listing of Loop With External Call


 Footnotes     Actions        DO Loops    Line
               DIR                            1   # 1 "pfa4.f90"
                                              1   subroutine caller(a,b,c,n)
                                              2      real a(n), b(n), c(n)
                                              3      external force
 1             NO NCS         +---------      4      do i = 1,n 
 2             NO NCS         !               5         a(i) = force(b(i),c(i)) 
                              !_________      6      end do
                                              7   end
 Abbreviations Used
  NO       not optimized           
  DIR      directive               
  NCS      non-concurrent-stmt     
 Footnote List
   1: not optimized              This loop contains an unoptimizable call to "FORCE".
   2: not optimized              This statement contains an unoptimizable call to "FORCE".

Since Power Fortran cannot be sure that function force has no side-effects, it cannot parallelize this loop. If the function has a side-effect—that is, if it assigns data to variables other than its arguments and result—errors would occur when it was called concurrently from multiple CPUs.

If you know that a procedure has no side-effects, you can insert an assertion to tell Power Fortran, as shown in Example 2-13.

Example 2-13. Loop With Asserted Concurrent Call


subroutine caller(a,b,c,n)
   real a(n), b(n), c(n)
   external force
!*$*assert concurrent call
   do i = 1,n
      a(i) = force(b(i),c(i))
   end do
end

With this modification, Power Fortran parallelizes the loop as shown in Example 2-14.

Example 2-14. Listing of Loop With Asserted Concurrent Call


 Footnotes     Actions        DO Loops    Line
               DIR                            1   # 1 "pfa4.f90"
                                              1   subroutine caller(a,b,c,n)
                                              2      real a(n), b(n), c(n)
                                              3      external force
               DIR                            4   !*$*assert concurrent call
               C              +---------      5      do i = 1,n
                              *               6         a(i) = force(b(i),c(i))
                              *_________      7      end do
                                              8   end
 Abbreviations Used
  DIR      directive               
  C        concurrentized          

Procedure Parameters

There is a further subtlety in using procedure calls in parallelized loops. Power Fortran does not examine the code of the external function (unless you use the optimization of procedure inlining, discussed in the MIPSpro Fortran 90 Programmer's Guide). As a result, Power Fortran cannot know whether the external procedure modifies any of its arguments. Code with this ambiguity is shown in Example 2-15.

Example 2-15. Loop With Ambiguous Parameter


subroutine tricky (a,b,c,n,m)
   real a(*), b(*)
   external my_function
!*$*assert concurrent call
   do i = 1, n
      a(i) = my_function (b(i), m)
      b(i) = a(i) + m
   end do
end

The question is, does my_function modify its argument m? If it only reads m, there can be a single copy of m used by all concurrent instances of the loop. If the function assigns to m, each loop instance needs its own copy of the variable. These two modes, called SHARE and LOCAL respectively, are discussed in Chapter 7 of the MIPSpro Fortran 90 Programmer's Guide.

Given Example 2-15, Power Fortran assumes that m is read-only, and gives it SHARE status. This can be seen when the transformed program is included in the listing (-listoptions=loi), as shown in Example 2-16.

Example 2-16. Listing of Loop With Ambiguous Parameter


DIR                            4   C*$*  assertconcurrentcall 
I                              5   C$PAR parallel if (N .gt. 16) shared (N,A,B,M) local (I)
I                              5   CSGI$ startloop 3
I                              5   C$PAR pdo 
LM I C         +---------      5          do 2 I=1,N
               *               6           A(I) = real (MY_FUNCTION (B(I),M))
               *               7           B(I) = A(I) + real (M)
I              *_________      8       2   continue
I                              8   C$PAR end pdo nowait
I                              8   CSGI$ endloop 3
I                              8   C$PAR end parallel 

The C$PAR clause shared(N,A,B,M) in Example 2-16 specifies that single copies of those variables will be accessed concurrently from all instances of the concurrent loop. If in fact my_function changes the value of m, then this is incorrect. If this is the case, you can give Power Fortran the hint it needs by adding a visible assignment to m prior to the procedure call, as shown in Example 2-17.

Example 2-17. Loop With Apparent Assignment to Parameter


subroutine tricky (a,b,c,n,m)
   real a(*), b(*)
   external my_function
!*$*assert concurrent call
   do i = 1, n
      m = 0 ! force M to be LOCAL
      a(i) = my_function (b(i), m)
      b(i) = a(i) + m
   end do
end

Since Power Fortran sees an assignment to m within the loop, it declares m to be LOCAL (without regard to its use as a parameter). This is an example of how it is sometimes necessary to put extra statements in a loop in order to get the best speed from a parallel program.


Note: If my_function both reads the input value of m and writes a new value, the trick in Example 2-17 will not work. You would have to find an assignment to m that preserves its value in each iteration of the loop. Unfortunately, most such non-assignments, such as m=m*1, are likely to be deleted as unnecessary by the scalar optimization phase of Power Fortran!


Reductions

A reduction produces a single value from a set of values. The subroutine in Example 2-18 calculates the sum of products of two arrays.

Example 2-18. Sum of Products Reduction


subroutine sum_prods(a,b,n,sum)
   real a(n), b(n), sum
   sum = 0.0
   do i = 1,n
      sum = sum + a(i)*b(i)
   end do
end

With Example 2-18 as input, Power Fortran produces the listing in Example 2-19.

Example 2-19. Listing of Sum of Products Procedure


                                              1   subroutine sum_prods(a,b,n,sum)
                                              2      real a(n), b(n), sum
                                              3      sum = 0.0
                              +---------      4      do i = 1,n
 1             DD             !               5         sum = sum + a(i)*b(i)
                              !_________      6      end do
                                              7   end
 Abbreviations Used
  DD       data dependence         

Because different iterations of the loop read and write the variable sum, Power Fortran detects a dependence. However, reduction is a special kind of data dependence. Because sum only accumulates a total, you can accumulate subtotals in parallel and then combine the subtotals at the end. (This general technique for dealing with reduction is discussed in Chapter 7 of the MIPSpro Fortran 90 Programmer's Guide.)

In fact, Power Fortran can recognize the four most common reductions—sum, product, min and max—and parallelize them. It does not do this automatically because, since the parallel version of the code adds the elements together in a different order than the single-process version, the round-off errors can accumulate differently in a parallelized reduction, producing a different answer depending on the number of CPUs that execute the code. In fact, if you use the dynamic scheduling option, the answer might vary slightly from one run of the program to the next, even if you use the same number of processes on the same machine.

Most applications can safely ignore this variation in round-off error. If your application is not affected, you can direct Power Fortran to use parallel reduction using either the C*$* ROUNDOFF(2) directive or the driver option –WK,–roundoff=2. The resulting listing is shown in Example 2-20.

Example 2-20. Listing of Reduction With Roundoff Directive


               DIR                            1   # 1 "pfa6.f90"  
                                              1   subroutine sum_prods(a,b,n,sum)  
                                              2      real a(n), b(n), sum   
                                              3      sum = 0.0      
               DIR                            4   !*$*roundoff(2)    
               C              +---------      5      do i = 1,n    
               SO             *               6         sum = sum + a(i)*b(i) 
                              *_________      7      end do  
                                              8   end  
 Abbreviations Used
  SO       scalar optimization     
  DIR      directive               
  C        concurrentized          

The round-off error produced by a parallel reduction operation is not necessarily worse than the round-off error seen in the serial version. It is simply different. If your original application was not affected by round-off error, there is no reason to worry about it in the parallel version. However, if your application takes special steps to reduce round off (for example, adding the numbers together in order from smallest absolute value to largest), then you should not use parallel reductions.

Table 2-6 shows the types of reductions Power Fortran supports.

Table 2-6. Power Fortran Reductions

Type

Operator

Example

Sum

+

sum = sum + expression

Product

*

prod = prod * expression

Min

min( )

least = min(least, expression)

Max

max( )

most = max(most, expression)

All these reductions are under the control of the –roundoff driver option and C*$*ROUNDOFF directive, even though technically the min and max reductions do not involve round-off problems.