DIGITAL Fortran 90
User Manual for
DIGITAL UNIX Systems


Previous Contents Index

C.3 Compilation Summary Section

The final entries on the compiler listing are the compiler options and compiler statistics.

The options shown include the ones specified on the f90 command line and the ones in effect as defaults during the compilation. The compiler statistics are the machine resources used by the compiler.

Example C-3 shows how compiler options and command-line options and compilation statistics appear on the listing.

Example C-3 Sample Compilation Summary

 
COMPILER OPTIONS BEING USED 
 
  no   -align commons                   no   -align dcommons 
       -align records                   no   -align rec1byte 
  no   -align rec2byte                  no   -align rec4byte 
  no   -align rec8byte                       -altparam 
       -arch generic                         -assume accuracy_sensitive 
  no   -assume bigarrays                no   -assume byterecl 
  no   -assume dummy_aliases            no   -assume minus0 
       -assume underscore                    -assume source_include 
       -assume zsize                    no   -automatic 
       -call_shared                     no   -check bounds 
  no   -check format                    no   -check omp_bindings 
  no   -check output_conversion         no   -check overflow 
       -check power                     no   -check underflow 
       -convert native                       -double_size 64 
  no   -d_lines                              -error_limit 30 
  no   -extend_source                   no   -f66 
  no   -fpconstant                           -fpe0 
       -fprm nearest                         -free 
       -g1                                   -granularity quadword 
  no   -hpf_matmul                      no   -intconstant 
       -integer_size 32                 no   -ladebug 
       -machine_code                         -math_library accurate 
  no   -module                               -names lowercase 
       -nearest_neighbor                no   -nowsf_main 
  no   -non_shared                      no   -noinclude 
       -numnodes 0                           -O4 
 
       -inline speed                    no   -transform_loops 
  no   -pipeline                             -speculate none 
       -tune generic                         -unroll 0 
  no   -pad_source                           -parallel manual 
  no   -pg                                   -real_size 32 
  no   -recursive                            -reentrancy none 
       -shadow_width 0                  no   -shared 
  no   -show include                         -show map 
  no   -show wsfinfo                    no   -show hpf_all 
  no   -show hpf_punt                   no   -show hpf_nearest 
  no   -show hpf_comm                   no   -show hpf_temps 
  no   -show hpf_indep                  no   -show hpf_dev 
  no   -show hpf_default                no   -std 
  no   -synchronous_exceptions          no   -syntax_only 
  no   -vms                                  -warn alignments 
  no   -warn argument_checking          no   -warn declarations 
       -warn general                         -warn granularity 
  no   -warn truncated_source                -warn uncalled 
       -warn uninitialized                   -warn usage 
       -warning_severity warning        no   -wsf 
  no   -fuse_xref 
 
       -I    path : /usr/lib/cmplrs/hpfrtl/,/usr/include/ 
       -V    filename : listing.l 
       -o    filename : listing.o 
 
COMPILER: DIGITAL Fortran 90 V5.x-xxx-xxxx 
 

A summary of compilation statistics appear at the end of the listing file.


Appendix D
Parallel Compiler Directives Reference Material

This appendix provides reference material for:

D.1 OpenMP Fortran API Compiler Directives

The set of OpenMP Fortran Directives allows you to specify the actions taken by the compiler and run-time system when executing a DIGITAL Fortran program in parallel.

For information about the directive format, refer to Chapter 6.

D.1.1 ATOMIC Directive

The ATOMIC directive ensures that a specific memory location is updated atomically, rather than exposing it to the possibility of multiple, simultaneous writing threads.

The ATOMIC directive takes the following form:

  • c$OMP ATOMIC

c

Is one of the following: C (or c), !, or * (see Chapter 6).

Rules and Restrictions for the ATOMIC Directive

This directive applies only to the immediately following statement, which must have one of the following forms:


x = x operator expr 
 
x = expr operator x 
 
x = intrinsic (x, expr) 
 
x = intrinsic (expr, x) 

In the preceding statements:

This directive permits optimization beyond that of the critical section around the assignment. An implementation can replace all ATOMIC directives by enclosing the statement in a critical section. All of these critical sections must use the same unique name.

Only the load and store of x are atomic; the evaluation of expr is not atomic. To avoid race conditions, all updates of the location in parallel must be protected using the ATOMIC directive, except those that are known to be free of race conditions. The function intrinsic, the operator operator, and the assignment must be the intrinsic function, operator, and assignment.

The following restriction applies to the ATOMIC directive:

Example

The following program avoids race conditions by protecting all simultaneous updates of the location, by multiple threads, with the ATOMIC directive. The ATOMIC directive applies only to the statement immediately following it. As a result, Y is not updated atomically:


c$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(X,Y,INDEX,N) 
      DO I=1,N 
         CALL WORK(XLOCAL, YLOCAL) 
c$OMP ATOMIC 
         X(INDEX(I)) = X(INDEX(I)) + XLOCAL 
         Y(I) = Y(I) + YLOCAL 
      END DO 

D.1.2 BARRIER Directive

The BARRIER directive synchronizes all the threads in a team. When encountered, each thread waits until all of the other threads in the team have reached the barrier.

The BARRIER directive takes the following form:

  • c$OMP BARRIER

c

Is one of the following: C (or c), !, or * (see Chapter 6).

Rules and Restrictions for the BARRIER Directive

The following restrictions apply to BARRIER directives:

Examples

The directive binding rules call for a BARRIER directive to bind to the closest enclosing PARALLEL directive. For more information about directive binding, see Section D.1.4.

In the following example, the BARRIER directive ensures that all threads have executed the first loop and that it is safe to execute the second loop:


c$OMP PARALLEL 
c$OMP DO PRIVATE(i) 
        DO i = 1, 100 
           b(i) = i 
        END DO 
c$OMP BARRIER 
c$OMP DO PRIVATE(i) 
        DO i = 1, 100 
           a(i) = b(101-i) 
        END DO 
c$OMP END PARALLEL 

D.1.3 CRITICAL Directive Construct

The CRITICAL directive restricts access to the enclosed code to only one thread at a time.

The CRITICAL directive takes the following form:

  • c$OMP CRITICAL [(name)]
  • block
  • c$OMP END CRITICAL [(name)]

c

Is one of the following: C (or c), !, or * (see Chapter 6).

Rules and Restrictions for CRITICAL and END CRITICAL Directives

The optional name argument identifies the critical section.

A thread waits at the beginning of a critical section until no other thread in the team is executing a critical section having the same name. All unnamed CRITICAL directives map to the same name. Critical section names are global entities of the program. If the name conflicts with any other entity, the behavior of the program is undefined.

The following restrictions apply to the CRITICAL directive:

Examples

The following example includes several CRITICAL directives, and illustrates a queuing model in which a task is dequeued and worked on. To guard against multiple threads dequeuing the same task, the dequeuing operation must be in a critical section. Because there are two independent queues in this example, each queue is protected by CRITICAL directives having different names, XAXIS and YAXIS, respectively:


c$OMP PARALLEL DEFAULT(PRIVATE) SHARED(X,Y) 
c$OMP CRITICAL(XAXIS) 
      CALL DEQUEUE(IX_NEXT, X) 
c$OMP END CRITICAL(XAXIS) 
      CALL WORK(IX_NEXT, X) 
c$OMP CRITICAL(YAXIS) 
      CALL DEQUEUE(IY_NEXT,Y) 
c$OMP END CRITICAL(YAXIS) 
      CALL WORK(IY_NEXT, Y) 
c$OMP END PARALLEL 

D.1.4 Directive Binding

The rules that apply to the dynamic binding of directives are:

D.1.5 Directive Nesting

The rules that apply to the dynamic nesting of directives are:

Examples

The following program containing nested PARALLEL regions is legal, because the inner and outer DO directives bind to different PARALLEL regions:


c$OMP PARALLEL DEFAULT(SHARED) 
c$OMP DO 
      DO I =1, N 
c$OMP PARALLEL SHARED(I,N) 
c$OMP DO 
         DO J =1, N 
            CALL WORK(I,J) 
         END DO 
c$OMP END PARALLEL 
      END DO 
!$OMP END PARALLEL 

The following variation of the preceding example is also legal:


c$OMP PARALLEL DEFAULT(SHARED) 
c$OMP DO 
      DO I =1, N 
         CALL SOME_WORK(I,N) 
      END DO 
c$OMP END PARALLEL 
          . 
          . 
          .      
      SUBROUTINE SOME_WORK(I,N) 
c$OMP PARALLEL DEFAULT(SHARED) 
c$OMP DO 
      DO J =1, N 
         CALL WORK(I,J) 
      END DO 
c$OMP END PARALLEL 
      RETURN 
      END 

D.1.6 DO Directive Construct

The DO directive specifies that the iterations of the immediately following DO loop must be executed in parallel. The loop that follows a DO directive cannot be a DO WHILE or a DO loop not having loop control. The iterations of the DO loop are distributed across the existing team of threads.

A DO directive takes the following form:

  • c$OMP DO [clause[[,] clause]...]
  • do_loop
  • [c$OMP END DO [NOWAIT]]

c

Is one of the following: C (or c), !, or * (see Chapter 6).

clause

Is one of the following:

  • FIRSTPRIVATE(list)
  • LASTPRIVATE(list)
  • ORDERED
  • PRIVATE(list)
  • REDUCTION( operator
  • intrinsic :list )
  • SCHEDULE(type[,chunk])

Rules and Restrictions for DO and END DO Directives

If you do not specify an END DO directive, an END DO directive is assumed at the end of the DO loop. If you specify NOWAIT on the END DO directive, threads do not synchronize at the end of the parallel loop. Threads that finish early proceed straight to the instruction following the loop without waiting for the other members of the team to finish the DO directive.

Parallel DO loop control variables are block-level entities within the DO loop. If the loop control variable also appears in the LASTPRIVATE list of the parallel DO, it is copied out to a variable of the same name in the enclosing PARALLEL region. The variable in the enclosing PARALLEL region must be SHARED if it is specified on the LASTPRIVATE list of a DO directive.

The following restrictions apply to the DO directives:

Examples

In the following example, the loop iteration variable is private by default, and it is not necessary to declare it explicitly. The END DO directive is optional:


c$OMP PARALLEL 
c$OMP DO 
      DO I=1,N 
         B(I) = (A(I) + A(I-1)) / 2.0 
      END DO 
c$OMP END DO 
c$OMP END PARALLEL 

If there are multiple independent loops within a parallel region, you can use the NOWAIT clause, shown in the following example, to avoid the implied BARRIER at the end of the DO directive:


c$OMP PARALLEL 
c$OMP DO 
      DO I=2,N 
         B(I) = (A(I) + A(I-1)) / 2.0 
      END DO 
c$OMP END DO NOWAIT 
c$OMP DO 
      DO I=1,M 
         Y(I) = SQRT(Z(I)) 
      END DO 
c$OMP END DO NOWAIT 
c$OMP END PARALLEL 

Correct execution sometimes depends on the value that the last iteration of a loop assigns to a variable. Such programs must list all such variables as arguments to a LASTPRIVATE clause so that the values of the variables are the same as when the loop is executed sequentially. In the following example, the value of I at the end of the parallel region will equal N+1, as in the sequential case:


c$OMP PARALLEL 
c$OMP DO LASTPRIVATE(I) 
      DO I=1,N 
         A(I) = B(I) + C(I) 
      END DO 
c$OMP END PARALLEL 
      CALL REVERSE(I) 

Ordered sections are useful for sequentially ordering the output from work that is done in parallel. Assuming that a reentrant I/O library exists, the following program prints out the indexes in sequential order:


c$OMP DO ORDERED SCHEDULE(DYNAMIC) 
      DO I=LB,UB,ST 
         CALL WORK(I) 
      END DO 
           . 
           . 
           . 
      SUBROUTINE WORK(K) 
c$OMP ORDERED 
      WRITE(*,*) K 
c$OMP END ORDERED 


Previous Next Contents Index