Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Allocatable arrays in OpenMP

eos_pengwern
Beginner
1,375 Views

Can anyone suggest why, when this code works perfectly:

do j=1, n

allocate(a(n, 2), b(n, 2), c(n, 2, 1))

do i=1, n
call foo(m, n, parms(i,j), results(i,j), a, b, c)
end do

deallocate(a,b,c)

call PrintResults(results)

end do

...this code fails with a message saying "allocatable array is already allocated":

call OMP_SET_NUM_THREADS(1)

!$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(i, j, a, b, c)
do j=1, n

allocate(a(n, 2), b(n, 2), c(n, 2, 1))

do i=1, n
call foo(m, n, parms(i,j), results(i,j), a, b, c)
end do

deallocate(a,b,c)

!$OMP CRITICAL
call PrintResults(results)
!$OMP END CRITICAL

end do
!$OMP END PARALLEL DO


As far as I know the use of an allocatable array as a private variable is perfectly legal OpenMP so long as the array is both allocated and deallocated within the parallel section, and broadly similar code (wth the same sort of allocate-deallocate structure) works well elsewhere in my application.

Thanks,
Stephen.

0 Kudos
6 Replies
pbkenned1
Employee
1,375 Views
Yes, it's fine to have an allocatable array in an OpenMP PRIVATE clause.

What compiler version are you using?Can you attach an example that reproduces the error?

I can't reproduce "allocatable array is already allocated", whether I use 1 thread or n threads (I'm using a 4 core system).

C:\>type allocable.f90

program F76780

include 'omp_lib.h' !need this for library calls

integer i,j,n,ithr

real, allocatable :: a(:,:), b(:,:), c(:,:,:)

n = 4

! call OMP_SET_NUM_THREADS(1) <<<=== just a comment...

!$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(i, j, a, b, c, ithr)

do j=1, n

allocate(a(n, 2), b(n, 2), c(n, 2, 1))

do i=1, n

! call foo(m, n, parms(i,j), results(i,j), a, b, c)

!$OMP CRITICAL

ithr = omp_get_thread_num()

print *,'thread = ',ithr,' j =',j,' i =',i

!$OMP END CRITICAL

end do

deallocate(a,b,c)

end do

!$OMP END PARALLEL DO

end program F76780

C:\>ifort -Qopenmp allocable.f90

Intel Visual Fortran Intel 64 Compiler Professional for applications running on Intel 64, Version 11.1 Build 20100414 Package ID: w_cprof_p_11.1.065

C:\>allocable.exe

thread = 0 j = 1 i = 1

thread = 1 j = 2 i = 1

thread = 2 j = 3 i = 1

thread = 3 j = 4 i = 1

thread = 0 j = 1 i = 2

thread = 1 j = 2 i = 2

thread = 2 j = 3 i = 2

thread = 3 j = 4 i = 2

thread = 0 j = 1 i = 3

thread = 1 j = 2 i = 3

thread = 2 j = 3 i = 3

thread = 3 j = 4 i = 3

thread = 0 j = 1 i = 4

thread = 1 j = 2 i = 4

thread = 2 j = 3 i = 4

thread = 3 j = 4 i = 4

C:\>

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,375 Views
Steven,

This sounds like an old version problem. If you are unable to update your compiler, then try adding array pointers pa, pb, and pc (same ranks as a, b, c)

!$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(i, j, pa, pb, pc)
do j=1, n
nullify(pa)
nullify(pb)
nullify(pc)
allocate(pa(n, 2), pb(n, 2), pc(n, 2, 1))
do i=1, n
call foo(m, n, parms(i,j), results(i,j), pa, pb, pc)
end do
deallocate(pa,pb,pc)
!$OMP CRITICAL
call PrintResults(results)
!$OMP END CRITICAL
end do
!$OMP END PARALLEL DO

Jim Dempsey
0 Kudos
eos_pengwern
Beginner
1,375 Views
This sounds like an old version problem. If you are unable to update your compiler, then try adding array pointers pa, pb, and pc (same ranks as a, b, c)

Thanks Patrick and Jim; I'm trying to do this with V11.1.051 and my support subscription has expired, but I'm planning to renew and upgrade in the next month or so.

In reality, "foo" has a few extra parameters which in the serial version of the program were pointers. When I first tried to parallelise this section of code, I kept getting "internal compiler errors" until I took the pointers out. In the current form with no pointers it will at least compile, and your feedback (together with similar feedback when I asked this same question in the OpenMP forum) has convinced me that at least my syntax is sane and there's no fatal flaw in my approach. Perhaps I'll accelerate that compiler upgrade.

Stephen.
0 Kudos
butette
Beginner
1,375 Views
Are ALLOCATABLE or POINTER arrays declared to be PRIVATE inside a parallel region allocated on the global heap or private stack for each thread as implemented by Intel compiler ?

Thanks.
0 Kudos
pbkenned1
Employee
1,375 Views
All allocatable arrays and pointer arrays are dynamically (heap) allocated, regardless of whether or not OpenMP is being used. If OpenMP is being used, ALLOCATABLE objects in a PRIVATE list are allocated from a heap local to each thread. On the other hand, if they are SHARED dynamic objects (specified in a SHARED list, or just by default), they are allocated from the global heap. Synchronization will be needed to avoid data races.

Patrick Kennedy
Intel Developer Support
0 Kudos
butette
Beginner
1,375 Views
Patrick,

So each thread maintains its thread-local heap as part of the global heap ? Is there any penalty/synchronization that I have to worry about when using thread local ALLOCATABLE objects ? Also if this is the case, why can't the compiler put automatic arrays on the heap when they are used inside a parallel region through the use of the -heap-arrays option ?

Thanks.
0 Kudos
Reply