Software Archive
Read-only legacy content
17061 Discussions

Re: forall construct

Intel_C_Intel
Employee
486 Views
One thing you should try when experimenting with new syntax is to run it through the compiler with F95 standard checking enabled. Your FORALL construct should give you at least two errors because you forgot to change the end do to end forall and because the first statement in your FORALL construct is a multiple assignment. The tricky thing about FORALL and WHERE is that they are not really looping constructs. The first statement says to assign array1 N times in any order and the second says to take the last assigned value of array1 and use it to determine all N values of array4. Thus all entries of array4 will have the same indeterminate value. You could replace both statements by

array4(i) = sum(abs(array2(i:k+i:N)*array3)**2)

and then the FORALL should work, given that you changed the end do to end forall as well.
0 Kudos
2 Replies
Steven_L_Intel1
Employee
486 Views
To answer your last question, yes, FORALL body constructs (the statements within the FORALL) are executed in sequence, but there is no implied ordering among the operations on the various active indexes.

For assignment statements, the standard says, "Execution of a forall-assignment-stmt that is an assignment-stmt causes the evaluation of expr and all expressions within variable for all active combinations of index-name vakues. These evaluations may be done in any order. After all these evaluations have been performed, each expr value is assigned to the corresponding variable. The assignments may occur in any order."

Steve
0 Kudos
Intel_C_Intel
Employee
486 Views
 
! Since you choose to read only my Fortran, not my prose... 
program forall_test 
   implicit none 
   real, allocatable :: array1(:), array2(:), array3(:), array4(:) 
   integer N 
   integer k 
   integer i 
 
   write(*,'(a)',advance='no') 'Enter the problem size:> ' 
   read(*,*) N 
   allocate(array1(max(N-1,1)),array2(N**2),array3(max(N-1,1))) 
   allocate(array4(N)) 
   call random_seed() 
   call random_number(array2) 
   call random_number(array3) 
   k = N*(N-1) 
   do i = 1, N 
      array1 = array2(i:k+i:N)*array3 ! Generates WARNING! 
      array4(i) = dot_product(array1, array1) 
   end do 
   write(*,'(a)') 'Results for DO loop:' 
   write(*,'(a,i0,a,f0.6)') ('array4(',i,') = ',array4(i),i=1,N) 
   forall( i = 1:N) 
      array1 = array2(i:k+i:N)*array3 
      array4(i) = dot_product(array1, array1) 
!   end do 
   end forall ! Suppress Christo for end do as above 
   write(*,'(a)') 'Results for FORALL construct:' 
   write(*,'(a,i0,a,f0.6)') ('array4(',i,') = ',array4(i),i=1,N) 
end program forall_test 
0 Kudos
Reply