The HPF EXTRINSIC Attribute

The HPF EXTRINSIC Attribute


Definition Back to Top

The HPF EXTRINSIC routine is provided to call procedures beyond the HPF language or style. The HPF compiler calls a procedure as though it were a plain serial routine on each node. An EXTRINSIC routine can

There must be a Fortran 90 INTERFACE block in the calling routine to describe the called routine.

Syntax of the EXTRINSIC and INTERFACE Statements:

  INTERFACE
  EXTRINSIC ( HPF | HPF_LOCAL | other ) 
  Description of the called routine
  END INTERFACE


General Example Back to Top

Example: Calling Random Number Generators from HPF

This example assumes some prior knowledge of DISTRIBUTE and INDEPENDENT.

If you have a sequential Fortran program that simulates a physical system, you often have a loop nest in which a random number generator provides pseudo-random input:

         do i = ...
            do j = ...
               :
               x = rand(x)
               :
            end do
         end do
If you want to parallelize this loop nest in HPF, you will spread the "i" iterations across the processors, but then you have a problem: all processors will be using the same random number sequence, and your simulation results will not be accurate. You need a collection of independent random number generators, as is provided for example by Cornell's PRNG (parallel random number generator):
!hpf$ independent,new(j)         ! parallelize the "do i" loop
         do i = ...
            do j = ...
               :
               x(i) = prng_next(i)  ! next number from generator "i"
               :
            end do
         end do
Here, x(i) is a new random number that the "i"th iteration can use, and each iteration uses an independent sequence of random numbers, no matter which processor node is actually executing the iteration. Moreover, your results will be the same whether you run serially, 1-way, or n-way, because each iteration will use the same generator. PRNG has 1022 such generators available, numbered 0, 1, ... 1021. To use this generator, link with "-lctc."

There are just two more steps to parallelizing the above loop: you need a distributed array in order to get HPF to spread the loop iterations, and you need to tell the compiler that prng_next is "safe" to call in parallel.

The first is easily done by distributing x, so that the "owner" of x(i) will execute iteration "i":

      real*8, dimension(NMAX):: x
!hpf$ distribute x(BLOCK)
Here we have chosen a BLOCK distribution for x, but CYCLIC would work just as well.

The second step is to tell HPF that prng_next is "pure," in that it contains no cross-iteration dependencies:

       interface
            pure function prng_next(i)
               integer,intent(in)::i
               real*8:: prng_next
            end function prng_next
        :
        end interface
(The interface block declares the function to be real*8, and it also tells the caller how the function is to be called.)

In this example, assuming that the loop nest contains no other data dependencies, the "do i" loop will be spread in BLOCK fashion across the processors being used in the parallel job. This means that node 0 will execute iterations 1, 2, ... k, while node 1 will execute iterations k+1, k+2 ..., and so on.


Tariff Program Examples Back to Top

EXTRINSIC is used twice in the Tariff Program:

          INTERFACE
          EXTRINSIC(HPF_LOCAL) & 
          SUBROUTINE sayit (t1,t2,message)
             real*8, intent(in)   :: t1,t2
             character*(*), intent(in) :: message
          END SUBROUTINE sayit
          EXTRINSIC(HPF_LOCAL) & 
	  SUBROUTINE getdata(sslope,shxlin,dslope,dhxlin,thxlin,ind1,ind2,tar)
             real,intent(out)::  sslope(:, :), shxlin(:)
             real,intent(out)::  dslope(:, :), dhxlin(:)
             real,intent(out)::  thxlin(:, :),tar(:, :)
             integer,intent(out):: ind1(:, :), ind2(:, :)
	  END SUBROUTINE getdata
          END INTERFACE
Move the program display to this section

These subroutines will be run on each node as a normal Fortran subroutine, not as HPF. I/O statements are executed on each node. The interface block tells the HPF compiler exactly how the subroutine is to be called. This was done to eliminate the I/O bottleneck that occurred when reading in the data using HPF.


Exercises (long) Back to Top

The lab exercises for this section are shared with the Case Study Part 5 and 6 labs. As such they call out prerequisites particular to the Case Study - you may proceed without reviewing them. The lab will start with a program that does not exactly match the program in this module.

These labs may be run using the Virtual Workshop Companion Web interface, which allows you to work through the lab exercises without opening a telnet session. If you would like to use the VW Companion, click on the link below, which will open up a separate browser window from which you will supply your userid and password. The rest of the interface will be launched from there.

Whether you prefer to log in or to use the VW Companion, you'll need to view the instructions for the labs, which will come up in this window.


Back to Top