2016-10-07 18 views
1

可能な限り共有メモリを使用してメモリのフットプリントを減らすために、ノード間の並列化のためにノード間およびスレッド用にMPIを使用して高度に並列化された実行を行うシミュレーションソフトウェアを作成しました。共有メモリでMPIを使用することができます

私のプログラムはうまくいきますが(最終的には)、私はこのアプローチが本当に最高かどうかについて、もう少し考えていますが、主に管理しているためです2つのタイプの並列化では、不規則な非同期コードが必要となります。

私はpaperpdf draft)がMPIへの共有メモリ拡張を導入し、単一ノード上でMPI並列化の中で共有データ構造を使用できることを発見しました。

私はMPIに詳しく経験していないので、私の質問です:これは最近の標準のOpen MPI実装で可能でしょうか?

メッセージの受け渡しが共有メモリでどのように行われるかについては言及していませんが、私はMPIがそうしていることを知っています。私は、複数のMPIプロセッサからメモリ内の同じオブジェクトにアクセス(読み込み)したいと思います。

答えて

3

これを行うことができます。ここには、各共有メモリノードに小さなテーブルを設定するテストコードがあります。一つだけのプロセス(ノードランク0)は実際に割り当て、テーブルを初期化しますが、ノード上のすべてのプロセスがそれを読むことができます - ここで

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

int main(void) 
{ 
    int i, flag; 

    int nodesize, noderank; 
    int size, rank, irank; 
    int tablesize, localtablesize; 
    int *table, *localtable; 
    int *model; 

    MPI_Comm allcomm, nodecomm; 

    char verstring[MPI_MAX_LIBRARY_VERSION_STRING]; 
    char nodename[MPI_MAX_PROCESSOR_NAME]; 

    MPI_Aint winsize; 
    int windisp; 
    int *winptr; 

    int version, subversion, verstringlen, nodestringlen; 

    allcomm = MPI_COMM_WORLD; 

    MPI_Win wintable; 

    tablesize = 5; 

    MPI_Init(NULL, NULL); 

    MPI_Comm_size(allcomm, &size); 
    MPI_Comm_rank(allcomm, &rank); 

    MPI_Get_processor_name(nodename, &nodestringlen); 

    MPI_Get_version(&version, &subversion); 
    MPI_Get_library_version(verstring, &verstringlen); 

    if (rank == 0) 
    { 
     printf("Version %d, subversion %d\n", version, subversion); 
     printf("Library <%s>\n", verstring); 
    } 

    // Create node-local communicator 

    MPI_Comm_split_type(allcomm, MPI_COMM_TYPE_SHARED, rank, 
       MPI_INFO_NULL, &nodecomm); 

    MPI_Comm_size(nodecomm, &nodesize); 
    MPI_Comm_rank(nodecomm, &noderank); 

    // Only rank 0 on a node actually allocates memory 

    localtablesize = 0; 

    if (noderank == 0) localtablesize = tablesize; 

    // debug info 

    printf("Rank %d of %d, rank %d of %d in node <%s>, localtablesize %d\n", 
    rank, size, noderank, nodesize, nodename, localtablesize); 


    MPI_Win_allocate_shared(localtablesize*sizeof(int), sizeof(int), 
       MPI_INFO_NULL, nodecomm, &localtable, &wintable); 

    MPI_Win_get_attr(wintable, MPI_WIN_MODEL, &model, &flag); 

    if (1 != flag) 
    { 
     printf("Attribute MPI_WIN_MODEL not defined\n"); 
    } 
    else 
    { 
     if (MPI_WIN_UNIFIED == *model) 
    { 
     if (rank == 0) printf("Memory model is MPI_WIN_UNIFIED\n"); 
    } 
     else 
    { 
     if (rank == 0) printf("Memory model is *not* MPI_WIN_UNIFIED\n"); 

     MPI_Finalize(); 
     return 1; 
    } 
    } 

    // need to get local pointer valid for table on rank 0 

    table = localtable; 

    if (noderank != 0) 
    { 
     MPI_Win_shared_query(wintable, 0, &winsize, &windisp, &table); 
    } 

    // All table pointers should now point to copy on noderank 0 

    // Initialise table on rank 0 with appropriate synchronisation 

    MPI_Win_fence(0, wintable); 

    if (noderank == 0) 
    { 
     for (i=0; i < tablesize; i++) 
    { 
     table[i] = rank*tablesize + i; 
    } 
    } 

    MPI_Win_fence(0, wintable); 

    // Check we did it right 

    for (i=0; i < tablesize; i++) 
    { 
     printf("rank %d, noderank %d, table[%d] = %d\n", 
     rank, noderank, i, table[i]); 
    } 

    MPI_Finalize(); 
} 

は、いくつかのサンプルです(書式設定のための謝罪は、スペース/タブの問題のようです) 2つのノードにわたる6つのプロセスの出力:

Version 3, subversion 1 
Library <SGI MPT 2.14 04/05/16 03:53:22> 
Rank 3 of 6, rank 0 of 3 in node <r1i0n1>, localtablesize 5 
Rank 4 of 6, rank 1 of 3 in node <r1i0n1>, localtablesize 0 
Rank 5 of 6, rank 2 of 3 in node <r1i0n1>, localtablesize 0 
Rank 0 of 6, rank 0 of 3 in node <r1i0n0>, localtablesize 5 
Rank 1 of 6, rank 1 of 3 in node <r1i0n0>, localtablesize 0 
Rank 2 of 6, rank 2 of 3 in node <r1i0n0>, localtablesize 0 
Memory model is MPI_WIN_UNIFIED 
rank 3, noderank 0, table[0] = 15 
rank 3, noderank 0, table[1] = 16 
rank 3, noderank 0, table[2] = 17 
rank 3, noderank 0, table[3] = 18 
rank 3, noderank 0, table[4] = 19 
rank 4, noderank 1, table[0] = 15 
rank 4, noderank 1, table[1] = 16 
rank 4, noderank 1, table[2] = 17 
rank 4, noderank 1, table[3] = 18 
rank 4, noderank 1, table[4] = 19 
rank 5, noderank 2, table[0] = 15 
rank 5, noderank 2, table[1] = 16 
rank 5, noderank 2, table[2] = 17 
rank 5, noderank 2, table[3] = 18 
rank 5, noderank 2, table[4] = 19 
rank 0, noderank 0, table[0] = 0 
rank 0, noderank 0, table[1] = 1 
rank 0, noderank 0, table[2] = 2 
rank 0, noderank 0, table[3] = 3 
rank 0, noderank 0, table[4] = 4 
rank 1, noderank 1, table[0] = 0 
rank 1, noderank 1, table[1] = 1 
rank 1, noderank 1, table[2] = 2 
rank 1, noderank 1, table[3] = 3 
rank 1, noderank 1, table[4] = 4 
rank 2, noderank 2, table[0] = 0 
rank 2, noderank 2, table[1] = 1 
rank 2, noderank 2, table[2] = 2 
rank 2, noderank 2, table[3] = 3 
rank 2, noderank 2, table[4] = 4 
関連する問題