Skip to content

Commit 2798fd8

Browse files
committed
Fortran mpi module: remove interface names
Fortran is a deceptively complicated language. It turns out that it is permissable to pass arrays of many sizes and shapes to subroutines that expect 1-dimensional array parameters. For example, a C programmer might look at the following subroutine declaration and assume that it means that the ARRAY_OF_REQUESTS parameter is a 1-dimensional array of any length: ``` MPI_WAITALL(COUNT, ARRAY_OF_REQUESTS, ARRAY_OF_STATUSES, IERROR) INTEGER COUNT, ARRAY_OF_REQUESTS(*), ARRAY_OF_STATUSES(MPI_STATUS_SIZE, *), IERROR ``` However, rules of the Fortran language allow the compiler to effectively morph non-1-dimensional array source parameters to match, for example, the 1-dimensional ARRAY_OF_REQUESTS dummy parameter. Sometimes this will be done by copy-in-copy-out; other times, the compiler can just swizzle the types to match because the source array data is already contiguous in memory. Regardless, there are several rules about when this type swizzling can happen, and there are differences in the rules between when the target subroutine in question is in a named interface such as: ``` INTERFACE FOO SUBROUTINE FOO(arg) INTEGER ARG(*) END SUBROUTINE FOO END INTERFACE ``` versus when the subroutine is in an unnamed interface such as: ``` INTERFACE SUBROUTINE FOO(arg) INTEGER ARG(*) END SUBROUTINE FOO END INTERFACE ``` I will not pretend to be a Fortran language expert and won't quote the language rules here. The short version is that unnamed interfaces allow more flexible type swizzling. For example, a user can pass a 2-dimensional INTEGER array to MPI_WAITALL's ARRAY_OF_REQUESTS argument, and -- assuming that the 2D array is contiguous in memory -- the compiler will make the 2D array type match the 1D ARRAY_OF_REQUESTS argument. Open MPI will get a contiguous chunk of memory of integers, so it doesn't know/care. The MPI standard does not address this issue at all. I.e., it doesn't say whether passing N-dimensional parameters to subroutines like MPI_WAITALL are permissable or not. It also does not specify whether interfaces need to be used, or if interfaces are used, whether they need to be named or unnamed -- these are all implementation decisions. However, there has been a lot of discussion about this in the Fortran group at the MPI Forum over the last week; there will almost certainly be an errata to MPI-4.0 and/or some text changes in MPI-4.1 to clarify the situation. I'm not going to speculate on the final language that will get accepted by the Forum, but it seems like since Open MPI's implentation decision to use named interfaces is perhaps the most restrictive in terms of compiler swizzling functionality, we should probably ease those restrictions so as not to violate the Law of Least Astonishment from the user's perspective (who would expect that the Fortran compiler will be able to swizzle array sizes and shapes). As such, this commit removes all interface names from the Fortran "mpi" bindings module where there's only a single subroutine in the interface, and that subroutine name exactly matches the interface name. Note that this specifically excludes the following routines, which have multiple subroutines in the interface (for two different types of Fortran pointers): * MPI_Alloc_mem * MPI_Win_allocate * MPI_Win_allocate_shared * MPI_Win_shared_query Deleting the interface names *may* cause ABI implications in some compilers. I have not exhaustively tested Fortran compilers to know if this is an issue or not. The safest thing to do is to implement this change for Open MPI v5.0.0 where we're breaking lots of ABI things as compared to prior versions of Open MPI. Note that this issue does *not* affect the mpi_f08 module. Using named interfaces were distinctly specified in the MPI standard. Also, this doesn't affect mpif.h, because Open MPI doesn't declare most interfaces/subroutines in mpif.h. Signed-off-by: Jeff Squyres <jsquyres@cisco.com>
1 parent d6d033f commit 2798fd8

9 files changed

+623
-613
lines changed

ompi/mpi/fortran/use-mpi-ignore-tkr/mpi-ignore-tkr-file-interfaces.h.in

Lines changed: 60 additions & 60 deletions
Large diffs are not rendered by default.

ompi/mpi/fortran/use-mpi-ignore-tkr/mpi-ignore-tkr-interfaces.h.in

Lines changed: 320 additions & 316 deletions
Large diffs are not rendered by default.

ompi/mpi/fortran/use-mpi-ignore-tkr/mpi-ignore-tkr-removed-interfaces.h.in

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
! -*- fortran -*-
22
!
3-
! Copyright (c) 2006-2012 Cisco Systems, Inc. All rights reserved.
3+
! Copyright (c) 2006-2021 Cisco Systems, Inc. All rights reserved
44
! Copyright (c) 2007 Los Alamos National Security, LLC. All rights
55
! reserved.
66
! Copyright (c) 2012 The University of Tennessee and The University
@@ -17,7 +17,7 @@
1717
!
1818
! $HEADER$
1919

20-
interface MPI_Address
20+
interface
2121

2222
subroutine MPI_Address(location, address, ierror)
2323
@OMPI_FORTRAN_IGNORE_TKR_PREDECL@ location
@@ -28,7 +28,7 @@ end subroutine MPI_Address
2828

2929
end interface
3030

31-
interface MPI_Attr_delete
31+
interface
3232

3333
subroutine MPI_Attr_delete(comm, keyval, ierror)
3434
integer, intent(in) :: comm
@@ -38,7 +38,7 @@ end subroutine MPI_Attr_delete
3838

3939
end interface
4040

41-
interface MPI_Attr_get
41+
interface
4242

4343
subroutine MPI_Attr_get(comm, keyval, attribute_val, flag, ierror)
4444
integer, intent(in) :: comm
@@ -50,7 +50,7 @@ end subroutine MPI_Attr_get
5050

5151
end interface
5252

53-
interface MPI_Attr_put
53+
interface
5454

5555
subroutine MPI_Attr_put(comm, keyval, attribute_val, ierror)
5656
integer, intent(in) :: comm
@@ -61,7 +61,7 @@ end subroutine MPI_Attr_put
6161

6262
end interface
6363

64-
interface MPI_Errhandler_create
64+
interface
6565

6666
subroutine MPI_Errhandler_create(function, errhandler, ierror)
6767
external :: function
@@ -71,7 +71,7 @@ end subroutine MPI_Errhandler_create
7171

7272
end interface
7373

74-
interface MPI_Errhandler_get
74+
interface
7575

7676
subroutine MPI_Errhandler_get(comm, errhandler, ierror)
7777
integer, intent(in) :: comm
@@ -81,7 +81,7 @@ end subroutine MPI_Errhandler_get
8181

8282
end interface
8383

84-
interface MPI_Errhandler_set
84+
interface
8585

8686
subroutine MPI_Errhandler_set(comm, errhandler, ierror)
8787
integer, intent(in) :: comm
@@ -91,7 +91,7 @@ end subroutine MPI_Errhandler_set
9191

9292
end interface
9393

94-
interface MPI_Keyval_create
94+
interface
9595

9696
subroutine MPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state, ierror)
9797
external :: copy_fn
@@ -103,7 +103,7 @@ end subroutine MPI_Keyval_create
103103

104104
end interface
105105

106-
interface MPI_Keyval_free
106+
interface
107107

108108
subroutine MPI_Keyval_free(keyval, ierror)
109109
integer, intent(inout) :: keyval
@@ -112,7 +112,7 @@ end subroutine MPI_Keyval_free
112112

113113
end interface
114114

115-
interface MPI_Type_extent
115+
interface
116116

117117
subroutine MPI_Type_extent(datatype, extent, ierror)
118118
integer, intent(in) :: datatype
@@ -122,7 +122,7 @@ end subroutine MPI_Type_extent
122122

123123
end interface
124124

125-
interface MPI_Type_hindexed
125+
interface
126126

127127
subroutine MPI_Type_hindexed(count, array_of_blocklengths, array_of_displacements, oldtype, newtype&
128128
, ierror)
@@ -136,7 +136,7 @@ end subroutine MPI_Type_hindexed
136136

137137
end interface
138138

139-
interface MPI_Type_hvector
139+
interface
140140

141141
subroutine MPI_Type_hvector(count, blocklength, stride, oldtype, newtype&
142142
, ierror)
@@ -150,7 +150,7 @@ end subroutine MPI_Type_hvector
150150

151151
end interface
152152

153-
interface MPI_Type_lb
153+
interface
154154

155155
subroutine MPI_Type_lb(datatype, lb, ierror)
156156
integer, intent(in) :: datatype
@@ -160,7 +160,7 @@ end subroutine MPI_Type_lb
160160

161161
end interface
162162

163-
interface MPI_Type_struct
163+
interface
164164

165165
subroutine MPI_Type_struct(count, array_of_blocklengths, array_of_displacements, array_of_types, newtype&
166166
, ierror)
@@ -174,7 +174,7 @@ end subroutine MPI_Type_struct
174174

175175
end interface
176176

177-
interface MPI_Type_ub
177+
interface
178178

179179
subroutine MPI_Type_ub(datatype, ub, ierror)
180180
integer, intent(in) :: datatype

ompi/mpi/fortran/use-mpi-ignore-tkr/mpi-ignore-tkr-status.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
!
33
! Copyright (c) 2020 Research Organization for Information Science
44
! and Technology (RIST). All rights reserved.
5+
! Copyright (c) 2021 Cisco Systems, Inc. All rights reserved
56
! $COPYRIGHT$
67
!
78
! Additional copyrights may follow
89
!
910
! $HEADER$
1011

1112

12-
interface MPI_Status_f082f
13+
interface
1314

1415
subroutine MPI_Status_f082f(f08_status, f_status, ierror)
1516
use mpi_types
@@ -22,7 +23,7 @@ end subroutine MPI_Status_f082f
2223
end interface
2324

2425

25-
interface MPI_Status_f2f08
26+
interface
2627

2728
subroutine MPI_Status_f2f08(f_status, f08_status, ierror)
2829
use mpi_types
@@ -35,7 +36,7 @@ end subroutine MPI_Status_f2f08
3536
end interface
3637

3738

38-
interface PMPI_Status_f082f
39+
interface
3940

4041
subroutine PMPI_Status_f082f(f08_status, f_status, ierror)
4142
use mpi_types
@@ -48,7 +49,7 @@ end subroutine PMPI_Status_f082f
4849
end interface
4950

5051

51-
interface PMPI_Status_f2f08
52+
interface
5253

5354
subroutine PMPI_Status_f2f08(f_status, f08_status, ierror)
5455
use mpi_types

ompi/mpi/fortran/use-mpi-tkr/mpi-f90-cptr-interfaces.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
! -*- fortran -*-
22
!
3-
! Copyright (c) 2014 Cisco Systems, Inc. All rights reserved.
3+
! Copyright (c) 2014-2021 Cisco Systems, Inc. All rights reserved
44
! $COPYRIGHT$
55
!
66
! Additional copyrights may follow
@@ -17,6 +17,7 @@
1717
! below.
1818
!
1919

20+
! This interface requires a name because there are multiple subroutines.
2021
interface MPI_Win_allocate
2122

2223
subroutine MPI_Win_allocate(size, disp_unit, info, comm, &
@@ -46,6 +47,7 @@ end subroutine MPI_Win_allocate_cptr
4647
end interface
4748

4849

50+
! This interface requires a name because there are multiple subroutines.
4951
interface MPI_Win_allocate_shared
5052

5153
subroutine MPI_Win_allocate_shared(size, disp_unit, info, comm, &
@@ -75,6 +77,7 @@ end subroutine MPI_Win_allocate_shared_cptr
7577
end interface
7678

7779

80+
! This interface requires a name because there are multiple subroutines.
7881
interface MPI_Win_shared_query
7982

8083
subroutine MPI_Win_shared_query(win, rank, size, disp_unit, baseptr,&

0 commit comments

Comments
 (0)