MPI_SENDRECV调用后MPI等级发生变化

时间:2016-08-09 09:40:37

标签: parallel-processing fortran mpi

我有一个简单的MPI_SENDRECV程序,用于在2D数组之间交换数据。 This帖子有同样的问题,这是由于在MPI_SENDRECV电话中输入的MPI类型,与实际发送/接收的内容不匹配。在下面的代码中,我尝试了交换双精度,单精度或整数,它们都产生了相同的行为。

program main                                                                                          
    use, intrinsic :: iso_fortran_env, sp=>real32, dp=>real64                                         
    use mpi                                                                                           
    implicit none                                                                                     
    integer :: ii, jj                                                                                 
    integer :: nprocs, myid                                                                    
    integer :: ierror, stat                                                                           
    integer :: Xsrc, Xdes, Ysrc, Ydes                                                                 
    integer, parameter :: grid_nx = 4                                                                 
    integer, parameter :: grid_ny = 4                                                                 
    integer, parameter :: proc_nx = 4 / 2                                                             
    integer, parameter :: proc_ny = 4 / 2                                                             
    integer, parameter :: buf     = 1                                                                 
    real(dp), allocatable, dimension(:,:) :: array                                                    

    ! MPI init                                                                                        
    call MPI_INIT(ierror)                                                                             
    call MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, ierror)                                                
    call MPI_COMM_RANK(MPI_COMM_WORLD,   myid, ierror)                                                
    print'(A,I1,A,I1,A)', "myid = ", myid, " out of ", nprocs, " processors."                                                                                 

    select case(myid)                                                                                 
        case(0)                                                                                       
            Xsrc = MPI_PROC_NULL; Xdes = 1                                                            
            Ysrc = MPI_PROC_NULL; Ydes = 2                                                            
        case(1)                                                                                       
            Xsrc = 0;             Xdes = MPI_PROC_NULL                                                
            Ysrc = MPI_PROC_NULL; Ydes = 3                                                            
        case(2)                                                                                       
            Xsrc = MPI_PROC_NULL; Xdes = 3                                                            
            Ysrc = 0;             Ydes = MPI_PROC_NULL                                                
        case(3)                                                                                       
            Xsrc = 2;             Xdes = MPI_PROC_NULL                                                
            Ysrc = 1;             Ydes = MPI_PROC_NULL                                                
    end select                                                                                        

    ! Init array                                                                                      
    allocate(array(0-buf:proc_nx-1+buf,0-buf:proc_ny-1+buf))                                          
    array(:,:) = -100._dp                                                                             
    do jj=0,proc_ny-1                                                                                 
        do ii=0,proc_nx-1                                                                             
            array(ii,jj) = (myid+1)*100._dp*(ii + 10._dp * jj) + myid * 10._dp                        
        end do                                                                                        
    end do                                                                                            
    if(myid==0) print*, "***************************************" 

    ! X buffer points                                                                                 
    call mpi_sendrecv(array(   0, 0:proc_ny-1),      proc_nx, MPI_DOUBLE, Xsrc, 200,&                 
                &     array(-buf, 0:proc_ny-1),      proc_nx, MPI_DOUBLE, Xsrc, 100,&                 
                &     MPI_COMM_WORLD, stat, ierror)                                                   

    call mpi_sendrecv(array(proc_nx-1, 0:proc_ny-1), proc_nx, MPI_DOUBLE, Xdes, 100,&                 
                &     array(proc_nx  , 0:proc_ny-1), proc_nx, MPI_DOUBLE, Xdes, 200,&                 
                &     MPI_COMM_WORLD, stat, ierror)          

    ! Y buffer points                                                                                 
    call mpi_sendrecv(array(0:proc_nx-1,   0),       proc_ny, MPI_DOUBLE, Ysrc, 300, &                
                &     array(0:proc_nx-1,-buf),       proc_ny, MPI_DOUBLE, Ysrc, 400, &                
                &     MPI_COMM_WORLD, stat, ierror)                                                   
    call mpi_sendrecv(array(0:proc_nx-1, proc_ny-1), proc_ny, MPI_DOUBLE, Ydes, 400, &                
                &     array(0:proc_nx-1, proc_ny  ), proc_ny, MPI_DOUBLE, Ydes, 300, &                
                &     MPI_COMM_WORLD, stat, ierror)                                                   

    print'(A,I1,A,I1,A)', "myid = ", myid, " out of ", nprocs, " processors."                         

    call MPI_FINALIZE(ierror)                                                                         
end program main

我用以下代码运行上面的代码:

mpirun -np 4 ./a.out

输出(并不总是这个顺序):

myid = 1 out of 4 processors.
myid = 2 out of 4 processors.
myid = 3 out of 4 processors.
myid = 0 out of 4 processors.
 ***************************************
myid = 0 out of 4 processors.
myid = 0 out of 4 processors.
myid = 0 out of 4 processors.
myid = 0 out of 4 processors.

如您所见,我的处理器等级在通话后会发生变化。我可能正在访问我不认为的内存部分。我是MPI的新手,所以我希望我没有犯任何愚蠢的错误。

0 个答案:

没有答案