Subject: compiler benchmarks

From: [email-masked]
Date: Thu, 19 Aug 93 15:20:51 -0400

COMPIL2.TEX
         ---------------
 
 Appended is the first draft of the chapter 6 on compiler benchmarks.
 Please, accept it as an invitation to discussions rather than the final
 version.
 
           Tom Haupt, 19 Aug 1993

%------------------------------------------------------------------------
%      PARKBENCH REPORT (second draft), File:        compil2.tex
%------------------------------------------------------------------------
%file compil2.tex
%compiled by Tom Haupt for compiler benchmarks subcommittee

\chapter{Compiler Benchmarks}
\footnote{assembled by Tom Haupt for Compiler Benchmarks subcommittee}

\section{Objectives and Metric}

For most users, the performance of codes generated by a compiler is what
that actually matters. The metric for the performance evaluation is the
wall--clock execution time of selected benchmark applications in, say,
seconds, or the execution time normalized to a standard floating point
counts, say, in GFLOP/s, as defined in chapter 2. A representative suite
of benchmark applications is described in other parts of this document
(Kernels, chapter 4, and Compact Applications, chapter 5), and we will
provide HPF versions of these codes.

For HPF compiler developers and implementators, however, an additional
benchmark suite may be very useful: the benchmark suite that can
evaluate specific HPF compilation phases and the compiler runtime
support. For that purpose, the best metric is the ratio of execution
times of compiler generated to hand coded programs as a function of the
problem size and number of processors engaged in the computation.

The compilation process can be logically divided into several phases,
and each of them influence the efficiency of the resulting code. The
initial stage is parsing of a source code which results in an internal
representation of the code. It is followed compiler transformations,
like data distribution, loop transformations, computation distribution, 
communication detection, sequentialization, insertion of calls to a
runtime support, and others. This we will call a HPF-specific phase of
compilation. The compilation is concluded by code generation phase. For
portable compilers that outputs f77+message passing code, the node
compilation is obviously factorized out and the efficiency of the node
compiler can be evaluated separately.  

This benchmark suite addresses the HPF-specific phase only. Thus, it is
well suited for performance evaluation of both translators (HPF to
F77+message passing) and genuine HPF compilers. The parsing phase is an
element of the conventional compiler technology and it is not of
interest in this context. The code generation phase involves
optimization techniques developed for  sequential compilers (in
particular, Fortran 90 compilers) as well as micro-grain parallelism or
vectorization. The object codes for specific platforms may be strongly
architecture dependent (e.g., may be very different for processors with
vector capabilities than for those without it). Evaluation of
performance of these aspects require different techniques that these
proposed here. 

It is worth noting, that the HPF-phase strongly affect the possibility
of optimization of the node codes. For example, insertions of calls to
the communication library may prohibit the node compiler to perform many
standard optimizations without expensive interprocedural analysis.
Therefore, capability to exploit opportunities for optimizations at HPF
level and to generate the output code that way it can be further
optimized by the node compiler is an important element of evaluation of
HPF compilers. Nevertheless, evaluation of the HPF-phase separately is
very valuable since the hand coded programs face the same problems. We
will address these issues in the future releases of the benchmark suite. 

Compilers for massively parallel and distributed systems are still
object of a research and laboratory testing rather than commercial
products. The parallel compiler technology  as well as methods of
evaluating it is not mature yet. The advent of the HPF standard gives
opportunity to develop systematic benchmarking techniques. The current
definition of HPF cannot be recognized as an ultimate solution for
parallel computing. Its limitations are well known, and many researchers
are working on extensions to HPF to address a broader class of real
life, commercial and scientific applications. We expect new language
features to be added to the HPF definition in future versions of HPF,
and we will extend the benchmark suite accordingly. On the other hand,
new parallel languages based on languages other than Fortran, notably
C++, become more and more popular. Since the parallelism is inherent in
a problem and not its representation, we anticipate many commonalities
in the parallel languages and corresponding compiler technologies,
notably sharing the runtime support. Therefore, we decided to address
this benchmark suite to these aspects of the compilation process that
are inherent to parallel processing in general, rather than testing
syntactic details of the HPF.
 
\section{High Performance Fortran}

HPF is an extension of Fortran 90 to support data parallel programming 
model, defined as
single threaded, global name space, loosely synchronous parallel
computation. The idea behind HPF is to provide  means to produce
scalable, portable, and top performance codes for MIMD and SIMD
computers with non-uniform memory access cost. The portability of the
HPF codes means that the efficiency of the code is preserved for
different machines with comparable number of processors. 

The HPF extensions to  the Fortran 90 standard fall into four
categories: compiler directives, new language features, library routines
and  restrictions to Fortran 90. The HPF compiler directives are
structured comments that suggest implementation strategies or assert
fact about a program to the compiler. They may affect the efficiency of
the computation performed, but they do not change the value computed by
the program. 

The new language features are FORALL statement and construct as well as
minor modifications and additions to the library of Fortran 90 intrinsic 
functions.
In addition, HPF introduces new functions that may be used to express
parallelism, like new array reduction functions, array combining scatter
functions, arrays suffix and prefix functions, array sorting functions
and others. These functions  are collected in a separate library, the
HPF library. Since it was anticipated that not all algorithms can be
easily expressed in HPF syntax, an escape mechanism, the extrinsic
functions, has been introduced. The extrinsic functions may be written
in languages other than HPF and may support a different computational
model. Finally, HPF imposes some restrictions to Fortran 90 definition
of storage and sequence associations.

The HPF approach is based on two key observations. First, the overall
efficiency of the program can be increased, if many operations are
performed concurrently by different processors, and secondly, the
efficiency of a single processor is likely be the highest, if the
processor performs computations on data elements stored in its local
memory. Therefore, the HPF extensions provide means for explicit
expression of parallelism  and data mapping. It follows that an HPF
programmer expresses parallelism explicitly, and the data distribution
is tuned accordingly to control the load balance and minimize
communication. On the other hand, given a data distribution, an HPF
compiler may be able to identify operations that can be executed
concurrently, and thus generate even more efficient code.

To speed up commercial implementations of HPF compilers, a HPF subset
has been defined as well. The subset comprises selected Fortran 90
features, notably array assignments and allocatable arrays, intrinsic
functions, and interface blocks. In addition, the subset excludes some
of HPF features, like dynamic mappings, pure and extrinsic function
attributes, FORALL construct, and the HPF library.

\section{Benchmark Suite}

The benchmark suite comprises several simple, synthetic applications which test
several aspects of the HPF compilation. The current version of the suite
addresses the basic features of HPF, and it is designed to measure
performance of early implementations of the compiler. They concentrate
on testing parallel implementation of explicitly parallel statements,
i.e., array assignments, FORALL statements, INDEPENDENT DO loops, and
intrinsic functions with different mapping directives. The language
features not included in the HPF subset are not addressed in this
release of the suite. The next releases will contain more kernels that
will address all features of HPF, and also they will be sensitive to
advanced compiler transformations.

Parallel implementation of the array assignments, including FORALL
statements, is a central issue for an early HPF compiler. Given a data
distribution, the compiler distributes computation over available
processors. An efficient compiler achieves an optimal load balance with
minimum interprocessor communication. Kernels AA, SH, ST, TM, FL, and IR
address that problem. They represent applications of different degree of
difficulty, from very easy to implement kernel AA that is very regular,
to kernel IR that require difficult unstructured interprocessor
communication that is specified only at runtime.

Every array assignment written according to Fortran 90 syntax can be
expressed as a FORALL statement. It is a matter of a programmer's
preference which syntax to use. The idea behind introducing FORALL in
HPF is to generalize array assignments to make expressing parallelism
easier. Kernel FL provides several examples of FORALL statements that
are difficult or inconvenient to write using Fortran 90 syntax.

Once the data and iteration space is distributed, the next step that
strongly influences efficiency of the resulting codes is communication
detection and code generation to execute data movement. In general, the
off-processor data elements must be gathered before execution of an
array assignment, and the results are to be scattered to destination
processors after the assignment is completed. In other words, some of
the array assignments may require a preprocessing phase to determine
which off-processor data elements are needed and execute the gather
operation. Similarly, they may require postprocessing (scatter). Many
different techniques may be used to optimize these operations. To
achieve a high efficiency, it may be very important that compiler is
able to recognize structured communication patterns, like shift,
multicast, etc. Kernels AA, SH, and ST introduce different structured
communication patterns, and kernel IR is an example of an array
assignment that require unstructured communication (because of
indirections). A good HPF compiler is expected to handle efficiently 
multiple indirections as well and appropriate test kernels will be
provided in the next releases of the suite.

Sometimes, the programmers may help the compiler to minimize necessary
interprocessor communication by suitable data mapping, in particular by
defining a relative alignment of different data object. This may be
achieved by aligning the data objects with an explicitly declared
template. Kernel TL provides an example of this kind.

The above test applications address essentially compiler transformations
of a single statement. Interstatement and interprocedural analysis
introduces an additional opportunity for aggressive optimizations (loop
transformations, optimizations of temporary arrays usage, overlapping
communications and computations, to name a few). These may be tested
using benchmark applications described in chapter 4 and 5. Some of the
issues are addressed in EP kernel, more will be added in kernels
addressing FORALL constructs.

The RD and EP kernels test performance of codes in which the parallelism
is expressed in other way: by using intrinsic functions (RD) and
INDEPENDENT DO construct (EP). The future release of the suite will also
contain examples of use functions from the HPF library, and examples of
nested INDEPENDENT loops.

The last group of kernels, AS, IT, IM and EI, demonstrate passing
distributed arrays as subprograms' arguments. They represents four
typical cases: 

\begin{enumerate}
\item a known mapping of the actual argument is to be preserved by the dummy
argument (AS). 
\item the mapping of the dummy argument is to be inherited from the actual
argument, thus no remapping is necessary. The mapping is known at
compile time (IT).
\item the mapping of the dummy argument is to be identical to that of the
actual argument, but the mapping is not known at the compile time (IM).
\item a specific mapping of the dummy argument is forced, regardless the
mapping of the actual elements (EI).
\end{enumerate} 

The next release of the suite will address other aspects of the HPF
compilation, including usage of allocatable arrays and pointers, dynamic
(re)mappings, FORALL construct, PURE functions, extrinsic functions, etc.

\section{Description of Codes}

\subsection{AA: Array Assignments}

This simple kernel it taken from Livermore Loop benchmark Suite \cite{Liv}. 
The sequence of Fortran 90 array assignments is that in many implementation it
requires no communication. The distribution of computation to achieve a
perfect load balancing is straightforward. The resulting code is
expected to be as efficient as a hand coded message passing version. The
possible differences in execution time may reflect an overhead generated
by the HPF compiler to set up the environment.

\begin{verbatim}

         program AA
C        =======================================================
C        array assignments kernel
C        taken from the Livermore Loops, kernel 9
C        =======================================================
         parameter ( N = 1024 )
         real PX(13,N), Q
         real DM22, DM23, DM24, DM25, DM26, DM27, DM28, C0
         integer i, k
CHPF$    processors p(16)
CHPF$    template d(1024)
CHPF$    distribute d(block)
CHPF$    align PX(*,I) with d(I)
C
         call start_timer()

C        inititialization
          ...
         FORALL ( i = 1:N ) 
     *   PX(1,i) =      DM28 * PX(13,i) + DM27 * PX(12,i) + 
     *                  DM26 * PX(11,i) + DM25 * PX(10,i) +
     *                  DM24 * PX(9,i)  + DM23 * PX(8,i)  +
     *                  DM22 * PX(7,i)  + C0 * (PX(5,i)   + 
     *                  PX(6,i))        + PX(3,i) 
        call stop_timer()

C       print results
        end 

\end{verbatim}

\subsection{SH: Array Assignments with Shift}

This is another Livermore kernel. The array assignments require multiple
collective communication. This kernel demonstrate performance of the
runtime shift function as well as ability of a compiler to minimize
communication requests.

\begin{verbatim}

        program SH
C       ==============================================================
C       array assignments with shifts
C       taken from the Livermore Loops, kernel 7
C       ==============================================================

        parameter ( N = 1024 )
        real U(N), X(N), Y(N), Z(N), Q, R, T
        integer k
CHPF$   processors p(8)
CHPF$   template d(1024)
CHPF$   distribute d(block)
CHPF$   align (:) with d(:) :: X, Y, Z, U

        call start_timer()

C       initialization
         ...
        forall (k=1:N-6)   
     &        X(k)=     U(k) + R*( Z(k) + R*Y(k)) +
     &               T*( U(k+3) + R*( U(k+2) + R*U(k+1)) +
     &               T*( U(k+6) + Q*( U(k+5) + Q*U(k+4))))
C
        call stop_timer()
C       print results

        end 

\end{verbatim}

\subsection{ST: Array Assignments with Strides}

This kernel extends test of compiler ability to recognize structured
communication patterns beyond shifts.

\begin{verbatim}

       program ST
C      =======================================================
C      array assignments kernel
C      taken from the Livermore Loops, kernel 9
C      =======================================================
       integer N,M,K1,K2,I
       parameter ( N = 1024 )
       parameter ( M = N/2 )
       real, array(N,N) :: A, B

CHPF$  processors p(4,4)
CHPF$  template d(1024,1024)
CHPF$  distribute d(block,block)
CHPF$  align WITH d :: A,B
C
       call start_timer()

C       initialization
        ...      

       A(1:N,K1)=B(1:M:2,K2)
       FORALL(I=2,M) A(I,K1)=A(2*I-1)*B(I,1)

       call stop_timer()

C      Print results
        end 

\end{verbatim}

\subsection{TM: Usage of a Template}

This kernel uses an explicitly declared template to force a relative
alignment of arrays to minimize communication.

\begin{verbatim}

      PROGRAM TM
C     =================================================================
C     template kerenel
C     adopted from the Purdue Set
C     =================================================================
      INTEGER NK,MK
      DATA N / 1023 /
      DATA M / 1023 /
      INTEGER NDIM,MDIM,ND1,MD1
      PARAMETER (NDIM=1023,MDIM=1023,ND1=NDIM+1,MD1=MDIM+1)
      REAL, ARRAY(MDIM)          :: R
      REAL, ARRAY(NDIM)          :: C
      REAL, ARRAY(NDIM,MDIM)     :: A
      REAL, ARRAY(ND1,MD1)       :: ABIG
      REAL, ARRAY(1,1)           :: ACORN
      REAL, ARRAY(NDIM-1,MDIM-1) :: B

CHPF$ PROCESSORS P(8)
CHPF$ TEMPLATE TOM(1024)
CHPF$ DISTRIBUTE TOM(BLOCK)
CHPF$ ALIGN ABIG(i,*) with TOM(i)
CHPF$ ALIGN A(i,*) with TOM(i)
CHPF$ ALIGN C(:) with TOM(:)
CHPF$ ALIGN B(i,*) with TOM(i+2) 

      call start_timer()

      forall(i=1:m) r(i)=1.0+i
      forall(i=1:n) c(i)=1.0-i
      forall(i=1:n,j=1:m) a(i,j)=i+j

      ACORN = .5
      ABIG(1:N,1:M)=A
      ABIG(1:N,M+1)=C
      ABIG(N+1,1:M)=R

      ABIG(N+1,M+1)=0.5

      FORALL(I=3:N+1,J=3:M+1) B(I,J)=A(I-2,J-2)

      call stop_timer()
C     print results
      STOP
      END

\end{verbatim}

\subsection{RD: Intrinsic Reduction Functions}

This kernel is adopted from the Purdue Set \cite{Rice}. It demonstrate
performance of selected intrinsic functions.

\begin{verbatim}

      PROGRAM RD
      INTEGER NS,NT
      DATA NS / 128 /
      DATA MT / 4092 /
      INTEGER NTDIM,NSDIM
      PARAMETER (NTDIM = 4092)
      PARAMETER (NSDIM = 128)

      REAL, ARRAY(NTDIM,NSDIM) :: SCORES
      LOGICAL, ARRAY(NTDIM,NSDIM) :: ABOVE
      LOGICAL, ARRAY(NTDIM) :: TEMP 

      INTEGER NABOVE
      REAL AVER,AVERTOP,LOWABO
      LOGICAL GENIUS

CHPF$ PROCESSORS Q(8)
CHPF$ TEMPLATE TOM(4092)       
CHPF$ DISTRIBUTE TOM(BLOCK)
CHPF$ ALIGN SCORES(i,*) with TOM(i)
CHPF$ ALIGN ABOVE(i,*) with TOM(i)
CHPF$ ALIGN TEMP(:) with TOM(:)

      call start_timer()

c       SCORES=60.0+40.0*SIN(SPREAD([1:NT],2,NS)*
c   +          SPREAD([1:NS],1,NT)*0.0006321)

       forall(i=1:nt,j=1:ns) scores(i,j)=
     + 60.0+40.0*sin(real(i))*j*0.0006321

         SSUM=SUM(SCORES)
         AVER=SSUM/(NS)
         WHERE(SCORES.GT.AVER)
           ABOVE=.TRUE.
           SCORES=SCORES*1.1
         ELSEWHERE
           ABOVE=.FALSE.
         ENDWHERE

         NABOVE=COUNT(ABOVE)
         AVERTOP=SUM(SCORES,MASK=ABOVE)/NABOVE
         LOWABO=MINVAL(SCORES,MASK=ABOVE)

c       GENIUS=ANY(ALL(ABOVE,DIM=1))
        TEMP=ALL(ABOVE,DIM=1)
        GENIUS=ANY(TEMP)

      call stop_timer

C     print results
      STOP
      END

\end{verbatim}

\subsection{FL: FORALL statement}

This kernel makes use of a FORALL statement. Note, that the array
assignment in this program are not easily expressible in Fortran 90
syntax.

\begin{verbatim}

      PROGRAM FL
C     ===================================================
C     forall statement kerenel
C     ==================================================
      REAL, ARRAY(1024,1024) :: x,y
      REAL, ARRAY(32) :: s

CHPF$ PROCESSORS P(4,4)
CHPF$ TEMPLATE T(1024,1024)
CHPF$ DISTRIBUTE T(BLOCK,BLOCK)
CHPF$ ALIGN WITH T :: X,Y

      n=1024
      m=32

      call start_timer()
      FORALL (i=1:n,j=1:n) y(i,j)=1.0/REAL(i+j-1)
      FORALL (k=1:n) x(k,1:m)=y(1:m,k)
      FORALL (i=1:m-1) s(i)=SUM(x(1:n:m)) 
      call stop_timer()
C     print results
      stop
      end

\end{verbatim}

\subsection{EP: Embarrasingly Parallel}

This kernel, adopted from NAS benchmark Suite \cite{NAS} is provided in two
versions: one using Fortran 90 syntax, and the other written as a
Fortran 77 DO loop with HPF assertion directive INDEPENDENT. For many
platforms, the latter version may be much more effective because of use
HPF's NEW scalar variables as opposed to explicitly declared arrays
necessary in Fortran 90 syntax.

\begin{verbatim}

(HPF version of the NAS EP kernel is to be included here)
\end{verbatim}

\subsection{IR: Irregular Communication}

The code of this kernel does not provide much information for compile
time optimization (indirections). The efficiency of the code solely
depends on the efficiency of the runtime support, including
communication scheduling.

\begin{verbatim}

      PROGRAM IR
C     ============================================================
C     irregular communications kernel
C     ============================================================

      PARAMETER (NIT = 100)
      PARAMETER (M=32)
      PARAMETER (ME = M*(M-1), ME2 = 2*ME, M2 = M*M)
      REAL, ARRAY(M2) :: Y
      INTEGER, ARRAY(ME2) :: L,R,U,D,IM

CHPF$ PROCESSORS P(8)
CHPF$ TEMPLATE TP(M2)
CHPF$ TEMPLATE TE(ME2)
CHPF$ DISTRIBUTE TP(CYCLIC)
CHPF$ DISTRIBUTE TE(CYCLIC)
CHPF$ ALIGN WITH TP :: Y
CHPF$ ALIGN WITH TE :: L,R,U,D,IM

      FORALL (I=1:ME) IM(I)= (I + I/M)/M
   
      FORALL(I=1:M2) Y(I)= I/M*0.1 + MOD(M,I)*0.2
      FORALL (I=1:ME) L(I)=I+IM(I)
      FORALL (I=1:ME) R(I)=L(I)+1
      FORALL (I=1:ME) U(I)=1+IM(I)+(MOD(IM(I),M)-1)*M
      FORALL (I=1:ME) D(I)=1+IM(I)+MOD(IM(I),M)*M

      L(ME+1:ME2) = U(1:ME)  
      R(ME+1:ME2) = D(1:ME)  

      DO IT = 1, NIT
       FORALL(I=1:ME2) Y(L(I)) = 0.5 * (Y(L(I)) + Y(R(I)))
      ENDDO

      CALL stop_timer()
C     print results
      END

\end{verbatim}

\subsection{AS: Assertion on the Mapping of the Actual Argument}

This kernel test the performance of the program that calls a subprogram
with an distributed array as an argument. The mapping of the actual and
dummy parameters are known at the compile time.

\begin{verbatim}

      PROGRAM AS
C     ===========================================================
C     assertions on the mapping of the actual argument
C     ==========================================================
      REAL, ARRAY(1024,1024) :: A
CHPF$ PROCESSORS P(4,4)
CHPF$ TEMPLATE T(1024,1024)      
CHPF$ DISTRIBUTE T(BLOCK,BLOCK)
CHPF$ ALIGN A(:,:) WITH T(:,:)

      call start_timer()

      FORALL(i=1:1024,1:1024) A(I,J)=I+0.1*J

      DO I=1,1000
       CALL SUBA(A)
      ENDO     

      call stop_timer()
C     print results
      END

      SUBROUTINE SUBA(X)
      REAL, ARRAY(1024,1024) :: X
CHPF$ PROCESSORS Q(4,4)
CHPF$ DISTRIBUTE X *(BLOCK,BLOCK) ONTO *Q

      FORALL (I=2:1023,J=2:1023) X(I,J)=0.25*(X(I+1,J)+X(I-1,J)+
     &        X(I,J-1)+X(I,J+1)

      RETURN
      END

\end{verbatim}

\subsection{IT: Inherited Template}

In this kernel, an array section is passed as an actual argument. The
inherit directive signal the compiler that no remapping is to be
performed.

\begin{verbatim}

      PROGRAM IT
C     ===========================================================
C     inherited template
C     ==========================================================
      PARAMETER (N=1024)
      PARAMETER (N1 = 1, N2 = N/2, N3 = N2+1, N4 = N)
      REAL, ARRAY(N,N) :: A
CHPF$ PROCESSORS P(4,4)
CHPF$ TEMPLATE T(N,N)      
CHPF$ DISTRIBUTE T(BLOCK,BLOCK)
CHPF$ ALIGN A(:,:) WITH T(:,:)

      call start_timer()

      FORALL(i=1:N,1:N) A(I,J)=I+0.1*J

      DO I=1,1000
       CALL SUBA(A(N1:N2),N1,N2))
       CALL SUBB(A(N3:N4),N3,N4))
      ENDO     

      call stop_timer()
C     print results        
      END

      SUBROUTINE SUBA(X,N1,N2)
      REAL, ARRAY(:,:) :: X
CHPF$ INHERIT X
CHPF$ PROCESSORS Q(4,4)
CHPF$ DISTRIBUTE X *(BLOCK,BLOCK) ONTO *Q

      FORALL (I=N1:N2,J=N1:N2) A(I,J)=0.25*(A(I+1,J)+A(I-1,J)+
     &        A(I,J-1)+A(I,J+1)

      RETURN
      END

      SUBROUTINE SUBB(X,N1,N2)
      REAL, ARRAY(:,:) :: X
CHPF$ INHERIT X
CHPF$ PROCESSORS Q(4,4)
CHPF$ DISTRIBUTE X *(BLOCK,BLOCK) ONTO *Q

      FORALL (I=N1:N2,J=N1:N2) A(I,J)=0.25*(A(I+1,J)-A(I-1,J)+
     &        A(I,J-1)-A(I,J+1)

      RETURN
      END

\end{verbatim}

\subsection{IM: Inherited Mapping}

In this kernel, a subprogram inherits mapping of the actual argument.
Thus, the mapping is known only at run time. The subroutine is called
twice, with different mapping.

\begin{verbatim}

      PROGRAM IM
C     ===========================================================
C     inherited mapping
C     ==========================================================
      PARAMETER (N=1024)
      REAL, ARRAY(N,N) :: A,B
CHPF$ PROCESSORS P(4,4)      
CHPF$ DISTRIBUTE A(BLOCK,BLOCK)
CHPF$ DISTRIBUTE B(BLOCK,*)

      call start_timer()

      FORALL(i=1:N,1:N) A(I,J)=I+0.1*J
      FORALL(i=1:N,1:N) B(I,J)=I+0.1*J

      DO I=1,1000
       CALL SUBA(A)
       CALL SUBA(B)
      ENDO     

      call stop_timer()
C     print results
      END

      SUBROUTINE SUBA(X)
      REAL, ARRAY(:,:) :: X,A
CHPF$ PROCESSORS Q(4,4)
CHPF$ DISTRIBUTE X * ONTO *Q
CHPF$ ALIGN A(:,:) WITH X(:,:)

      A=CSHIFT(X,1,DIM=1)
      X=0.5*(A+X)

      RETURN
      END

\end{verbatim}

\subsection{EI: Mapping of a Dummy Argument Declared in an Explicit Interface}

A specific mapping of the dummy argument is forced by explicit mapping
directives.

\begin{verbatim}

(in preparation)

\end{verbatim}

\section{Example Results}

\begin{verbatim}

(efficiency of the benchmark codes generated by the Fortran 90D compiler
 are to be presented here)

\end{verbatim}

\section{Summary}

The synthetic compiler benchmark suite described here is an addition to the
benchmark kernels and applications described in chapter 4 and 5. It is
not meant as a tool to evaluate the overall performance of the compiler
generated codes. It has been introduced as an aid for compiler
developers and implementators to address some selected aspect of the HPF
compilation process. In the current version, the suite does not comprise
a comprehensive sample of HPF codes. Actually, it addresses only the HPF
subset. Hopefully, it will contribute to establishment of a systematic
compiler benchmarking methodology. We intend to continue our effort to
develop a complete, fully representative HPF benchmark suite. 

% ----------------------------------------------------------------------------
% --- end of chapter on compiler benchmarks ----------------------------------
% ----------------------------------------------------------------------------