You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

关于Fortran中MPI包装子例程从假定大小参数改为假定形状参数对MPI_SSEND执行影响的问询

关于Fortran中MPI包装子例程从假定大小参数改为假定形状参数对MPI_SSEND执行影响的问询

你好呀,我来帮你梳理这个问题~ 首先要给你点个赞,把旧的假定大小数组(integer :: buf(*))改成通用接口+不同秩的假定形状数组版本,这是非常符合现代Fortran编程规范的改进,也完美解决了你遇到的编译错误。

接下来核心问题:这种改动完全不会影响MPI_SSEND的执行逻辑和正确性,原因主要有这几点:

1. MPI的底层工作逻辑和Fortran数组类型无关

MPI本质上是直接操作连续内存块的,它并不关心Fortran里是用假定大小、假定形状还是显式形状数组传递数据——只要传递给MPI的内存地址指向的是连续的、符合count参数指定长度的有效数据区域,MPI就能正确完成发送操作。

2. 你的三个包装子例程都能正确匹配MPI的内存要求

我们逐个看:

  • 标量版本mpi_int_ssend_scalar里的buf是单个整数,传递给MPI_SSEND时,它会被当成一段长度为1的连续内存(这里要注意哦,你原来的标量调用里传了count=2,这其实是不符合逻辑的,可能是个小bug,但这和参数类型无关)。
  • 向量版本:假定形状数组integer, dimension(:) :: buf在Fortran中是连续存储的,和原来假定大小数组传递的内存块完全一致,MPI能直接读取所有元素。
  • 矩阵版本:Fortran采用列优先存储,假定形状数组integer, dimension(:,:) :: buf的内存布局和你之前用的假定大小数组完全相同,只要你计算的count参数正确(比如size(mort_no,1)*lnblocks),MPI就能准确发送所有矩阵元素。

额外的小建议

  • 可以考虑在标量版本的子例程里强制count=1,避免调用时传错count值引发错误;
  • 假定形状数组相比假定大小数组,编译器能提供更严格的类型检查和边界检查,能帮你更早发现代码中的内存访问问题;
  • 如果你后续还要扩展其他数据类型的MPI包装,可以继续沿用这种通用接口的模式,代码会更清晰易维护。

补充你提到的代码片段供参考:

原代码中报错的标量调用:

! -> PASSING SCALAR (ERROR GENERATED)
call mpi_int_ssend ( &
& new_loc(1, i), &
& 2, &
& MPI_INTEGER, &
& child(2, j, i), &
& child(1,j,i), &
& MPI_COMM_WORLD, &
& ierr &
& )

原假定大小参数的子例程:

subroutine mpi_int_ssend (buf, count, datatype, dest, tag, comm, ierror)
use mpi
integer :: buf(*)
integer :: count, datatype, dest, tag, comm, ierror
call mpi_ssend(buf, count, datatype, dest, tag, comm, ierror)
return
end subroutine mpi_int_ssend

新的通用接口和分秩子例程:

interface mpi_int_ssend
module procedure mpi_int_ssend_scalar
module procedure mpi_int_ssend_vector
module procedure mpi_int_ssend_matrix
end interface mpi_int_ssend

subroutine mpi_int_ssend_scalar (buf, count, datatype, dest, tag, comm, ierror)
use mpi
integer :: buf
integer :: count, datatype, dest, tag, comm, ierror
call mpi_ssend(buf, count, datatype, dest, tag, comm, ierror)
return
end subroutine mpi_int_ssend_scalar

subroutine mpi_int_ssend_vector(buf, count, datatype, dest, tag, comm, ierror)
use mpi
integer, dimension (:) :: buf
integer :: count, datatype, dest, tag, comm, ierror
call mpi_ssend(buf, count, datatype, dest, tag, comm, ierror)
return
end subroutine mpi_int_ssend_vector

subroutine mpi_int_ssend_matrix(buf, count, datatype, dest, tag, comm, ierror)
use mpi
integer, dimension (:, :) :: buf
integer :: count, datatype, dest, tag, comm, ierror
call mpi_ssend(buf, count, datatype, dest, tag, comm, ierror)
return
end subroutine mpi_int_ssend_matrix

备注:内容来源于stack exchange,提问作者Andris R.

火山引擎 最新活动