2016-05-14 540 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"); 
}