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

OpenMP and Modules

dajum
Novice
700 Views

I have a program that I have used openmp with a parallel sections:


SUBROUTINE OPERI
USE PARALLELOUT
call poutinit
!$OMP PARALLEL SECTIONS NUM_THREADS(2)
CALL OPER
CALL ENDPOUTPUT
!$OMP SECTION
CALL POUTPUT
!$OMP END PARALLEL SECTIONS
RETURN
END

All routines use the module:


MODULE PARALLELOUT
LOGICAL DOOUTPUT
INTEGER NUMFILLED
INTEGER NUMOUT
LOGICAL DONEFilling
LOGICAL DONEWriting
TYPE::FilesList
sequence
CHARACTER*1024 filename
INTEGER numItems
INTEGER FirstItemPtr
end TYPE

TYPE(FilesList), allocatable :: fnl(:)
REAL, allocatable :: outbuffer(:)
INTEGER FreeLoc
End module

This works fine in debug mode.  The code runs and generates perfect output.  But when I run in release mode it doesn't work.  The NUMFILLED variable gets incremented in one thread, and I can see it happen.  But the other thread never sees it get incremented.  I added write statements and see it has different values in the two threads, always staying with zero in the thread where I look at the value. I know there are two threads running as I have written out the thread numbers too.  I'm confused by why it works in debug and not in release.  Any idea's of what to look for that could cause this issue?

Thanks,

Dave

0 Kudos
6 Replies
Steven_L_Intel1
Employee
700 Views
I assume you know that module variables are static and that unsynchronized access can cause problems. Can you provide a small but complete program that demonstrates the problem?
0 Kudos
dajum
Novice
700 Views
Yes I know how it works. But I only set variables in one thread. Read in the other, so they should be fully synchronized. That's why I think the debug version works. But how can a static variable change in one thread and not the other? This is part of a huge program that I can't send in. But i'm working to distill it down and see if I can reproduce it. Dave
0 Kudos
dajum
Novice
700 Views
Okay I figured it out. I check the status of the other thread in a loop as below where NUMFILLED is incremented in one thread and compared to what is done in the second thread. DO WHILE(DOOUTPUT) IF(NUMFILLED .GT. NUMOUT)THEN DO my outputing ENDIF So what do I have to do to tell the compiler not to think my counter is constant inside the loop as it appears the optimizer put the load of memory outside of the loop. I take it the compiler isn't smart enough to understand parallel threads are active? I tested this by turning off optimization for the routine and viola it works fine. Thanks, Dave
0 Kudos
jimdempseyatthecove
Honored Contributor III
700 Views
Attribute NUMFILLED as VOLATILE Jim Dempsey
0 Kudos
dajum
Novice
700 Views
Thanks Jim! I obviously have to study some more on multi-threaded applications.
0 Kudos
Steven_L_Intel1
Employee
700 Views
Yes indeed. If the compiler does not know the variable can be accessed "invisibly" (such as from another thread), it is free to make a local copy for optimizations. Jim has the correct answer here.
0 Kudos
Reply