我在fortran中使用MPI来计算我的数据。我通过打印数据来验证,每个进程正在对所需的范围执行计算,但是,主数据无法整理数据。
以下是我尝试使其工作的代码: 编辑:为send和recv创建一个常量的标记
integer :: tag
tag = 123
if(pid.ne.0) then
print *,'pid: ',pid,'sending'
DO j = start_index+1, end_index
CALL MPI_SEND(datapacket(j),1, MPI_REAL,0, tag, MPI_COMM_WORLD)
!print *,'sending'
END DO
print *,'send complete'
else
DO slave_id = 1, npe-1
rec_start_index = slave_id*population_size+1
rec_end_index = (slave_id + 1) * population_size;
IF (slave_id == npe-1) THEN
rec_end_index = total-1;
ENDIF
print *,'received 1',rec_start_index,rec_end_index
CALL MPI_RECV(datapacket(j),1,MPI_REAL,slave_id,tag,MPI_COMM_WORLD, &
& status)
!print *,'received 2',rec_start_index,rec_end_index
END DO
它永远不会在received
调用之后打印MPI_RECV
或任何内容但是,我可以看到发送发生就好了,但是除了依赖print语句之外我无法验证它。
变量databpacket
初始化如下:
real, dimension (:), allocatable :: datapacket
我在这里做错了什么?
编辑:对于测试设置,所有进程都在localhost上运行。
答案 0 :(得分:0)
您正在为所有发送使用不同的消息标记,但是在您的接收中,您只使用j,它在根进程中永远不会被更改。另请注意,您的实现看起来像MPI_Gather,我建议您使用它而不是自己实现。
编辑:对不起,在您更新后我现在意识到,您实际上是从每个排名> 0(start_index + 1到end_index)发送多封邮件,如果您需要,您需要让标签区分个人信息。但是,您还需要在主服务器上拥有多个接收。 也许最好陈述一下你真正想要实现的目标。
你想要这样的东西:
integer :: tag
tag = 123
if(pid.ne.0) then
print *,'pid: ',pid,'sending'
CALL MPI_SEND(datapacket(start_index+1:end_index),end_index-start_index, MPI_REAL,0, tag, MPI_COMM_WORLD)
!print *,'sending'
print *,'send complete'
else
DO slave_id = 1, npe-1
rec_start_index = slave_id*population_size+1
rec_end_index = (slave_id + 1) * population_size;
IF (slave_id == npe-1) THEN
rec_end_index = total-1;
ENDIF
print *,'received 1',rec_start_index,rec_end_index
CALL MPI_RECV(datapacket(rec_start_index:rec_end_index),rec_end_index-rec_start_index+1,MPI_REAL,slave_id,tag,MPI_COMM_WORLD, &
& status)
!print *,'received 2',rec_start_index,rec_end_index
END DO
end if