Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!

Compiling Without Underscores and OMP

Kevin_T_
Beginner
196 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
Black Belt Retired Employee
196 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.

Kevin_T_
Beginner
196 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. 

Steve_Lionel
Black Belt Retired Employee
196 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.

jimdempseyatthecove
Black Belt
196 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
 

Steve_Lionel
Black Belt Retired Employee
196 Views

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

Kevin_T_
Beginner
196 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.

Reply