我已经花了好几天时间搜索了很多东西(包括这个网站和Fortran文档)所以请原谅我这是否真的是一个非常简单的问题,但我在Fortran中相对缺乏经验并来自于C ++ / C#/ Java背景。 我正在使用F90 MPI编译器,因此我无法使用任何更新的功能,而且我没有选择。
我试图将MPI函数包装成一个通信层并封装直接的MPI交互(只是不能动摇那些OO的习惯!)。为此,我需要将数据传递给我的包装函数。
MPI spec有这个原型,例如:
INCLUDE ’mpif.h’
MPI_SEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, IERROR)
<type> BUF(*)
INTEGER COUNT, DATATYPE, DEST, TAG, COMM, IERROR
我的子程序是这样的:
SUBROUTINE empi_wrap_open_send(sendbuf, size, targetid, the_type)
我不得不添加'the_type'让我通过{*}传递正确的MPI dataype。但是,我无法将子程序的后续内部声明'sendbuf'编译。我试过了:
TYPE(C_PTR) :: sendbuf !with 'USE iso_c_binding'
TYPE :: sendbuf(*)
POINTER :: sendbuf
POINTER, TYPE(*) :: sendbuf
我的最后一招是取消我的'IMPLICIT NONE',但我担心这样会导致灾难! 关于如何正确地做到这一点的任何提示,我将非常感激。肯定不是那么难吗?
{*}我宁愿做运行时类型检查,即:
SELECT TYPE (sendbuf)
TYPE is (INTEGER)
empi_type = MPI_INTEGER
TYPE is (DOUBLE)
empi_type = MPI_DOUBLE_PRECISION
END SELECT
但我可以忍受黑客攻击。
答案 0 :(得分:3)
我会使用泛型。当然,它带来了一些代码重复,但你得到了类型检查和其他好的功能。以下是我在生产中使用的实际代码的片段。我没有发现以这种方式包装Send和Recv是有用的(我使用不同的内部过程作为包装器),但我确实包装了MPI colectives。最后一个函数显示您根本不必传递大小。
interface mpi_co_min
module procedure mpi_co_min_32
module procedure mpi_co_min_64
end interface
...
interface mpi_co_reduce
module procedure mpi_co_reduce_32
module procedure mpi_co_reduce_64
module procedure mpi_co_reduce_32_1d
...
end interface
...
function mpi_co_min_32(x) result(res)
real(real32) :: res
real(real32),intent(in) :: x
integer ie
res = mpi_co_reduce(x, MPI_MIN, global_comm)
end function
function mpi_co_min_64(x) result(res)
real(real64) :: res
real(real64),intent(in) :: x
integer ie
res = mpi_co_reduce(x, MPI_MIN, global_comm)
end function
function mpi_co_reduce_32(x,op,comm) result(res)
real(real32) :: res
real(real32),intent(in) :: x
integer, intent(in) :: op, comm
integer ie
call MPI_AllReduce(x, res, &
count=1, datatype=MPI_MI_REAL32, op=op, &
comm=comm, ierror=ie)
end function
function mpi_co_reduce_64(x,op,comm) result(res)
real(real64) :: res
real(real64),intent(in) :: x
integer, intent(in) :: op, comm
integer ie
call MPI_AllReduce(x, res, &
count=1, datatype=MY_MPI_REAL64, op=op, &
comm=comm, ierror=ie)
end function
function mpi_co_reduce_32_1d(x,op,comm) result(res)
real(real32),intent(in) :: x(:)
real(real32) :: res(size(x))
integer, intent(in) :: op, comm
integer ie
call MPI_AllReduce(x, res, &
count=size(x), datatype=MY_MPI_REAL32, op=op, &
comm=comm, ierror=ie)
end function