MPI_Scatterv编译报错:无对应通用子程序,求参数问题排查
MPI_Scatterv编译错误:"there is no specific subroutine for the generic 'mpi_scatterv'" 问题排查
你的编译错误直接源于MPI_Scatterv参数类型不匹配,同时代码中还存在几处逻辑问题,以下是具体分析和修正方案:
1. 直接导致编译错误的参数问题
MPI_Scatterv的标准接口中,第6个参数recvcount是单个整数,表示当前进程要接收的元素个数;但你传入了一个数组rcv_count(n_proc)。MPI无法匹配到对应参数类型的特定子程序,因此抛出编译错误。
修正方式:每个进程只需传入自己要接收的元素数量(单个整数),而非整个数组。
2. 其他需要修正的逻辑问题
2.1 接收缓冲区分配错误
你当前给所有进程固定分配rcv_buf(2,n_proc),这不符合实际需求——每个进程接收的元素数量不同,应该根据自身的接收个数动态分配。
2.2 Sendcounts计算逻辑缺陷
你用rem = mod(2*n,n_proc)计算剩余元素,可能导致余数为奇数,后续每次给sendcounts加2会导致总元素数与原数组不匹配。正确的做法应该以数据点个数n为基准计算余数,保证每个进程接收的元素数是偶数(对应完整的(x,y)对)。
2.3 隐式变量风险
代码注释掉了implicit none,导致x,y等变量隐式声明,容易引发类型错误,建议恢复该语句并显式声明所有变量。
修正后的关键代码片段
修正Sendcounts与Displs计算
rem = mod(n, n_proc) base = 2 * (n / n_proc) ! 每个进程基础接收的元素数(每个数据点2个real) allocate(sendcounts(n_proc), displs(n_proc)) summ = 0 do counter = 1, n_proc sendcounts(counter) = base ! 前rem个进程多接收一组数据(2个元素) if (counter <= rem) then sendcounts(counter) = sendcounts(counter) + 2 end if displs(counter) = summ summ = summ + sendcounts(counter) end do
动态分配接收缓冲区
! 每个进程计算自身接收的元素数 integer :: cnt rem = mod(n, n_proc) base = 2 * (n / n_proc) cnt = base if (my_id < rem) then cnt = cnt + 2 end if ! 按接收的元素数分配缓冲区(每2个元素对应1行) allocate(rcv_buf(2, cnt/2))
修正MPI_Scatterv调用
call MPI_Scatterv(r, sendcounts, displs, MPI_REAL, rcv_buf, cnt, MPI_REAL, 0, MPI_COMM_WORLD, ierr)
额外注意事项
- 确保所有进程都能正确获取
n的值(当前代码中只有主进程读取文件得到n,非主进程的n初始为0,会导致计算错误),需要在MPI初始化后将n广播给所有进程。 - 恢复
implicit none并显式声明所有变量,比如添加real :: x,y。
内容的提问来源于stack exchange,提问作者Dono Don
相关产品推荐
相关产品推荐

