MPI接收/收集动态矢量长度

jdi*_*218 5 gpgpu mpi multi-gpu

我有一个存储结构矢量的应用程序.这些结构包含有关内存和giga-flop/s等系统上每个GPU的信息.每个系统上有不同数量的GPU.

我有一个程序可以同时在多台机器上运行,我需要收集这些数据.我对MPI很新,但我能够MPI_Gather()在大多数情况下使用,但是我想知道如何收集/接收这些动态大小的向量.

class MachineData
{
    unsigned long hostMemory;
    long cpuCores;
    int cudaDevices;
    public:
    std::vector<NviInfo> nviVec; 
    std::vector<AmdInfo> amdVec;
    ...
};

struct AmdInfo
{
    int platformID;
    int deviceID;
    cl_device_id device;
    long gpuMem;
    float sgflops;
    double dgflops;
};
Run Code Online (Sandbox Code Playgroud)

群集中的每台计算机都会填充其实例MachineData.我想收集这些实例中的每一个,但我不确定如何进行收集nviVec,amdVec因为它们的长度因机器而异.

Hri*_*iev 6

您可以MPI_GATHERV结合使用MPI_GATHER来实现这一目标.MPI_GATHERV是变量版本,MPI_GATHER它允许根级别从每个发送过程中收集不同数量的元素.但是为了使根等级指定这些数字,它必须知道每个等级持有多少元素.在此之前可以使用简单的单个元素来实现MPI_GATHER.像这样的东西:

// To keep things simple: root is fixed to be rank 0 and MPI_COMM_WORLD is used

// Number of MPI processes and current rank
int size, rank;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

int *counts = new int[size];
int nelements = (int)vector.size();
// Each process tells the root how many elements it holds
MPI_Gather(&nelements, 1, MPI_INT, counts, 1, MPI_INT, 0, MPI_COMM_WORLD);

// Displacements in the receive buffer for MPI_GATHERV
int *disps = new int[size];
// Displacement for the first chunk of data - 0
for (int i = 0; i < size; i++)
   disps[i] = (i > 0) ? (disps[i-1] + counts[i-1]) : 0;

// Place to hold the gathered data
// Allocate at root only
type *alldata = NULL;
if (rank == 0)
  // disps[size-1]+counts[size-1] == total number of elements
  alldata = new int[disps[size-1]+counts[size-1]];
// Collect everything into the root
MPI_Gatherv(vectordata, nelements, datatype,
            alldata, counts, disps, datatype, 0, MPI_COMM_WORLD);
Run Code Online (Sandbox Code Playgroud)

您还应该datatype为结构注册MPI派生的数据类型(在上面的代码中)(二进制发送将起作用但不可移植,并且不能在异构设置中工作).