2016-05-14 536 views
1

我想在进程之间使用共享内存。我试图MPI_Win_allocate_shared但是当我执行程序它给了我一个奇怪的错误:MPI:如何正确使用MPI_Win_allocate_shared

断言文件./src/mpid/ch3/include/mpid_rma_shm.h在行592失败:local_target_rank >= 0 internal ABORT

这里是我的源:

# include <stdlib.h> 
# include <stdio.h> 
# include <time.h> 

# include "mpi.h" 

int main (int argc, char *argv[]); 
void pt(int t[], int s); 

int main (int argc, char *argv[]) 
{ 
    int rank, size, shared_elem = 0, i; 
    MPI_Init (&argc, &argv); 
    MPI_Comm_rank (MPI_COMM_WORLD, &rank); 
    MPI_Comm_size (MPI_COMM_WORLD, &size); 
    MPI_Win win; 
    int *shared; 

    if (rank == 0) shared_elem = size; 
    MPI_Win_allocate_shared(shared_elem*sizeof(int), sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &shared, &win); 
    if(rank==0) 
    { 
     MPI_Win_lock(MPI_LOCK_EXCLUSIVE, 0, MPI_MODE_NOCHECK, win); 
     for(i = 0; i < size; i++) 
     { 
      shared[i] = -1; 
     } 
     MPI_Win_unlock(0,win); 
    } 
    MPI_Barrier(MPI_COMM_WORLD); 
    int *local = (int *)malloc(size * sizeof(int)); 
    MPI_Win_lock(MPI_LOCK_SHARED, 0, 0, win); 
    for(i = 0; i < 10; i++) 
    { 
     MPI_Get(&(local[i]), 1, MPI_INT, 0, i,1, MPI_INT, win); 
    } 
    printf("processus %d (avant): ", rank); 
    pt(local,size); 
    MPI_Win_unlock(0,win); 

    MPI_Win_lock(MPI_LOCK_EXCLUSIVE, 0, 0, win); 

    MPI_Put(&rank, 1, MPI_INT, 0, rank, 1, MPI_INT, win); 

    MPI_Win_unlock(0,win); 

    MPI_Win_lock(MPI_LOCK_SHARED, 0, 0, win); 
    for(i = 0; i < 10; i++) 
    { 
     MPI_Get(&(local[i]), 1, MPI_INT, 0, i,1, MPI_INT, win); 
    } 
    printf("processus %d (apres): ", rank); 
    pt(local,size); 
    MPI_Win_unlock(0,win); 


    MPI_Win_free(&win); 
    MPI_Free_mem(shared); 
    MPI_Free_mem(local); 
    MPI_Finalize (); 

    return 0; 
} 

void pt(int t[],int s) 
{ 
    int i = 0; 
    while(i < s) 
    { 
     printf("%d ",t[i]); 
     i++; 
    } 
    printf("\n"); 
} 

我得到的以下结果:

processus 0 (avant): -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
processus 0 (apres): 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 
processus 4 (avant): 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 
processus 4 (apres): 0 -1 -1 -1 4 -1 -1 -1 -1 -1 
Assertion failed in file ./src/mpid/ch3/include/mpid_rma_shm.h at line 592: local_target_rank >= 0 
internal ABORT - process 5 
Assertion failed in file ./src/mpid/ch3/include/mpid_rma_shm.h at line 592: local_target_rank >= 0 
internal ABORT - process 6 
Assertion failed in file ./src/mpid/ch3/include/mpid_rma_shm.h at line 592: local_target_rank >= 0 
internal ABORT - process 9 

有人可以帮我吗排除出了什么问题&错误的含义是什么?非常感谢。

回答

3

MPI_Win_allocate_shared是从MPI非常抽象的本质出发。它暴露了底层内存组织,并允许程序绕过昂贵的(并且往往令人困惑的)MPI RMA操作,并直接在具有这种操作的系统上使用共享内存。虽然MPI通常处理排名不共享物理内存地址空间的环境,但现在典型的HPC系统由许多互连的节点组成。因此,在同一节点上执行的队列可以附加到共享内存段,并通过共享数据而不是消息传递进行通信。

MPI提供一种通信器分割操作,允许一个创建,使得在每个子组中的行列能够共享存储器行列亚组:

MPI_Comm_split_type(comm, MPI_COMM_TYPE_SHARED, key, info, &newcomm); 

在典型的簇,这实质上组行列由它们执行的节点。分割完成后,共享内存窗口分配可以在每个newcomm的队列中执行。请注意,对于多节点群集作业,这将导致多个独立的newcomm通信器,并因此导致多个共享存储器窗口。一个节点上的排名不会(也不应该)能够看到其他节点上的共享内存窗口。

在这方面,MPI_Win_allocate_shared是独立于平台的封装器,用于共享内存分配的操作系统特定机制。

+1

嗨!我仍然不明白为什么我得到错误,但... – Reda94

+0

所有进程是否在同一节点上运行? –

+0

@Hristolliev在我的情况下,他们是,但它只是为了测试,如果我让所有的东西都起作用,我将在其他计算机上通过网络连接进行测试...... – Reda94

0

该代码和用法有几个问题。 @ Hristolliev的回答中提到了其中的一些。

  1. 您必须运行同一节点中的所有进程才能拥有一个intranode通信器或使用通信器split分享。
  2. 您需要运行此代码至少10个进程。
  3. 三,local应该用free()解除分配。
  4. 您应该从查询中获得shared指针。
  5. 你应该释放shared(我认为这是由Win_free照顾)

这是生成的代码:

# include <stdlib.h> 
# include <stdio.h> 
# include <time.h> 

# include "mpi.h" 

int main (int argc, char *argv[]); 
void pt(int t[], int s); 

int main (int argc, char *argv[]) 
{ 
    int rank, size, shared_elem = 0, i; 
    MPI_Init (&argc, &argv); 
    MPI_Comm_rank (MPI_COMM_WORLD, &rank); 
    MPI_Comm_size (MPI_COMM_WORLD, &size); 
    MPI_Win win; 
    int *shared; 

// if (rank == 0) shared_elem = size; 
// MPI_Win_allocate_shared(shared_elem*sizeof(int), sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &shared, &win); 

    if (rank == 0) 
    { 
     MPI_Win_allocate_shared(size, sizeof(int), MPI_INFO_NULL, 
           MPI_COMM_WORLD, &shared, &win); 
    } 
    else 
    { 
     int disp_unit; 
    MPI_Aint ssize; 
     MPI_Win_allocate_shared(0, sizeof(int), MPI_INFO_NULL, 
           MPI_COMM_WORLD, &shared, &win); 
     MPI_Win_shared_query(win, 0, &ssize, &disp_unit, &shared); 
    } 


    if(rank==0) 
    { 
     MPI_Win_lock(MPI_LOCK_EXCLUSIVE, 0, MPI_MODE_NOCHECK, win); 
     for(i = 0; i < size; i++) 
     { 
      shared[i] = -1; 
     } 
     MPI_Win_unlock(0,win); 
    } 

    MPI_Barrier(MPI_COMM_WORLD); 

    int *local = (int *)malloc(size * sizeof(int)); 
    MPI_Win_lock(MPI_LOCK_SHARED, 0, 0, win); 
    for(i = 0; i < 10; i++) 
    { 
     MPI_Get(&(local[i]), 1, MPI_INT, 0, i,1, MPI_INT, win); 
    } 
    printf("processus %d (avant): ", rank); 
    pt(local,size); 
    MPI_Win_unlock(0,win); 

    MPI_Win_lock(MPI_LOCK_EXCLUSIVE, 0, 0, win); 

    MPI_Put(&rank, 1, MPI_INT, 0, rank, 1, MPI_INT, win); 

    MPI_Win_unlock(0,win); 

    MPI_Win_lock(MPI_LOCK_SHARED, 0, 0, win); 
    for(i = 0; i < 10; i++) 
    { 
     MPI_Get(&(local[i]), 1, MPI_INT, 0, i,1, MPI_INT, win); 
    } 
    printf("processus %d (apres): ", rank); 
    pt(local,size); 
    MPI_Win_unlock(0,win); 


    MPI_Win_free(&win); 
// MPI_Free_mem(shared); 
    free(local); 
// MPI_Free_mem(local); 
    MPI_Finalize (); 
    return 0; 


} 

void pt(int t[],int s) 
{ 
    int i = 0; 
    while(i < s) 
    { 
     printf("%d ",t[i]); 
     i++; 
    } 
    printf("\n"); 
}