mpi3分配共享内存的次数是否有限制

mpi3共享内存错误
我在使用mpi3中的共享内存,需要在各个进程中共享的是很多个小矩阵块(大约2300个),当我第2045次调用MPI_Win_allocate_shared函数后,会报错access violation,一开始我以为是分配了太多导致内存不够了,于是我将每个矩阵块的大小设置为2*2,结果当我第2045次调用MPI_Win_allocate_shared时仍然会报错access violation。不知道有没有做过相关问题的朋友能帮忙分析一下问题,下面是我的代码

program sharedmemtest
  USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR, C_F_POINTER
  use mpi
  !use global_parameter
  implicit none
  integer, parameter :: dp = selected_real_kind(14,200)
  integer ::hostcomm,hostrank
  INTEGER(KIND=MPI_ADDRESS_KIND) :: windowsize
  INTEGER :: disp_unit,my_rank,ierr,total
  integer i,size
  TYPE(C_PTR) ,allocatable:: baseptr(:)
  type matrix !新定义一个复数矩阵类型
      complex(8),pointer :: mat(:,:)
  end type !=========================
  TYPE(matrix),pointer :: NF_group_pair(:)
  
integer ,allocatable::win(:)
  call MPI_INIT( ierr )
  call MPI_COMM_RANK(MPI_COMM_WORLD,MY_RANK,IERR)
  call MPI_COMM_SIZE(MPI_COMM_WORLD,Total,IERR)
  CALL MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0, MPI_INFO_NULL, hostcomm,ierr)
  CALL MPI_Comm_rank(hostcomm, hostrank,ierr)
  
    allocate(NF_group_pair(2300))
    allocate(win(2300),baseptr(2300))
    if (hostrank == 0) then
        windowsize = int(2**2,MPI_ADDRESS_KIND)*16_MPI_ADDRESS_KIND
    else
        windowsize = 0_MPI_ADDRESS_KIND
    end if
        disp_unit = 1
  !此处是循环分配共享内存,但是在第2045次的时候就会报错
    do i = 1,2300
        CALL MPI_Win_allocate_shared(windowsize, disp_unit, MPI_INFO_NULL, hostcomm, baseptr(i), win(i), ierr)
        if (hostrank /= 0) then
           CALL MPI_Win_shared_query(win(i),  0, windowsize, disp_unit, baseptr(i),  ierr)
        end if
        CALL C_F_POINTER(baseptr(i), NF_group_pair(i)%mat,[2,2])
    end do

  call MPI_BARRIER(MPI_COMM_WORLD,ierr) 
  call MPI_FINALIZE(IERR)

  end program

  • MPI窗口数量上限了。你在循环中给每个矩阵都创建了一个新的窗口,导致在2045次时窗口数量达到了限制。
  • 创建一个不就行了,然后在窗口中给所有的矩阵分配内存。代码修改如下:
program sharedmemtest
  USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR, C_F_POINTER
  use mpi
  implicit none
  integer, parameter :: dp = selected_real_kind(14,200)
  integer ::hostcomm,hostrank
  INTEGER(KIND=MPI_ADDRESS_KIND) :: windowsize
  INTEGER :: disp_unit,my_rank,ierr,total
  integer i,size
  TYPE(C_PTR) :: baseptr
  type matrix !新定义一个复数矩阵类型
      complex(8),pointer :: mat(:,:)
  end type !=========================
  TYPE(matrix),pointer :: NF_group_pair(:)
  INTEGER :: win
  call MPI_INIT( ierr )
  call MPI_COMM_RANK(MPI_COMM_WORLD,MY_RANK,IERR)
  call MPI_COMM_SIZE(MPI_COMM_WORLD,Total,IERR)
  CALL MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0, MPI_INFO_NULL, hostcomm,ierr)
  CALL MPI_Comm_rank(hostcomm, hostrank,ierr)
    allocate(NF_group_pair(2300))
    if (hostrank == 0) then
        windowsize = int(2**2,MPI_ADDRESS_KIND)*16_MPI_ADDRESS_KIND*2300
    else
        windowsize = 0_MPI_ADDRESS_KIND
    end if
    disp_unit = 1
    CALL MPI_Win_allocate_shared(windowsize, disp_unit, MPI_INFO_NULL, hostcomm, baseptr, win, ierr)
    if (hostrank /= 0) then
       CALL MPI_Win_shared_query(win,  0, windowsize, disp_unit, baseptr,  ierr)
    end if
    do i = 1,2300
        CALL C_F_POINTER(baseptr, NF_group_pair(i)%mat,[2,2])
        baseptr = C_PTRADD(baseptr, 2**2*16)
    end do
  call MPI_BARRIER(MPI_COMM_WORLD,ierr) 
  call MPI_FINALIZE(IERR)
  end program

只在一个窗口中给所有的矩阵分配内存,再通过C_PTRADD函数移动指针的位置,获取每个矩阵的内存地址。

根据您提供的代码,问题出现在第2045次调用MPI_Win_allocate_shared函数时报错。这可能是由于共享内存的分配超出了系统的限制或者存在其他内存访问冲突导致的。

解决这个问题的方法可能有以下几种:

  1. 检查内存限制:请确保您所使用的系统支持并允许您分配如此多的共享内存。您可以尝试减少共享内存的大小,看是否仍然会出现错误。如果这是系统的限制,您可能需要考虑使用其他方法来实现您的目标。

  2. 检查内存访问冲突:确保在多个进程之间正确地进行数据访问。请检查您在使用共享内存时是否存在任何竞争条件或数据冲突。您可以尝试使用互斥锁或其他同步机制来确保数据的一致性和完整性。

  3. 调整代码逻辑:如果可能的话,您可以尝试重新设计代码逻辑,以减少对共享内存的需求。考虑是否可以使用其他通信模式或算法来代替共享内存,以达到您的目标。

另外,请注意,在您的代码中,您声明了一个名为my_rank的变量,但在后续使用时却使用了MY_RANK。请注意大小写敏感的问题,并确保变量名的一致性。

希望以上建议对您有所帮助!如果您有任何进一步的问题,请随时提问。

根据你提供的代码和描述,出现 "access violation" 错误可能是由于共享内存资源耗尽导致的。MPI的共享内存实现有可能存在资源限制,具体限制因MPI实现而异。你遇到的问题可能是超过了共享内存的资源限制。

解决这个问题的方法可能是:

  1. 检查系统和MPI的共享内存设置:检查你所使用的系统和MPI实现的文档,了解共享内存的资源限制,包括最大共享内存大小、可用的共享内存块数量等。

  2. 减小单个共享内存块的大小:你已经尝试将每个矩阵块的大小设置为2x2,但仍然遇到问题。你可以尝试进一步减小每个矩阵块的大小,以减少对共享内存资源的需求。

  3. 检查MPI_Win_allocate_shared的返回值:在调用MPI_Win_allocate_shared函数后,你可以检查返回值ierr以了解是否成功分配了共享内存。如果返回值非零,说明共享内存分配失败,你可以根据错误代码进一步排查问题。

  4. 联系MPI实现的支持:如果以上方法仍然无法解决问题,你可以联系MPI实现的支持团队,向他们提供更详细的错误信息和代码,以便他们能够更好地帮助你解决问题。

请注意,MPI的共享内存实现因MPI库的版本和底层系统的不同而异。因此,确保查阅与你所使用的MPI库和系统版本相对应的文档和资源,以获取准确的信息和解决方案。