- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When using ifort I encounter a segfault at "DEALLOCATE(test)" in the following code:
program demo INTEGER, DIMENSION(:), ALLOCATABLE :: test ALLOCATE(test(1)) PRINT *, "Before parallel region:" IF (ALLOCATED(test)) THEN PRINT *, " Test already allocated. Location:", LOC(test) ELSE PRINT *, " Test not allocated." ENDIF PRINT * PRINT *, "Within parallel region:" !$omp parallel num_threads(2) default(none) private(test) IF (ALLOCATED(test)) THEN PRINT *, " Test already allocated. Location:", LOC(test) PRINT *, " Deallocating..." DEALLOCATE(test) ELSE PRINT *, " Test not allocated." ENDIF !$omp end parallel end program demo
Output is the following:
Before parallel region:
Test already allocated. Location: 46912518012896
Within parallel region:
Test already allocated. Location: 140737488326928
Test already allocated. Location: 46912522410000
Deallocating...
Deallocating...
forrtl: severe (174): SIGSEGV, segmentation fault occurred
The output shows that (as expected) new private instances of test are created for each of the two threads at different memory locations. Both are already allocated as the OpenMP standard requires (Section 2.19.3, note on Fortran). However, when trying to deallocate them, a segfault occurs.
I cross-checked this with gfortran and the Cray ftn compiler and both have no issues with this code. So is this a bug in ifort or am I doing something illegal here? I'm using ifort in version 19.0.4.243 20190416.
Side note: Of course this is a very constructed example. Originally I encountered this issue using private instances of a more complex data structure that re-allocates some buffers on-demand.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In older versions of Fortran the behavior of passing in an unallocated array as private(array) resulted in the parallel region having an uninitialized array descriptor. The correction for this was to use firstprivate(array) such that the unallocated array descriptor was copied into the copy in the parallel region.
What are the results of your test program after changing private(test) to firstprivate(test)?
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove (Blackbelt) wrote:In older versions of Fortran the behavior of passing in an unallocated array as private(array) resulted in the parallel region having an uninitialized array descriptor.
Note that in my case the array is already allocated before entering the parallel region. If I leave it unallocated, the private copies are unallocated as well and I can allocate them within the threads without problems. Here's a slightly modified version for demonstration:
program demo INTEGER, DIMENSION(:), ALLOCATABLE :: test ! ALLOCATE(test(1)) PRINT *, "Before parallel region:" IF (ALLOCATED(test)) THEN PRINT *, " Test already allocated. Location:", LOC(test) ELSE PRINT *, " Test not allocated." ENDIF PRINT * PRINT *, "Within parallel region:" !$omp parallel num_threads(2) default(none) private(test) IF (ALLOCATED(test)) THEN PRINT *, " Test already allocated. Location:", LOC(test) PRINT *, " Deallocating..." DEALLOCATE(test) ELSE PRINT *, " Test not allocated." PRINT *, " Allocating..." ALLOCATE(test(1)) ENDIF !$omp end parallel end program demo
Output:
Before parallel region:
Test not allocated.
Within parallel region:
Test not allocated.
Test not allocated.
Allocating...
Allocating...
jimdempseyatthecove (Blackbelt) wrote:
The correction for this was to use firstprivate(array) such that the unallocated array descriptor was copied into the copy in the parallel region.
What are the results of your test program after changing private(test) to firstprivate(test)?
The segfault still occurs when changing private() to firstprivate().
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>Note that in my case the array is already allocated before entering the parallel region.
At issue, in the older versions of Intel Fortran, private(array) would not initialize an empty array descriptor, additionally the uninitialized array descriptor could, at times, report allocated as .true. Using firstprivate(array) would correct for this.
Seeing that in the past there had been an issue with private(array), even though your have the array allocated, I suggested that you try firstprivate(array) in the event that this old problem resurfaced itself. Your observation "The segfault still occurs when changing private() to firstprivate()" indicates that this is an entirely new problem.
Your test code is suitable to submit to Intel as a reproducer of the problem.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks! I sent in a report as ticket #04378880.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I saw your issue come in. So let me ask a stupid question: What exactly do you expect to happen with the deallocate?
You want to deallocate the thread-private copy of test(:) right? you are NOT suggesting that you expect the threads to deallocate TEST outside of the parallel region, correct? You know that would be a race condition IF that is what you are trying to do. The only thing that makes sense here, if it's legal at all, is to deallocate the thread local copies of TEST and leave the outside TEST alone - this IS what you intend yes?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for looking into this! Exactly, I would expect the private copy within the thread to be deallocated so that the thread can for example reallocate its own copy with a different size. This is what seems to happen using gfortran. The original array outside of the parallel region of course must not be altered at all.
However, I am also not entirely sure if this is a legal operation according to the standard which is why I opened this thread in the forum first. The OpenMP standard only says that the private copies must be allocated if the original array is allocated when entering the parallel region. I'm not sure if this implies that it must be possible to de-/reallocate.
Anyway, a segfault at runtime seems to me like a bug. If it is an illegal thing to do, the compiler should probably error out at compile time.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>The original array outside of the parallel region of course must not be altered at all
At issue here can be an implementation issue whereby the main thread of the region, when it happens to be one of the two threads within the parallel region, uses:
a) the original copy of the array, or
b) uses a copy of the original array
Jim Dempsey
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page