0

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

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

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

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

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

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

4

1 回答 1

4

我对 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 的主进程将向本地主进程发送数据。他们将在他们负责的节点上分发工作。

于 2015-09-03T14:37:49.877 回答