MPI通信器是在Fortran中创建的,并传递给C,C随后又返回指向c_ptr
通信器的指针(C
)。这样做是为了避免为每个C
函数构造C
通信器。但是,当我尝试在C
中重用ReuseComm
通信器时,就会遇到分段错误。
Fortran模块
module mymodule
use mpi
use, intrinsic :: ISO_C_Binding, only: c_ptr, c_null_ptr
implicit none
private
interface
subroutine reuse_comm(comm) bind(C, name="reuse_comm")
import c_ptr
implicit none
type(c_ptr), intent(in) :: comm
end subroutine reuse_comm
function f_MPI_Comm_f2c(comm) result(optr) bind(C, name="f_MPI_Comm_f2c")
import c_ptr
implicit none
integer, intent(in) :: comm
type(c_ptr) :: optr
end function f_MPI_Comm_f2c
end interface
type(c_ptr), save :: ccomm = c_null_ptr
public :: CreateCcomm, ReuseComm, ccomm
CONTAINS
subroutine CreateCcomm(com)
integer, intent(in) :: com
ccomm = f_MPI_Comm_f2c(com)
end subroutine CreateCcomm
subroutine ReuseComm()
call reuse_comm(ccomm)
end subroutine ReuseComm
end module mymodule
Fortran驱动程序
program main
use mpi
use Tailor_module, only : CreateCcomm, ReuseComm, ccomm
use, intrinsic :: ISO_C_Binding, only: c_ptr
IMPLICIT NONE
integer error
call MPI_Init(error)
call CreateCcomm(MPI_COMM_WORLD)
call ReuseComm()
call MPI_Finalize (error)
end
C ++
extern "C"
{
MPI_Comm* f_MPI_Comm_f2c(MPI_Fint* f_handle)
{
MPI_Comm* comm;
comm = (MPI_Comm*)malloc(sizeof(MPI_Comm));
*comm = MPI_Comm_f2c(*f_handle);
assert(*comm != MPI_COMM_NULL);
int sizep = -1;
MPI_Comm_size(*comm, &sizep);
std::cout << "sizep: " << sizep << std::endl; // good, prints correct output.
return comm;
}
void reuse_comm(MPI_Comm* comm)
{
assert(comm != NULL);
assert(*comm != MPI_COMM_NULL);
int sizep = -1;
MPI_Comm_size(*comm, &sizep); // causes seg fault.
std::cout << "sizep: " << sizep << std::endl;
}
}