[J3] [SC22WG5.6552] bind(C) external linkage issues on MacOS
Jeff Hammond
jehammond at nvidia.com
Fri Mar 15 17:28:55 UTC 2024
This is both an FYI for those of you who use MacOS but also a possible identification of a problem in how we specify 19.5.1.5 Linkage association.
Apple has removed “-commons use_dylibs” in recent versions of MacOS. This flag sets a non-default behavior of COMMON symbols (which include linkage associated bind(C) symbols that are not using obsolescent features) to be “U” (undefined) instead of “S” (uninitialized, small) https://linux.die.net/man/1/nm.
This flag is required to get a bind(C) module variable that points to a C global variable to work properly, as is potentially required by MPI. There are many reports of failures online with both GCC and Intel compilers (I can only verify the former).
It has been noted that our definition of linkage association may not be adequate to interact with C shared libraries. I don’t understand this topic well enough to have an opinion either way.
Has anybody else run into this or thought about it enough to know if there is a way to enhance our definition of linkage association so as to not require Fortran-specific linker options and behave more like C extern in shared libraries?
Thanks,
Jeff
jhammond at Jeff-M2 fortran % gcc -fPIC -shared extern2.c -o libxxx.so && gfortran -c extern.F90 && ld extern.o libxxx.so -L/opt/homebrew/Cellar/gcc/13.2.0/lib/gcc/current/ -lgfortran -commons use_dylibs -o extern && ./extern ; nm extern | grep MPI
MPIR_F08_MPI_IN_PLACE=0 &MPIR_F08_MPI_IN_PLACE=0x1003a4000 &MPIR_F08_MPI_IN_PLACE=4298784768
LOC(MPI_IN_PLACE)= 4298784768
LOC(buf)= 6168523360
sendbuf=0x1003a4000, sendbuf=4298784768
sendbuf is MPI_IN_PLACE? yes
recvbuf=0x16fac3260, recvbuf=6168523360
*count=1, *datatype=2, *op=3, *comm=4
911
U _MPIR_F08_MPI_IN_PLACE
U _MPI_Allreduce
jhammond at Jeff-M2 fortran % gcc -fPIC -shared extern2.c -o libxxx.so && gfortran -c extern.F90 && ld extern.o libxxx.so -L/opt/homebrew/Cellar/gcc/13.2.0/lib/gcc/current/ -lgfortran -o extern && ./extern ; nm extern | grep MPI
MPIR_F08_MPI_IN_PLACE=0 &MPIR_F08_MPI_IN_PLACE=0x102b1c000 &MPIR_F08_MPI_IN_PLACE=4340170752
LOC(MPI_IN_PLACE)= 4339777664
LOC(buf)= 6127137376
sendbuf=0x102abc080, sendbuf=4339777664
sendbuf is MPI_IN_PLACE? no
recvbuf=0x16d34b260, recvbuf=6127137376
*count=1, *datatype=2, *op=3, *comm=4
911
0000000100008080 S _MPIR_F08_MPI_IN_PLACE
U _MPI_Allreduce
==> extern2.c <==
#include <stdio.h>
#include <stdint.h>
int MPIR_F08_MPI_IN_PLACE;
void p(void)
{
printf("MPIR_F08_MPI_IN_PLACE=%d &MPIR_F08_MPI_IN_PLACE=%p &MPIR_F08_MPI_IN_PLACE=%zu\n",
MPIR_F08_MPI_IN_PLACE, &MPIR_F08_MPI_IN_PLACE, (intptr_t)&MPIR_F08_MPI_IN_PLACE);
}
void MPI_Allreduce(void ** sendbuf, void ** recvbuf,
int * count, int * datatype,
int * op, int * comm, int * ierror)
{
printf("sendbuf=%p, sendbuf=%zu\n", sendbuf, (intptr_t)sendbuf);
printf("sendbuf is MPI_IN_PLACE? %s\n",
(intptr_t)sendbuf==(intptr_t)&MPIR_F08_MPI_IN_PLACE ? "yes" : "no");
printf("recvbuf=%p, recvbuf=%zu\n", recvbuf, (intptr_t)recvbuf);
printf("*count=%d, *datatype=%d, *op=%d, *comm=%d\n",
*count, *datatype, *op, *comm);
*ierror = 911;
}
==> extern.F90 <==
module mpi
use iso_c_binding
!type(c_ptr), bind(C,name="MPI_F_IN_PLACE") :: MPI_IN_PLACE
integer(c_int), bind(C, name="MPIR_F08_MPI_IN_PLACE"), target :: MPI_IN_PLACE
interface
subroutine p() bind(C,name="p")
end subroutine
end interface
interface
SUBROUTINE MPI_ALLREDUCE(SENDBUF, RECVBUF, COUNT, DATATYPE, OP, COMM, IERROR) &
bind(C,name="MPI_Allreduce")
use iso_c_binding
import :: MPI_IN_PLACE
!DEC$ ATTRIBUTES NO_ARG_CHECK :: sendbuf,recvbuf
!GCC$ ATTRIBUTES NO_ARG_CHECK :: sendbuf,recvbuf
!$PRAGMA IGNORE_TKR sendbuf,recvbuf
!DIR$ IGNORE_TKR sendbuf,recvbuf
!IBM* IGNORE_TKR sendbuf,recvbuf
INTEGER(kind=c_int) :: SENDBUF(*), RECVBUF(*)
INTEGER(kind=c_int) :: COUNT, DATATYPE, OP, COMM, IERROR
END SUBROUTINE MPI_ALLREDUCE
end interface
end module mpi
program main
use mpi
implicit none
real :: buf(100)
integer :: ierror
call p
buf = 17
print*,'LOC(MPI_IN_PLACE)=',LOC(MPI_IN_PLACE)
print*,'LOC(buf)=',LOC(buf)
call MPI_ALLREDUCE(MPI_IN_PLACE,buf,1,2,3,4,ierror)
print*,ierror
end program main
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.j3-fortran.org/pipermail/j3/attachments/20240315/e714efe4/attachment.htm>
More information about the J3
mailing list