2012-08-22 5 views
4

구조체의 벡터를 저장하는 응용 프로그램이 있습니다. 이 구조체는 메모리 및 giga-flop/s와 같은 시스템에서 각 GPU에 대한 정보를 보유합니다. 각 시스템마다 다른 수의 GPU가 있습니다.MPI Receive/Gather Dynamic Vector Length

나는 한 번에 여러 컴퓨터에서 실행되는 프로그램이 있으며이 데이터를 수집해야합니다. 나는 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_GATHER과 조합하여 MPI_GATHERV을 사용할 수 있습니다. 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)를 등록해야합니다.