【问题标题】:Undefined symbols for mpi_win_allocate_shared when compiling编译时 mpi_win_allocate_shared 的未定义符号
【发布时间】:2016-11-18 13:06:50
【问题描述】:

所以我正在尝试并行化我使用 MPI 的 Fortran 2003 程序。我在具有 64Gb 共享内存的 16 个处理器内核的节点上运行它。我的 MPI 通信器中的 16 个等级必须对一个相当大的数组(大约 6000 x 8000 个元素,双精度)的一部分应用一些算法。

现在,我使用MPI_BCAST 将该数组的副本从根级别发送到其他 15 个级别,这需要很多时间。大数组是只读的,所以我认为使用MPI_win_allocate_shared 让它对所有等级开放阅读并传递win 对象会更快。由于它是一个共享内存节点,因此应该可以正常工作。 (全部基于我在该主题的答案中找到的解释:MPI Fortran code: how to share data on node via openMP?

但是,当我尝试编译程序时,我收到以下错误消息:

Undefined symbols for architecture x86_64:
 "_mpi_win_allocate_shared_", referenced from:
      ___lakefinder_parallel_mpi_nam_module3_MOD_fill_sea_master in lakefinder_parallel_mpi_nam_module3.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status

不知道为什么,因为该程序使用了几个其他 MPI 命令(MPI_INIT、MPI_SEND、MPI_BCAST 等)并且可以正常工作。

有什么想法吗?

这是我的基本代码(只有相关部分,它是大型气候模型的一部分,我不会打扰你):

PROGRAM Main_program

USE mpi
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR, C_F_POINTER
USE configuration_main_module, only: dp  ! 8-byte float

IMPLICIT NONE

REAL(dp), DIMENSION(6000,8000) :: data_array
INTEGER                        :: ierr, rank, size, win, disp_unit
INTEGER(KIND=MPI_ADDRESS_KIND) :: windowsize
TYPE(C_PTR)                    :: baseptr

! Split program into ranks
CALL MPI_INIT(ierr)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr)
CALL MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)

! Open up a lot of space for the root rank and nothing for the others
IF (rank==0) THEN
  windowsize = 6000*8000*8_MPI_ADDRESS_KIND
ELSE
  windowsize = 0
END IF

disp_unit = 1
CALL MPI_Win_allocate_shared(windowsize, disp_unit, MPI_INFO_NULL, MPI_COMM_WORLD, baseptr, win, ierr)

CALL MPI_FINALIZE(ierr)

END PROGRAM Main_program

【问题讨论】:

  • MPI_WIN_ALLOCATE_SHARED 是 MPI-3.0 的一部分。您需要一个涵盖该标准版本或更高版本的实现。
  • 谢谢,那就这样吧。我刚刚安装了 openmpi-2.0.0 但显然卸载 1.10.3 版本没有正常工作(现在,即使我卸载了旧版本的代码仍然可以编译,所以某个地方有一个版本)。
  • 您的代码不是 Fortran 90。内在模块 iso_c_binding 是在 Fortran 2003 的后期定义的。
  • Open MPI 1.10.3 确实支持 MPI-3.0。那你的问题就是别的了。

标签: fortran mpi shared-memory


【解决方案1】:

以下代码在 Intel Fortran 16.0.2 和 MPICH 3.2 上编译和运行没有错误。请注意,我在退出之前触摸了分配的缓冲区并释放了窗口。我还选择了一个不会占用大量内存的数组维度。

您可以尝试使用较小的数组维度进行测试并按比例放大直到失败,以查看问题是否与共享内存资源不足有关,这在 Sys5 共享内存 API 中很常见,但在 POSIX 共享内存 API 中不常见.

如果不是资源问题,则可能是 Open-MPI 中的错误。请将错误报告给 Open-MPI 并切换到 MPICH。值得一提的是,我没有看到 Open-MPI 出现任何 MPI-3 共享内存问题,但我没有像其他人那样对其进行大量测试,而且我从不使用 Fortran 的 RMA。

PROGRAM Main_program

USE mpi
USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR, C_F_POINTER
use iso_fortran_env

IMPLICIT NONE

REAL(kind=REAL64), DIMENSION(60,80) :: data_array
INTEGER                        :: ierr, rank, size, win, disp_unit
INTEGER(KIND=MPI_ADDRESS_KIND) :: windowsize
TYPE(C_PTR)                    :: baseptr

! Split program into ranks
CALL MPI_INIT(ierr)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr)
CALL MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)

! Open up a lot of space for the root rank and nothing for the others
IF (rank==0) THEN
      windowsize = 60*80*8_MPI_ADDRESS_KIND
ELSE
      windowsize = 0
END IF

disp_unit = 1
CALL MPI_Win_allocate_shared(windowsize, disp_unit, MPI_INFO_NULL, MPI_COMM_WORLD, baseptr, win, ierr)
if (ierr .ne. 0) call MPI_Abort(MPI_COMM_WORLD, ierr, -1)
CALL MPI_Win_lock_all(0, win, ierr)
if (rank .eq. 0 ) data_array = 0
CALL MPI_Win_unlock_all(win, ierr)
CALL MPI_Win_free(win, ierr)

CALL MPI_FINALIZE(ierr)

END PROGRAM Main_program

【讨论】:

    猜你喜欢
    • 2013-03-07
    • 2015-05-23
    • 1970-01-01
    • 2010-12-31
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多