pmontgom@euphemia.math.ucla.edu (Peter Montgomery) (09/21/90)
C My first posting of this used "*" rather than "C" on these initial
C comments -- the news software deleted them all.
C How do I allocate an array inside a concurrent loop?
C In this toy example, each call to TRIG returns an array (sc)
C whose contents are used only for the duration of that
C iteration of the loop by the caller. If the loop in the
C main program is to execute concurrently, then each
C processor must have a private copy of the array,
C but I want to avoid allocating separate copies for each iteration
C of the outer loop (i.e., on an 8-processor system I am willing
C to have 8 copies of the temporary array, but not 100000 copies).
C How should I declare this? If I use "allocate", the compiler
C declines to optimize the loop.
program test
implicit none
integer IMAX, i
parameter (IMAX = 100000)
double precision sc1(2), sc2(2), sc3(2, IMAX), sc4(:)
double precision sum1, sum2, sum3, sum4
sum1 = 0
do i = 1, IMAX ! Sequential loop
call TRIG(DBLE(i), sc1)
sum1 = sum1 + sc1(1)*sc1(2)**2
end do
CVD$L CNCALL
sum2 = 0
do i = 1, IMAX ! Executes incorrectly
call TRIG(DBLE(i), sc2)
sum2 = sum2 + sc2(1)*sc2(2)**2
end do
CVD$L CNCALL
sum3 = 0
do i = 1, IMAX ! sc3 array too big
call TRIG(DBLE(i), sc3(1,i))
sum3 = sum3 + sc3(1,i)*sc3(2,i)**2
end do
CVD$L CNCALL
sum4 = 0
do i = 1, IMAX ! allocate inhibits
! concurrency
allocate(sc4(1:2))
call TRIG(DBLE(i), sc4)
sum4 = sum4 + sc4(1)*sc4(2)**2
deallocate (sc4)
end do
print *, 'Sums are ', sum1, sum2, sum3, sum4 ! Should be identical
end
recursive subroutine TRIG(angle, sc)
implicit none
double precision angle, sc(2)
sc(1) = SIN(angle)
sc(2) = COS(angle)
end
--
Peter L. Montgomery
pmontgom@MATH.UCLA.EDU
Department of Mathematics, UCLA, Los Angeles, CA 90024-1555
If I spent as much time on my dissertation as I do reading news, I'd graduate.jac@Alliant.COM (Jim Chmura) (09/27/90)
The trick here, which gives you 8 copies of the array, is to declare the array to be dimensioned (n,0:7) and then use the library routine lib_processor_number to determine which processor a particular iteration is running on. This ensures that each processor works in a separate copy: dimension array(n,0:7) . . cvd$ cncall do i=1,100000 . . np=lib_processor_number() call sub(...array(1,np)...) . . enddo Be sure to include -lcommon in your link string to pick up the lib_processor_number routine. Regards, Jim Chmura Area Analyst Manager Alliant - Marietta GA