Chapter 3. Utilizing Power Fortran Output

This chapter contains the following sections:

Overview of Output Files

Power Fortran can generate three types of output files:

  • listing file (.l)

  • transformed Fortran source file (.m) that contains the original source program with the multiprocessing directives inserted by Power Fortran

  • an input file for use with WorkShop Pro MPF (.anl)

When you specify the list argument to –pfa, Power Fortran produces a line-numbered listing file. If you specify the keep argument instead, Power Fortran produces the numbered listing file, transformed Fortran source file, and the WorkShop Pro MPF file. (For details about invoking Power Fortran, refer to Chapter 2, “How to Use Power Fortran.”)

For example, consider the following code segment, sample.f:

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

Compiling sample.f as follows

% f77 -pfa list -c sample.f

generates the following listing file, sample.l:

Footnotes Actions   Do Loops Line
          DIR                  1  # 1  "sample.f"
                               2       subroutine sample(a,b,c)
                               3       dimension  a(1000),b(1000),c(1000)
          SO C      +--------  4       do 10 i = 1,1000
          SO        *_______   5  10   a (i) = b(i) + c(i)
                               6       end
Abbreviations Used
   SO     scalar optimization
   DIR    directive
   C      concurrentized
Loop Summary
       From  To    Loop     Loop    at
Loop#  line  line  label    index   nest   Status
1      4     5     Do 10    I       1      concurrentized

Power Fortran placed a C before the first statement of the DO loop in the listing file, sample.l. The Abbreviations Used table shows that C stands for “concurrentized,” which means that Power Fortran determined that it can safely run the loop in parallel. The Loop Summary table at the bottom of sample.l shows that the status of the loop is concurrentized.


Note: The first line number directive appears in the listing because it was actually added by cpp before Power Fortran ran.


Formatting the Listing File

You can customize a Power Fortran listing file by

  • paginating the listing

  • selecting the information to be printed

  • disabling specific message classes

Paginating the Listing

The –lines=n option (or –ln=n) paginates the listing for printing. Use this option to change the number of lines per page. Specifying –lines=0 paginates at subroutine boundaries.

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

Specifying Information to Include

The –listoptions=list option (or –lo=list) specifies the information to include in the listing file (.l), where list is any combination of the options in Table 3-1. The default is –listoptions=ol.

Table 3-1. Listing File Include Options

Value

Produces

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 f77 –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.f with Power Fortran and includes an annotated listing of the original program and a summary of the optimizations performed in the listing file:

% f77 -pfa -pfa,-listoptions=ls source.f

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 (.l) file. These messages range from syntax warnings and error messages to messages about the optimizations performed. list is any combination of the options in Table 3-2.

Table 3-2. 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.

Interpreting Default Listing Information

Knowing when and where to modify your code means understanding the information in the Power Fortran listing. This understanding allows you to recognize where small changes to the source code will make a big difference in how much code is run in parallel. The listing file generated by Power Fortran lists the optimizations Power Fortran made to the code. 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.

This section explains how to view the listing file online and then lists and describes the various fields.

Viewing the Listing File

The listing file is in 132-column format. To view the file, open a window with 132 columns and 40 rows by entering

% wsh -s132,40

Field Descriptions

This section explains the contents of the listing file when you use the default values for the –listoptions command-line option (that is, o and l).

A default Power Fortran listing file includes

  • line numbers

  • DO loop markings

  • footnotes

  • syntax errors/warning messages

  • action summary

Line Numbers

In the listing transformed by Power Fortran, a statement labeled with a line number, such as 21, is the same as line 21 from the original program or has been derived from that line. These 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 new line of code is labeled with the same number as the line of the original program from which it was generated. Consequently, many lines of the transformed program listing carry the same number because they are related to one line of the original program listing.

DO Loop Marking

The listing file displays DO loops graphically in a column headed DO Loops. Power Fortran surrounds each DO loop (up to nest level 10) with a loop delimiter character. The delimiters form brackets around each loop nest level. Each character listed in Table 3-3 has a specific meaning.

Table 3-3. Listing File DO Loop Delimiters

Character

Denotes

|

Generic DO loop

*

Power Fortran can run loop in parallel

!

Syntax error

A statement contained within n DO loops has n of these loop delimiters on that line. For example, the following statements are contained within one DO loop and therefore have only one |:

DO Loops  Line
+-------  173      DO 100 M=2,MAX(MFLD,2)
|         174      IADR = ISECT(M)
|         175      IADR1= ISECT(M-1)
|         176      PNM(IADR)=(ANM(IADR) *PNM(IADR1))
|_______  177 100  PPNM(IADR)= -(ANM(IADR) *PNM(IADR1))

Footnotes

Power Fortran uses the footnotes listing to give important details concerning its actions. Power Fortran numbers and prints the footnotes at the bottom of each program unit under the Footnote List heading. References to the footnotes are displayed in the listing under the Footnotes column. For example, this footnote

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

appears under Footnote List at the end of the program unit

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 Power Fortran action, and the IF statement on line 1790 refers to the original source line number.

Syntax Errors/Warning Messages

When a program has syntax errors, the listing file describes the error next to the lines that start with the symbol ### in the Footnotes column. These messages are also printed to stderr, which is usually your terminal.

For example:

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

Action Summary

When Power Fortran translates or modifies a statement, it uses abbreviations in the Actions column of the listing file to identify the statements. Power Fortran lists an abbreviated explanation of its actions at the bottom of the listing. For the DIR and V classes, the class itself serves as the message without detailed messages. All other classes have associated messages.

Table 3-4 lists and explains the values that can appear in the Actions column.

Table 3-4. Power Fortran Action Abbreviations

Value

Meaning

DD

(Data Dependence) Indicates that data dependence prevented Power Fortran from running this statement in parallel.

DIR

(Directive) Used in conjunction with the footnotes and concerns compiler directives. If you code a compiler directive and that line does not have the DIR abbreviation in the listing, Power Fortran will not recognize the directive. Check the setting of the –directives command-line option and the syntax of the directive.

E

(Error) Indicates syntax errors. These messages can refer to missing or extra characters, illegal keywords, or text placed in the wrong column. Power Fortran cannot do anything with such code. The equivalent transformed source file (.m) contains a copy of this program unit that Power Fortran has not modified.

EX

(Extension) Shows where a construct in the original program is not allowed in the language Power Fortran produces. In some cases, an operation or type is allowed in the input language but not in the output language.

INF

(Information) Provides noncritical information.

I

(Insertion) Indicates that Power Fortran added a statement.

LR

(Loop Reordering) Indicates that Power Fortran has modified a Fortran 77 statement in the process of interchanging loops. If during optimization Power Fortran ascertains that an outer loop would be more efficient as an inner loop, and it can legally reorder the loops, Power Fortran places the outer loop inside. In the process of this reordering, Power Fortran might have to change loop bounds (for triangular loops), distribute loops, or float IF assignments. Only the statements modified for the exchange are marked.

MIS

(Miscellaneous) Indicates that some Power Fortran information has been lost. This message does not always mean that something is wrong with the program.

NX

(Nonconcurrent Statement) Indicates that Power Fortran did not try or was unable to run the statement in parallel. For example, when a subroutine call is involved in a loop, Power Fortran generates this message.

NO

(Program Too Large—Not Optimized) Indicates that the program unit being processed is too large for Power Fortran to optimize, because of Power Fortran data structure size limitations. When Power Fortran optimizes programs, it adds statements that might also overflow the fixed-size tables. In either case, Power Fortran stops optimization and passes the original program to the equivalent transformed source file (.m), informing you of this action. For Power Fortran to process the unit, you must split the program into smaller sections.

OE

(Option Error) Indicates a syntax error in a Power Fortran option. This error does not stop the processing of a program unit.

OTF

(Output Translation Failure) Marks statements that have constructs that exist in the input language but that cannot be represented in the output language.

Q

(Question) Indicates that Power Fortran tried to optimize a loop nest but discovered a data dependence it could not break at compile time without further information. You can usually answer this question with an appropriate assertion.

SO

(Scalar Optimization) Marks places in the transformed listing where Power Fortran has optimized a scalar loop.

STD

(Standardized) Marks where Power Fortran changed a program to improve the chance of finding code that it can optimize. This is often a conversion from an IF/GOTO into a block IF, loop rerolling, and conversion of an IF loop into a DO loop.

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 sort of bug (so it can be corrected) and, if possible, send Silicon Graphics the code that caused the trace back as well as the trace back itself. If you can reproduce the error in a small program unit, send that small program unit as well.

W

(Warning) Contains syntax warnings.


Sample Listing Files

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

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

when submitted to Power Fortran, produces this listing file:

Footnotes  Actions     DO Loops   Line
           DIR                    1  # 1 "foo2.f"
                                  1    subroutine foo2(a,b,index,n)
                                  2    real a(n), b(n)
                                  3    integer index(n)
                                  4
1          Q SO        +-------   5    do i = 1, n
2          DD SO       !          6       a(index(i)) = a(index(i)) + b(i)
                       !_______   7    enddo
                                  8    end
Abbreviations Used
 DD       data dependence
 Q        question
 SO       scalar optimization
 DIR      directive
Footnote List
 1: question           Is “INDEX” a permutation vector?
 2: data dependence    Data dependence involving this line due to variable A.
Loop Summary
       From   To     Loop     Loop    at
loop#  line   line   label    index   nest   Status
1      6      8      Do       I       1      scalar mode preferable

DD in the Actions column on line 6 of the listing 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 of index(i) are ever the same for different values of i, then different iterations might use the same location in a. Therefore, this code contains a possible data dependence.

If you can guarantee that the values of index(i) are always different for each value of i, then there is no dependence (each iteration uses a different location in a). Question one on the Footnote List asks if index(i) is different for every value of i. A permutation vector is a list of numbers, each of which is different from the others. If you know that index is a permutation vector, then the loop is data-independent. An example of a permutation vector is a list of objects in which each object appears exactly once.

Explicitly state that index is a permutation vector by adding an assertion in the source.

Example 3-1. Indirect Indexing


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

Now the listing file shows that Power Fortran finds the loop safe to run in parallel (indicated by the * DO loop delimiter):

Footnotes  Actions     DO Loops   Line
           DIR                    1  # 1 "foo2.f"
                                  1    subroutine foo2(a,b,index,n)
                                  2    real a(n), b(n)
                                  3    integer index(n)
           DIR                    4  c*$*assert permutation (index)
                                  5
1          SO C        +-------   6    do i = 1, n
2          SO          *          7       a(index(i)) = a(index(i)) + b(i)
                       *_______   8    enddo
                                  9    end
Abbreviations Used
 SO    scalar optimization
 DIR   directive
 C     concurrentized
Loop Summary
       From   To     Loop     Loop    at
loop#  line   line   label    index   nest   Status
1      7      9      Do       I       1      concurrentized


Note: As with all assertions, Power Fortran does not verify the truth of this assertion. When you make an assertion, be certain that it is always true for all possible input data.


Function Call

This example shows what happens when a loop contains a call to an external routine. The Fortran 77 code

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

generates this listing:

Footnotes  Actions     DO Loops   Line
           DIR                    1  # 1 "foo3.f"
                                  1    subroutine foo3(a,b,c,n)
                                  2    real a(n), b(n), c(n)
                                  3    external force
                                  4
1 2        NO SO NCS   +------    5    do i = 1,n
3          NO SO NCS   !          6       a(i) = force (b(i), c(i))
                       !______    7    enddo
                                  8    end
Abbreviations Used
 NO    not optimized
 SO    scalar optimization
 DIR   directive
 NCS   non-concurrent-stmt
Footnote List
  1: not optimized       No optimizable statements found.
  2: not optimized        This loop contains an unoptimizable call to “FORCE”.
  3: not optimized       This statement contains an unoptimizable call to “FORCE”.
Loop Summary
        From   To     Loop    Loop    at
Loop#   line   line   label   index   nest     Status
1       6      8      Do      I       1        unoptimizable call (FORCE)

Calling the function force prevents Power Fortran from automatically running the loop in parallel. Power Fortran identifies the function call as a non-concurrent-stmt. By its nature, a nonconcurrent statement prevents Power Fortran from assuming the loop is safe to run in parallel because Power Fortran cannot see into the routine to look for data dependencies.

If you know that force generates no data dependencies, then explicitly state this fact for the nonconcurrent statement.

Example 3-2. Concurrent Function Call


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

Now that Power Fortran knows that the nonconcurrent statement involves no data dependency, Power Fortran will find the loop safe to run in parallel.

There is one subtlety in using the concurrent call assertion. When you use this assertion, Power Fortran makes no attempt to examine the called routine; it simply assumes that it is safe. However, Power Fortran is still left with the problem of correctly declaring the variables in the loop to be either SHARE or LOCAL. (Power Fortran does the best it can, but it can sometimes be fooled.) For example:

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

The question is whether the variable m should be SHARE or LOCAL. If the routine my_function reads only the old value of m, then it should be SHARE. If my_function writes a new value of m, then it should be LOCAL. In the absence of any more clues, Power Fortran must go by what it can see; and what it can see is that within the loop, there are no visible assignments to m, and so Power Fortran will declare it to be SHARE. If in fact my_function is writing the value of m, then this is incorrect.

In this case, to give Power Fortran the hint it needs, add a visible assignment to m at the top of the loop. For example, consider the following code:

do i = 1, n
m = 0
a(i) = my_function(b(i), m)
b(i) = a(i) + m
enddo

Here, Power Fortran can see an assignment to m and so declares it to be LOCAL. Note that if my_function is both reading the old value and writing a new value of m, then it was not legal to parallelize the loop.

Reductions

This example shows how Power Fortran produces a single value from a set of values. Because the entire set of values is reduced to a single value, these operations are called reductions. Consider the following Fortran 77 code.

Example 3-3. Roundoff Reduction


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

Using the previous code as input, Power Fortran produces this listing file:

Footnotes  Actions     DO Loops   Line
           DIR                    1  # 1 "foo3.f"
                                  1      subroutine foo4(a,b,n,sum)
                                  2      real a(n), b(n), sum
                                  3
           SO                     4      sum = 0.0
           SO           +-----    5      do i = i, n
1          DD SO        !         6         sum = sum + a(i)*b(i)
                        !_____    7      enddo
                                  8      end
Abbreviations Used
 DD        data dependence
 SO        scalar optimization
 DIR       directive
Footnote List
1: data dependence       Data dependence involving this
                         line due to variable “SUM”.
Loop Summary
       From  To    Loop   Loop    at
Loop#  line  line  label  index   nest    Status
1      6     8     Do     I       1       scalar mode preferable

Because different iterations of the loop read and write the same location (the variable sum), there is a dependence. However, this is a special case. Because sum just accumulates a total, you can accumulate subtotals in parallel and then combine the subtotals at the end.

Because the parallel version of the code adds the elements together in an order different from the single-process version, the round-off errors accumulate differently for the two versions of the code. Thus, the answer can differ slightly as you vary the number of processes used to run the code. In fact, if you use the dynamic scheduling option for the code, 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 you do not care about this round-off error, tell Power Fortran to use parallel subtotals. To tell Power Fortran not to worry about round-off error, use either the C*$*ROUNDOFF(2) directive or the f77 command-line option –pfa,–roundoff=2. The resulting listing file is

Footnotes  Actions     DO Loops   Line
           DIR                    1  # 1 "foo3.f"
                                  1      subroutine foo4(a,b,n,sum)
                                  2      real a(n), b(n), sum
                                  3
           SO                     4      sum = 0.0
           SO C         +-----    5      do i = i, n
           SO           *         6         sum = sum + a(i)*b(i)
                        *_____    7      enddo
                                  8      end
Abbreviations Used
 SO        scalar optimization
 DIR       directive
 C         concurrentized
Footnote List
1: data dependence       Data dependence involving this
                         line due to variable “SUM”.
Loop Summary
       From  To    Loop   Loop    at
Loop#  line  line  label  index   nest    Status
1      6     8     Do     I       1       concurrentized

Be aware that the round-off error produced by the parallel reduction operation is not necessarily any worse than the round-off error already present in the original serial version. It is simply different. If your application did not worry about the round-off error in the original, there is no reason to suppose that it should worry about it in the parallel version. If, on the other hand, 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.