MPI Fortran代码处理大整数时计算结果异常求助
问题根源:MPI通信类型与自定义整型不匹配导致溢出
你的代码里定义了MyLongIntType(至少12位精度的64位整数)来存储大数值n和累加和,但在MPI_BCAST和MPI_REDUCE调用中,你用了MPI_INTEGER——这个类型通常对应32位整数,最大值仅为2147483647。当n≥1e10时,数值远超32位整数的上限,广播和归约过程中会被截断,最终得到错误结果(你看到的1410065408就是1e10对2^32取模的结果)。
解决方案
1. 匹配MPI数据类型
需要为自定义的长整型创建对应的MPI通信类型,或者直接使用编译器支持的预定义64位MPI整数类型:
- 方法一:用
MPI_TYPE_CREATE_F90_INTEGER生成匹配类型(跨编译器兼容) - 方法二:直接用
MPI_INTEGER8(GCC、Intel Fortran等主流编译器支持)
2. 修正代码中的关键问题
下面是修正后的完整代码,标注了修改点:
program test use mpi IMPLICIT NONE integer:: ierr, num_procs, my_id, root integer:: i integer, parameter :: MyLongIntType = selected_int_kind (12) integer(kind=MyLongIntType):: n, sum=0, partialsum=0, mypartialsum=0 real:: starttime, endtime ! 新增:定义匹配的MPI长整型类型 integer :: MPI_MyLongIntType root=0 call MPI_INIT ( ierr ) call MPI_COMM_RANK (MPI_COMM_WORLD, my_id, ierr) call MPI_COMM_SIZE (MPI_COMM_WORLD, num_procs, ierr) ! 生成匹配自定义类型的MPI数据类型 call MPI_TYPE_CREATE_F90_INTEGER(selected_int_kind(12), MPI_MyLongIntType, ierr) call MPI_TYPE_COMMIT(MPI_MyLongIntType, ierr) starttime = MPI_WTIME() if (my_id .eq. root) then print*, "Running in process 0." print*, "total number of process is", num_procs ! 修正:用自定义类型转换大数值,避免int8截断 n = int(1d10, kind=MyLongIntType) endif ! 修正:MPI_BCAST使用匹配的长整型类型 call MPI_BCAST(n, 1, MPI_MyLongIntType, 0, MPI_COMM_WORLD, ierr) mypartialsum=0 ! 修正:去掉浮点数赋值,用整数赋值 do i = my_id+1, n, num_procs mypartialsum = mypartialsum + 1 ! 简化:直接加1,无需int(1) enddo partialsum=mypartialsum print*, "Running process", my_id, "Partial sum is ", partialsum ! 修正:MPI_REDUCE使用匹配的长整型类型 call MPI_REDUCE(partialsum, sum, 1, MPI_MyLongIntType, MPI_SUM, ROOT, MPI_COMM_WORLD, ierr) endtime = MPI_WTIME() if (my_id .eq. 0) then print*, "sum is", sum, "time spent processing", endtime-starttime endif ! 释放自定义MPI类型 call MPI_TYPE_FREE(MPI_MyLongIntType, ierr) call MPI_FINALIZE ( ierr ) end program
额外注意点
- 避免用
int8(1d10):int8是8位整数类型,会直接截断大数值,必须用你定义的MyLongIntType来转换。 - 累加时直接用整数1:
mypartialsum+1比mypartialsum+int(1)更简洁,且避免不必要的类型转换。 - 如果编译器支持
MPI_INTEGER8,可以直接替换MPI_MyLongIntType,省去类型创建和提交的步骤,代码会更简洁。
内容的提问来源于stack exchange,提问作者M.Malvagio
相关产品推荐
相关产品推荐

