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.
I think it's because you're getting different routines. I suggest adding:
after the program statement. This will declare the OpenMP routines and constants.
That's what I settled on; basically replaced:
!$ integer, external :: omp_get_max_threads
!$ 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.
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.
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).
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.