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

Compiling Without Underscores and OMP

Kevin_T_
Beginner
1,378 Views

Have a situation where the same code returns very different results when compiled with and without underscores (-assume (no)underscore).  For example:

program OMPUnderscore

  implicit none

  !$ integer,  external :: omp_get_max_threads
  integer :: max_threads

  !$ call omp_set_num_threads(5)  
  !$ max_threads = omp_get_max_threads()

  write(*,*) 'max_threads = ', max_threads  

end program OMPUnderscore

When compiled on Linux with "-assume underscore" the output is as expected ("max_threads = 5"), but when compiled with "-assume nounderscore" the output is something like "max_threads = 1234567".  I can work around that in a number of ways, but I'm curious as to why the above happens; what's going on behind the scenes that I don't understand?   I have a feeling it's something simple/obvious, but I'm currently at a loss.

0 Kudos
6 Replies
Steve_Lionel
Honored Contributor III
1,378 Views

I think it's because you're getting different routines. I suggest adding:

use omp_lib

after the program statement. This will declare the OpenMP routines and constants.

0 Kudos
Kevin_T_
Beginner
1,378 Views

Hi Steve,

That's what I settled on; basically replaced:

!$ integer, external :: omp_get_max_threads

with:

!$ use omp_lib, only: omp_get_max_threads

This works, which is great, but I kind of feel like a monkey pushing buttons until the banana falls down.

A week ago I might have told you that to the above were effectively "the same" in that they led to compiled to code that did the same thing.  Now that I know better, I'm trying to see how big the gap in my knowledge is.  Aesthetically I would prefer the latter way, but maybe the former is "better" in some way (esp. as this is part of an older codebase that I didn't write)? 

Bottom line, I'm not sure why the compiler would create different code here, and what advantages/disadvantages there might be in those differences. 

0 Kudos
Steve_Lionel
Honored Contributor III
1,378 Views

I'm unsure why the difference on Linux, and that isn't something I can test easily. The trailing underscore convention on Linux for Fortran routines allows libraries to distinguish C from Fortran. Given that there are a lot of OpenMP programs not using the modules, I'd guess that there is a omp_get_max_threads_ routine in the OMP libraries, but given that this routine has no arguments and returns a default integer (C int) result, I fail to see why it should differ from the omp_get_max_threads (no underscore) routine in the same library. Perhaps someone with a Linux install can investigate.

The definition in the omp_lib module uses BIND(C), so it doesn't apply the underscore convention, so I am even more puzzled that you say you get an unreasonable result with -assume nounderscore.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,378 Views

Kevin,

By not using omp_lib and not properly declaring the interface to omp_set_num_threads.

The Fortran compiler will assume that omp_set_num_threads is a Fortran subroutine
and as such, the argument is passed by reference (not value).
IOW the address of the (stack temporary copy of) the literal 5 will be used as the number of requested threads (an impossibly large number as the stack on the MAC may be in the negative address space).

Jim Dempsey
 

0 Kudos
Steve_Lionel
Honored Contributor III
1,378 Views

Ah, I completely overlooked the call to omp_set_num_threads! Thanks, Jim!

0 Kudos
Kevin_T_
Beginner
1,378 Views

Thanks Jim (and Steve) - that makes sense.  Will update the old code without worry.  I'm a relative newbie to Fortran, and I've learned a lot from both of you (both here and elsewhere); it's much appreciated.

0 Kudos
Reply