如何在MPI_Reduce中使用自定义精度?解决精度不被识别问题
MPI_Reduce无法识别自定义F90精度类型的问题解决
问题描述
在Fortran中使用MPI_TYPE_CREATE_F90_Real创建自定义双精度类型后,MPI_Reduce调用返回错误结果(0.0),但将MPI类型替换为MPI_DOUBLE时结果正常。另外,点对点通信MPI_Send/Recv可正常使用该自定义类型。
编译命令:
f2py -c --f90exec=mpif90 --fcompiler=gfortran --f90flags="-fopenmp" -lgomp test.f90 -m testsum
Fortran原代码:
Module testsum implicit none Contains subroutine Test(comm, vec, s) use mpi implicit none integer, intent(in) :: comm integer :: rank, ntask, ierr, stat Integer, Parameter :: dp = Selected_Real_Kind(15,307) integer :: I, N integer, allocatable :: workload(:) real (kind=dp), intent(in) :: vec(:) Real (kind=dp), intent(out) :: s real (kind=dp) :: si integer :: istart, iend, mpi_dp call MPI_Comm_size(comm, ntask, ierr) call MPI_Comm_rank(comm, rank, ierr) Call MPI_TYPE_CREATE_F90_Real(15, 307, mpi_dp, ierr) N = size(vec) Allocate(workload(ntask)) workload = N / ntask workload(1:mod(N,ntask)) = workload(1:mod(N,ntask)) + 1 istart = sum(workload(1:rank)) iend = istart + workload(rank+1) si = 0.0_dp s = 0.0_dp Do I = istart+1, iend si = si + vec(I) End Do Call MPI_reduce(si,s,1,MPI_dp,MPI_Sum,0,comm,ierr) Call MPI_Bcast(s,1,MPI_dp,0,comm,ierr) Print *, s end subroutine End Module
Python调用代码:
from mpi4py import MPI import numpy as np import testsum fcomm = MPI.COMM_WORLD.py2f() vec = np.ones(80) s = testsum.testsum.test(fcomm, vec) print(s)
解决方案
问题核心:自定义MPI数据类型必须通过MPI_TYPE_COMMIT提交后,才能用于集体通信操作。点对点通信(如MPI_Send/Recv)对未提交的类型有兼容性,但集体通信(MPI_Reduce、MPI_Bcast等)要求类型必须完成注册。
具体修改步骤:
- 在
MPI_TYPE_CREATE_F90_Real调用后,添加MPI_TYPE_COMMIT完成类型注册 - 在通信操作完成后,调用
MPI_TYPE_FREE释放类型资源(可选,但能避免内存泄漏)
修改后的Fortran关键代码片段:
Call MPI_TYPE_CREATE_F90_Real(15, 307, mpi_dp, ierr) ! 新增:提交自定义MPI类型 Call MPI_TYPE_COMMIT(mpi_dp, ierr) ! ... 原有计算和通信代码 ... Call MPI_reduce(si,s,1,MPI_dp,MPI_Sum,0,comm,ierr) Call MPI_Bcast(s,1,MPI_dp,0,comm,ierr) Print *, s ! 新增:释放自定义MPI类型 Call MPI_TYPE_FREE(mpi_dp, ierr)
额外注意事项
- 确保
Selected_Real_Kind(15,307)与MPI_TYPE_CREATE_F90_Real的参数(15位精度、307位指数范围)完全匹配,避免类型不兼容 - 确认使用的MPI实现(如OpenMPI、MPICH)支持
MPI_TYPE_CREATE_F90_Real接口,主流版本均已支持
内容的提问来源于stack exchange,提问作者Ruiheng Song
相关产品推荐
相关产品推荐

