MPI Bcast或Scatter到特定等级

时间:2015-09-03 01:47:41

标签: python mpi mpi4py

我有一些数据。我试图做的是这样的:

使用等级0将数据投射到50个节点。每个节点上都有1 mpi进程,该进程可以使用16个核心。然后,每个mpi进程将调用python多处理。完成了一些计算,然后mpi进程保存了使用多处理计算的数据。 mpi进程然后更改一些变量,并再次运行多处理。等

因此除了初始启动之外,节点不需要彼此通信,它们都接收一些数据。

多处理效果不佳。所以现在我想使用所有MPI。

我怎么能(或者不可能)使用引用bcast或scatter的MPI等级的整数数组。例如,排名1-1000,该节点有12个核心。所以每12个排名我想要播放数据。然后在每12个等级,我希望它将数据分散到12 + 1到12 + 12等级。

这需要第一个bcast与totalrank / 12进行通信,然后每个等级将负责将数据发送到同一节点上的排名,然后收集结果,保存它,然后将更多数据发送到同一节点上的排名。

1 个答案:

答案 0 :(得分:2)

我不太了解mpi4py能够为您提供代码示例,但这里可以解决C ++问题。我相信你可以很容易地推断出Python代码。

#include <mpi.h>
#include <iostream>
#include <cstdlib> /// for abs
#include <zlib.h>  /// for crc32

using namespace std;

int main( int argc, char *argv[] ) {

    MPI_Init( &argc, &argv );
    // get size and rank
    int rank, size;
    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
    MPI_Comm_size( MPI_COMM_WORLD, &size );

    // get the compute node name
    char name[MPI_MAX_PROCESSOR_NAME];
    int len;
    MPI_Get_processor_name( name, &len );

    // get an unique positive int from each node names
    // using crc32 from zlib (just a possible solution)
    uLong crc = crc32( 0L, Z_NULL, 0 );
    int color = crc32( crc, ( const unsigned char* )name, len );
    color = abs( color );

    // split the communicator into processes of the same node
    MPI_Comm nodeComm;
    MPI_Comm_split( MPI_COMM_WORLD, color, rank, &nodeComm );

    // get the rank on the node
    int nodeRank;
    MPI_Comm_rank( nodeComm, &nodeRank );

    // create comms of processes of the same local ranks
    MPI_Comm peersComm;
    MPI_Comm_split( MPI_COMM_WORLD, nodeRank, rank, &peersComm );

    // now, masters are all the processes of nodeRank 0
    // they can communicate among them with the peersComm
    // and with their local slaves with the nodeComm
    int worktoDo = 0;
    if ( rank == 0 ) worktoDo = 1000;
    cout << "Initially [" << rank << "] on node "
         << name << " has " << worktoDo << endl;
    MPI_Bcast( &worktoDo, 1, MPI_INT, 0, peersComm );
    cout << "After first Bcast [" << rank << "] on node "
         << name << " has " << worktoDo << endl;
    if ( nodeRank == 0 ) worktoDo += rank;
    MPI_Bcast( &worktoDo, 1, MPI_INT, 0, nodeComm );
    cout << "After second Bcast [" << rank << "] on node "
         << name << " has " << worktoDo << endl;

    // cleaning up
    MPI_Comm_free( &peersComm );
    MPI_Comm_free( &nodeComm );

    MPI_Finalize();
    return 0;
}

如您所见,您首先在同一节点上创建具有进程的通信器。然后,您可以在每个节点上创建具有相同本地排名的所有进程的对等通信器。 从那时起,您的全局排名0的主进程将向本地主人发送数据。他们将在他们负责的节点上分发工作。