- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi all,
I'm trying to compile a code with ifort v11.0 on a linux system and receive the following compiler error:
error #7636: This statement or directive is not permitted within the body of an OpenMP SINGLE directive
FORALL (t = 1:nrows)
----^
/afs/crc.nd.edu/user/t/tstitt/packages/cp2k/intel/cp2k/makefiles/../src/lib/dbcsr_methods.F(1183): error #7636: This statement or directive is not permitted within the body of an OpenMP SINGLE directive
END FORALL
----^
compilation aborted
...
Can anyone suggest a workaround?
Thanks.
Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Interesting, I don't know why SINGLE is not allowed. I can't find anything in the OpenMP 3.0 spec that forbids it.
As a workaround, try using the WORKSHARE directive; FORALL statements/constructs are allowed under WORKSHARE. Note that Intel's WORKSHARE is only executed by a single thread, so the semantics are equivalent to using SINGLE.
I'll find out from the OpenMP developers why we're disallowing FORALL under SINGLE. GNU accepts it:
Patrick Kennedy
Intel Developer Support
As a workaround, try using the WORKSHARE directive; FORALL statements/constructs are allowed under WORKSHARE. Note that Intel's WORKSHARE is only executed by a single thread, so the semantics are equivalent to using SINGLE.
I'll find out from the OpenMP developers why we're disallowing FORALL under SINGLE. GNU accepts it:
> cat U77885-OpenMP-single.f90
program U77885
implicit none
integer, parameter :: n=4
real x(n), y(n,n)
integer i
!$omp parallel
!$omp single
forall(i = 1:n) x(i) = i
!$omp end single
!$omp workshare
forall(i = 1:n) y(i, i) = 2.0 * x(i)
!$omp end workshare
!$omp end parallel
print *, 'y(i, i) =',(y(i, i), i=1,n)
end program U77885
> gfortran --version
GNU Fortran (GCC) 4.5.0 20090924 (experimental) [trunk revision 152147]
> gfortran -fopenmp U77885-OpenMP-single.f90
> ./a.out
y(i, i) = 2.0000000 4.0000000 6.0000000 8.0000000
>
Patrick Kennedy
Intel Developer Support
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Due to the implementation, as Patrick mentioned, the reported problem involves unexpected nested SINGLE regions. Patrick's suggestion removes the hidden duplication.
The next ifort release implements do concurrent, which fits some requirements better than forall.
The next ifort release implements do concurrent, which fits some requirements better than forall.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Tim,
>>problem involves unexpected nested SINGLE
Does this imply the FORALL is implicitly
!$OMP SINGLE
FORALL(...)
!$OMP END SINGLE
IOW the equivilent to the above !$OMP... being injected into the code stream?
Jim
>>problem involves unexpected nested SINGLE
Does this imply the FORALL is implicitly
!$OMP SINGLE
FORALL(...)
!$OMP END SINGLE
IOW the equivilent to the above !$OMP... being injected into the code stream?
Jim
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Compile the example above with the SINGLE directives removed, for example, with -openmp -S set. You would still see calls to __kmp_single and __kmp_end_single in the expansion of FORALL. I don't know if you consider it equivalent to what you wrote.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, that is what I would consider as equivilent.
The OP could use the workshare as mentioned or possibly
INTEGER :: SINGLETHREAD
SINGLETHREAD = -1
!$OMP PARALLEL SHARED(SINGLETHREAD)
...
!$OMP SINGLE
SINGLETHREAD = OMP_GET_THREAD_NUM()
!$OMP END SINGLE
IF(OMP_GET_THREAD_NUM() .EQ. SINGLETHREAD) THEN
... (original single code here up to but not including FORALL)
FORALL(...)
... (remainder of single code here)
ENDIF ! end single section
...
!$OMP END PARALLEL
Jim Dempsey
The OP could use the workshare as mentioned or possibly
INTEGER :: SINGLETHREAD
SINGLETHREAD = -1
!$OMP PARALLEL SHARED(SINGLETHREAD)
...
!$OMP SINGLE
SINGLETHREAD = OMP_GET_THREAD_NUM()
!$OMP END SINGLE
IF(OMP_GET_THREAD_NUM() .EQ. SINGLETHREAD) THEN
... (original single code here up to but not including FORALL)
FORALL(...)
... (remainder of single code here)
ENDIF ! end single section
...
!$OMP END PARALLEL
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FORALL will be accepted withina SINGLE directive in an update to the 12.1 compiler. It was a straight bug, pure and simple. I'll post an update here when a compiler with the fix is available.
Tracking number for this defect: DPD200161616
Patrick Kennedy
Intel Developer Support
Tracking number for this defect: DPD200161616
Patrick Kennedy
Intel Developer Support
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This issue isresolved in update #7 (package l_fcompxe_2011.7.256).
Patrick
Patrick

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page