Forum Jump

Select Group :
Select Forum :
Sorted By :
Sort Order :
From The :
 
Thread Tools  Search this thread 
fah10
Total Points:
50
Status Points:
0
Green Belt
July 18, 2009 4:46 AM PDT
Array constructor
When using array constructors with variables in it like arr(:) = (/1.0, a, b/) in an OpenMP loop, the private variable arr sometimes contains random values. Intel's thread checker also reports an "write->write data race" error at this line.

Is the array constructor not thread safe?????
jimdempseyatthecove
Total Points:
36,397
Status Points:
36,397
Black Belt
July 18, 2009 8:57 AM PDT
Rate
 
#1

Can you provide a code sample?

Is the arr(:) = (/1.0, a, b/) occuring inside your parallel region (i.e. to each private arr(:))?

Jim Dempsey

--------

Blog: The Parallel Void


www.quickthreadprogramming.com


fah10
Total Points:
50
Status Points:
0
Green Belt
July 18, 2009 11:05 AM PDT
Rate
 
#2 Reply to #1
The following test program usually produces errors when running with multiple OpenMP threads. Sometimes it is very hard to get the test failed. Using static arrays, it seems to be more likely that the test passes. However, in any case Intel's thread checker reports "Write->Write data-races" at the line with the array constructor.

program arraytest
  ! compiled with ifort -openmp arraytest.F90
  
  integer(kind=4), parameter :: n=1000000
  integer(kind=4) :: i
  real(kind=8), dimension(:,:),allocatable :: data
  real(kind=8), dimension(:),allocatable :: arr

  allocate(data(3,n))

  !$omp parallel private(arr,i) shared(data)
  allocate(arr(3))

  !$omp do
  do i=1,n

     arr(:) = (/ real(i,kind=8)**2, real(i,kind=8)**3, 1.0_8 /)

     ! uncommenting the following lines never produces an error
     !arr(1) = real(i,kind=8)**2
     !arr(2) = real(i,kind=8)**3
     !arr(3) = 1.0_8

     data(:,i) = arr(:)

  end do
  !$omp end do

  deallocate(arr)
  !$omp end parallel

  do i=1,n
     if ( data(1,i) /= real(i,kind=8)**2 ) then
        print*,'test failed'
        print*,real(i,kind=8)**2
        print*,data(1,i)
        stop
     end if
  end do

  print*,'test passed'
  deallocate(data)
end program arraytest



tim18
Total Points:
68,747
Status Points:
68,747
Black Belt
July 18, 2009 2:16 PM PDT
Rate
 
#3 Reply to #2
For me, it fails consistently when compiled with debug symbols, no optimization, as recommended for thread checker.  It seems it may use a shared temporary in the array constructor. 
If there is a race in the non-optimized implementation of the array constructor, depending on optimization to keep the values in register and avoid a race may produce results which depend on your compiler version.
With a current compiler, with optimization, instead of a race condition, Thread Checker complains about closing of a synchronization object at the final deallocate.  This doesn't make much sense to me, particularly as that deallocation would be performed implicitly at the end of the subroutine in any case.


Steve Lionel (Intel)
Total Points:
115,145
Status Points:
115,145
Black Belt
July 18, 2009 7:33 PM PDT
Rate
 
#4 Reply to #3
In some cases, array constructors are indeed not thread-safe.  This is a bug in the process of being fixed.



jimdempseyatthecove
Total Points:
36,397
Status Points:
36,397
Black Belt
July 19, 2009 7:12 AM PDT
Rate
 
#5 Reply to #2

On a whim, try:  real(kind=8), automatic, dimension(:), allocatable :: arr

Easy enough to try (add automatic).

Jim Dempsey

--------

Blog: The Parallel Void


www.quickthreadprogramming.com


tim18
Total Points:
68,747
Status Points:
68,747
Black Belt
July 19, 2009 8:59 AM PDT
Rate
 
#6 Reply to #5

On a whim, try:  real(kind=8), automatic, dimension(:), allocatable :: arr

Easy enough to try (add automatic).

Jim Dempsey
The posted code can be changed so as to eliminate arr() entirely, and verify that the problem isn't located there.  At first glance, I thought perhaps the private(arr) wasn't working, but that is easily eliminated as a cause of the reported problem.  Private clearly requires that each thread gets its own copy of the array, and that can't be influenced by adding the non-standard keyword to the declaration outside the parallel region.  If that were so, it would be another bug exposed by this example.
My thread checker did complain about both deallocate() violating synchronization objects, but I could move deallocate out of the parallel region without satisfying it.


jimdempseyatthecove
Total Points:
36,397
Status Points:
36,397
Black Belt
July 20, 2009 5:55 AM PDT
Rate
 
#7 Reply to #6

The point of the automatic on arr being:

Your intentions for arr were to have each thread have a separate copy.

For this to happen, each thread needs a seperate copy of not only the data but also the array descriptor.

Normally, enabling OpenMP, sets subroutines to default to RECURSIVE which makes "stack" declared array descriptors go on stack (as opposed to one static copy of the array descriptor as it does for non-recursive/non-OpenMP subroutines/functions).

Your (intended to be) "stack" array descriptor is declared inside PROGRAM not SUBROUTINE nor FUNCTION.

RECURSIVE is a prefix that can be placed on SUBROUTINE or FUNCTION (not PROGRAM). Therefore, should the compiler write(s) "fixed" OpenMP array descriptor on stack by flipping on RECURSIVE .AND. should RECURSIVE be ignored in PROGRAM, then the array descriptor may get place in static area.

Therefor, on a whim, add AUTOMATIC to the declaration of the arr as an alternate means to force the compiler to place the array descriptor for arr on the stack (as opposed to one static copy).

This is a trivial test for an assumption. Should this not fix the problem, then there is a deeper problem with multi-threaded array constructors. Should this fix the problem then you can raise the issue with Intel.

", automatic" 11 characters to make the test.

Jim Dempsey

--------

Blog: The Parallel Void


www.quickthreadprogramming.com


jimdempseyatthecove
Total Points:
36,397
Status Points:
36,397
Black Belt
July 20, 2009 6:03 AM PDT
Rate
 
#8 Reply to #7

Second alternative to avoid AUTOMATIC

take body of PROGRAM and place in SUBROUTINE FOO, then CALL FOO as only statement in PROGRAM.

If this fixes the problem then this reinforces my assumption about OpenMP using RECURSIVE to force descriptors to stack (.and. recursive not applicable to program). This also provides you with a standard work around while you hash out the issue with Intel as to how OpenMP is to handle array descriptors in PROGRAM.

Jim Dempsey

--------

Blog: The Parallel Void


www.quickthreadprogramming.com


Steve Lionel (Intel)
Total Points:
115,145
Status Points:
115,145
Black Belt
July 20, 2009 7:58 AM PDT
Rate
 
#9 Reply to #8
Enabling OpenMP implies -auto (which should be the same as adding RECURSIVE.)  The problem is that when the compiler sees an array constructor containing at least one constant, it tends to want to make it static, even when it shouldn't.  This will be fixed.  The issue ID is DPD200083317.



jimdempseyatthecove
Total Points:
36,397
Status Points:
36,397
Black Belt
July 20, 2009 8:04 PM PDT
Rate
 
#10 Reply to #9

And RECURSIVE applies to SUBROUTINE and FUNCTION not (necessarily) PROGRAM. The array descriptor was declared in PROGRAM (not SUBROUTINE and FUNCTION).

It would be interesting if the poster with the problem would ecapsulate the contents of their PROGRAM/END PROGRAM into a subrouting and call it. Thus establishing if the reported constructor problem is in actuality a faux pas w/rt PROGRAM/SUBROUTINE/FUNCTION.

The OpenMP option should force all non-SAVE'd array descriptors on stack by way of a seperate flag (as opposed to riding along implicitly with RECURSIVE).

Jim
--------

Blog: The Parallel Void


www.quickthreadprogramming.com


Steve Lionel (Intel)
Total Points:
115,145
Status Points:
115,145
Black Belt
November 3, 2009 8:55 AM PST
Rate
 
#11 Reply to #9
This should be fixed in 11.1 Update 2.





Intel Software Network Forums Statistics

8474 users have contributed to 31606 threads and 100656 posts to date.
In the past 24 hours, we have 30 new thread(s) 109 new posts(s), and 163 new user(s).

In the past 3 days, the most popular thread for everyone has been gemm(A,A,A) like possible? The most posts were made to gemm(A,A,A) like possible? The post with the most views is Dear Steve, excuse me for a d

Please welcome our newest member Kevin Johnson