首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MPI Fortran编译器优化错误

MPI Fortran编译器优化错误
EN

Stack Overflow用户
提问于 2015-05-29 18:53:39
回答 1查看 1K关注 0票数 2

尽管已经编写了长的、高度并行化的代码,复杂的发送/接收超过了三维数组,但这段带有二维整数数组的简单代码已经让我束手无策。我梳理了堆叠溢出以寻找可能的解决方案,并发现了一个与我正在处理的问题有点相似的解决方案:

Boost.MPI: What's received isn't what was sent!

然而,解决方案似乎指出代码循环段是覆盖内存部分的罪魁祸首。但这个人似乎表现得更奇怪。也许是我疏忽了一些简单的细节。问题在于下面的代码:

代码语言:javascript
复制
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代码是否都是正确的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-29 19:21:22

在MPI中使用Fortran 90接口会发现调用MPI_RECV不匹配

代码语言:javascript
复制
      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)

这是因为状态变量stValinteger标量,而不是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)、

改变

代码语言:javascript
复制
integer :: rank, ierr, stVal

代码语言:javascript
复制
integer :: rank, ierr, stVal(mpi_status_size)

生成一个按预期工作的程序,用gfortran5.1和OpenMPI 1.8.5进行测试。

使用F90接口(use mpi vs include "mpif.h"),编译器可以在编译时检测不匹配的参数,而不是产生令人困惑的运行时问题。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30537036

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档