尽管已经编写了长的、高度并行化的代码,复杂的发送/接收超过了三维数组,但这段带有二维整数数组的简单代码已经让我束手无策。我梳理了堆叠溢出以寻找可能的解决方案,并发现了一个与我正在处理的问题有点相似的解决方案:
Boost.MPI: What's received isn't what was sent!
然而,解决方案似乎指出代码循环段是覆盖内存部分的罪魁祸首。但这个人似乎表现得更奇怪。也许是我疏忽了一些简单的细节。问题在于下面的代码:
program main
implicit none
include 'mpif.h'
integer :: i, j
integer :: counter, offset
integer :: rank, ierr, stVal
integer, dimension(10, 10) :: passMat, prntMat !! passMat CONTAINS VALUES TO BE PASSED TO prntMat
call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
counter = 0
offset = (rank + 1)*300
do j = 1, 10
do i = 1, 10
prntMat(i, j) = 10 !! prntMat OF BOTH RANKS CONTAIN 10
passMat(i, j) = offset + counter !! passMat OF rank=0 CONTAINS 300..399 AND rank=1 CONTAINS 600..699
counter = counter + 1
end do
end do
if (rank == 1) then
call MPI_SEND(passMat(1:10, 1:10), 100, MPI_INTEGER, 0, 1, MPI_COMM_WORLD, ierr) !! SEND passMat OF rank=1 to rank=0
else
call MPI_RECV(prntMat(1:10, 1:10), 100, MPI_INTEGER, 1, 1, MPI_COMM_WORLD, stVal, ierr)
do i = 1, 10
print *, prntMat(:, i)
end do
end if
call MPI_FINALIZE(ierr)
end program main当我使用没有标志的mpif90编译代码并使用mpirun -np 2在我的计算机上运行它时,在数组的前四个索引中得到了以下输出,其中值错误:
0 0 400 0 604 605 606 607 608 609 610 611 612 613 614 616 616 618 618 619 620 621 622 623624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647648 649 650 651 652 653 654 655 655 657 659 660 661 662 663 664 665 666 667 668 669 670 671672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 689 690 691 692 693 694 695696 697 698 699
然而,当我用相同的编译器编译它,但是打开-O3标志时,我得到了正确的输出:
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 616 616 618 618 619 620 621 622 623624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647648 649 650 651 652 653 654 655 655 657 659 660 661 662 663 664 665 666 667 668 669 670 671672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 689 690 691 692 693 694 695696 697 698 699
此错误与机器有关。此问题仅在运行Ubuntu14.04.2的系统上出现,使用OpenMPI 1.6.5
我在运行RedHat和CentOS的其他系统上尝试了这种方法,并且使用和不带-O3标志的代码运行良好。奇怪的是,这些机器使用的是OpenMPI - 1.4的旧版本。
我猜想-O3标志正在执行一些奇怪的优化,即修改进程之间传递数组的方式。
我还尝试了其他版本的数组分配。以上代码使用显式形状数组。假设的形状和分配的数组,我收到了同样的,如果不是更奇怪的结果,其中一些断断续续。我试着使用Val差伦来跟踪这些故障的来源,但我仍然没有掌握让Val差伦在MPI程序运行时不会给出错误的窍门。
我相信,解决上述代码的性能差异将帮助我理解我的其他代码的愤怒。
任何帮助都将不胜感激!这段代码真的让我怀疑我写的其他MPI代码是否都是正确的。
发布于 2015-05-29 19:21:22
在MPI中使用Fortran 90接口会发现调用MPI_RECV不匹配
call MPI_RECV(prntMat(1:10, 1:10), 100, MPI_INTEGER, 1, 1, MPI_COMM_WORLD, stVal, ierr)
1
Error: There is no specific subroutine for the generic ‘mpi_recv’ at (1)这是因为状态变量stVal是integer标量,而不是MPI_STATUS_SIZE数组。F77与MPI_RECV的接口(include 'mpif.h')是:
包括‘mpif.h’MPI_RECV(BUF、COUNT、DATATYPE、SOURCE、TAG、COMM、STATUS、IERROR) BUF(*)整数计数、数据类型、源、标记、通信整数状态(MPI_STATUS_SIZE)、
改变
integer :: rank, ierr, stVal至
integer :: rank, ierr, stVal(mpi_status_size)生成一个按预期工作的程序,用gfortran5.1和OpenMPI 1.8.5进行测试。
使用F90接口(use mpi vs include "mpif.h"),编译器可以在编译时检测不匹配的参数,而不是产生令人困惑的运行时问题。
https://stackoverflow.com/questions/30537036
复制相似问题