MPI接收/收集动态矢量长度(MPI Receive/Gather Dynamic Vector L

2019-09-21 12:20发布

我有一个存储结构的向量的应用程序。 这些结构容纳约像存储器和千兆触发器/ 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;
};

集群中的每个机器填充其实例MachineData 。 我想收集所有这些情况下,但我不确定如何处理收集nviVecamdVec ,因为它们的长度在每台机器上各不相同。

Answer 1:

您可以使用MPI_GATHERV结合MPI_GATHER来实现这一目标。 MPI_GATHERV是可变版本MPI_GATHER并且它允许根秩来收集来自每个发送处理元件的数目differt。 但是,为了根排名来指定这些数字它必须知道每个等级是多少元素控股。 这可以通过使用简单的单一元件来实现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);

你也应该注册MPI的数据类型( datatype在上面的代码中)的结构(二进制发送会工作,但不会是便携,也不会在异构设置工作)。



文章来源: MPI Receive/Gather Dynamic Vector Length