Description
Background information
What version of Open MPI are you using? (e.g., v3.0.5, v4.0.2, git branch name and hash, etc.)
We observed this while testing Open MPI 3.1.5 with the NVIDIA HPC SDK compilers, but we also see the same behavior in the current 4.1.5 release.
(Yes, we do understand that 3.1.5 is obsolete, but I have been told that we have an app that depends on this version for performance reasons until some additional functionality is implemented in UCX.)
Describe how Open MPI was installed
Downloaded source tarball. Set path to pick up NVIDIA HPC SDK compilers, then ran:
CC=nvc FC=nvfortran ./configure
Please describe the system on which you are running
This problem is independent of any particular operating system version and CPU type.
Details of the problem
This problem may be tangentially related to #9795.
In the recent 23.3 release nvfortran
, our compiler developers have added support fortype (*), dimension (*)
declarations in Fortran. Where previously (release 23.1 and before), the following test would fail with nvfortran
in ./configure
:
!
! Autoconf puts "program main" at the top
interface
subroutine force_assumed_shape(a, count)
integer :: count
complex, dimension(:,:) :: a
end subroutine force_assumed_shape
end interface
interface
subroutine foo(buffer, count)
!GCC$ ATTRIBUTES NO_ARG_CHECK :: buffer
type(*), dimension(*), intent(in) :: buffer
integer, intent(in) :: count
end subroutine foo
end interface
! Simple interface with an un-typed first argument (e.g., a choice buffer)
integer :: count
real :: buffer1(3)
character :: buffer2
complex :: buffer3(4,4)
complex, pointer, dimension(:,:) :: ptr
target :: buffer3
integer :: buffer4
ptr => buffer3
! Set some known values (somewhat irrelevant for this test, but just be
! sure that the values are initialized)
a = 17
buffer1(1) = 4.5
buffer1(2) = 6.7
buffer1(3) = 8.9
buffer2 = 'a'
! Call with one type for the first argument
call foo(buffer1, count)
! Call with a different type for the first argument
call foo(buffer2, count)
! Force us through an assumed shape
call force_assumed_shape(buffer3, count)
! Force a pointer call through an assumed shape (!)
ptr => buffer3
! Also try with a simple scalar integer
! (Intel 2016 compiler suite only partially supports GCC pragmas;
! they work with all the above buffer types, but fail with a
! simple scalar integer)
call foo(buffer4, count)
end program
subroutine force_assumed_shape(a, count)
integer :: count
real, dimension(:,:) :: a
call foo(a, count)
end subroutine force_assumed_shape
! Autoconf puts "end" after the last line
subroutine bogus
end
.
This test now succeeds with nvfortran
, causing ./configure
to incorrectly assume that nvfortran
supports the !GCC$ ATTRIBUTES NO_ARG_CHECK
directive.
Before, ./configure
would correctly fail down to the !DIR$ IGNORE_TKR
case:
checking for Fortran compiler support of !GCC$ ATTRIBUTES NO_ARG_CHECK… no
checking for Fortran compiler support of !DEC$ ATTRIBUTES NO_ARG_CHECK… no
checking for Fortran compiler support of !$PRAGMA IGNORE_TKR… no
checking for Fortran compiler support of !DIR$ IGNORE_TKR… yes
checking Fortran compiler ignore TKR syntax… 1:real, dimension(*):!DIR$ IGNORE_TKR
Now the !GCC$ ATTRIBUTES NO_ARG_CHECK
test succeeds, causing ./configure
to incorrectly assume that nvfortran
supports this directive.
This, in turn, causes Open MPI to generate incorrect Fortran interfaces with nvfortran
that use !GCC$ ATTRIBUTES NO_ARG_CHECK ::
rather than the standard !DIR$ IGNORE_TKR
directive.
According to our Fortran language expert:
Their test, which has the statement type( * ), dimension( * ), intent(in) :: buffer , should not produce an error no matter the directive used. But they incorrectly use the !GCC$ directive when an error is not produced. The Fortran standard says an error should not occur. Here is the citation:
Fortran 2018 Standard, 15.5.2.4 Ordinary dummy variables (paragraph 14), we have the following:
If the actual argument is a noncoindexed scalar, the corresponding dummy argument shall be scalar unless
• the actual argument is default character, of type character with the C character kind (18.2.2), or is an
element or substring of an element of an array that is not an assumed-shape, pointer, or polymorphic array,
• the dummy argument has assumed-rank, or
• the dummy argument is an assumed-type assumed-size array.
The third bullet applies. Assumed type is type( * ) and assumed size is dimension( * ). In other words, type shall be ignored and one can either pass a rank 1 array or scalar argument to type( * ), dimension( * ), intent(in) :: buffer.
Thus, he believes this test should pass for all standards-compliant Fortran compilers, and it should not assume that the GCC directive is needed here.
Could you take a look at this ./configure
test and consider if the logic here is correct?
Thanks in advance.