2012-08-22 65 views
4

我有一個存儲結構向量的應用程序。這些結構保存系統中每個GPU的信息,例如內存和千兆位/秒。每個系統上有不同數量的GPU。MPI接收/收集動態向量長度

我有一個程序一次在多臺機器上運行,我需要收集這些數據。我對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,因爲它們的長度在每臺計算機上都不相同。

+0

請發佈代碼。也檢查出'MPI_GATHERV()' – arunmoezhi

+0

正如我所說,你可以嘗試使用GATHERV。這樣每臺機器都可以發送自己長度的矢量。使用'recvcounts'來完成這個。 – arunmoezhi

+0

謝謝MPI_Gatherv()運行良好! – jdimarco218

回答

5

您可以使用MPI_GATHERV結合MPI_GATHER來完成此操作。 MPI_GATHERVMPI_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); 

你也應該註冊結構MPI的數據類型(datatype在上面的代碼)(二進制發送會工作,但不會是便攜,也不會在異構設置工作)。