2017-05-12 4 views
0

단일 열 전략을 사용하여 행렬 벡터 곱셈을 수행하는 질문이있는 대학 숙제를하고 있습니다. 기본적으로 모든 프로세스는 행렬을 가져옵니다. 행렬 - 벡터 정의의 모든 프로세스는 벡터의 한 요소를 얻을 수 있기 때문에, - - 그것은 A -의이 x를 호출하자, 여기에 내가 가지고있는 기능입니다 :MPI에서 하나의 메시지에 두 개의 배열을 분산시키는 방법

double *mpiSingleColumn(const double *A,const double *x,const int size,const int rank){ 
    double *col=calloc(size,sizeof(double)),xi=0.0,*cols=calloc(size,sizeof(double)),*y=NULL; 
    MPI_Request request; 
    MPI_Iscatter(x,1,MPI_DOUBLE,&xi,1,MPI_DOUBLE,0,MPI_COMM_WORLD,&request); 
    MPI_Datatype vectype,resizedvectype; 
    MPI_Type_vector(size,1,size,MPI_DOUBLE,&vectype); 
    MPI_Type_commit(&vectype); 
    MPI_Type_create_resized(vectype,0,sizeof(double),&resizedvectype); 
    MPI_Type_commit(&resizedvectype); 
    MPI_Scatter(A,1,resizedvectype,col,size,MPI_DOUBLE,0,MPI_COMM_WORLD); 
    MPI_Type_free(&vectype); 
    MPI_Type_free(&resizedvectype); 
    MPI_Wait(&request,MPI_STATUS_IGNORE); 
    for(int i=0;i<size;i++) 
     cols[i]=xi*col[i]; 
    free(col); 
    if(rank==0) 
     y=calloc(size,sizeof(double)); 
    MPI_Reduce(cols,y,size,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD); 
    free(cols); 
    return y; 
} 

A는 행렬, x 벡터는, size입니다 A의 크기는 x이고이 문제의 경우 프로세스 수인와 같습니다.이 프로세스의 순위입니다.

위 기능은 완벽하게 작동하며 원하는 결과를 만들어냅니다. 그러나 지금은 두 개의 메시지에 xA을 산란시키고 있습니다. 가능한 경우 하나에 흩어지기를 바랍니다. 그렇습니다. 첫 번째 분산 형은 비동기식이지만 여전히 메시지입니다.

파생 된 유형, 특히 MPI_Type_create_struct을 생각해 봤지만 그렇지 않은 구조체 배열이있을 때 작동합니다.

가 나는 또한 MPI_Scatterv으로 검토 한 결과 그것이 내가 원하는 것과 가장 가까운 듯 MPI_Pack으로 검토 한하지만 난 Scatter 함께 넣어하는 방법을 모르겠어요, 너무 하나 개의 어레이와 함께 작동, 나는 알고있다 방법 그래도 Send와 함께 넣으십시오.

저는 MPI-2 RMA 및 MPI-3 공유 메모리를 알고 있지만 메시지 전달 스타일에서이를 수행 할 수있는 방법이 있는지 알고 싶습니다.

이렇게하는 방법 (가능한 경우)? 당신이 수학을 할 경우 모든 열이 i 다음 결과 열이 요약되어있는 COL-번호 x[i] 곱한됩니다 위의 기능을 설명하는 방법으로

, 당신은 결과가 :) 참 A*x 것을 깨달을 것입니다.

답변

0

사용자 (또는 MPI)는 행렬의 각 열과 관련 값 x를 연속적인 메모리 덩어리에 넣어야합니다. 직접 또는 MPI_Pack()을 통해이 작업을 수행하는지 여부는 중요하지 않습니다. 다음은 수동으로 그 일의 예이지만, MPI_Pack() 사용하여 동일한 구조 :

int i; 
double * buf; 
double * extendedCol; 
if (rank == 0) { 
    buf = malloc(sizeof(*buf)*(size+1)); 
    // this will need to change if you don't have 1 process per column 
    for (i = 0; i < size; ++i) { 
    memcpy(buf+(i*(size+1)), A+(i*size),(size+1)*sizeof(*buf)); 
    } 
} 

extendedCol=malloc((size+1)*sizeof(*extendedCol)); 

MPI_Scatter(buf,1,resizedvectype,extendedCol,size+1,MPI_DOUBLE,0,MPI_COMM_WORLD); 

for(i=0;i<size;i++) { 
    cols[i]=extendedCol[size]*extendedCol[i]; 
} 

주, 많은 MPI 프로그램은 메모리 제한, 그래서 메모리 셔플의이 종류는 일반적으로 옵션/좋은 생각이 아니다 . 그러나 이미 모든 프로세스를 하나의 프로세스에 저장하고 있으므로 메모리가 문제가되지 않는다고 가정합니다 (이미 인터리브 된 데이터 구조로 데이터를 읽거나 두 메시지로 살아야하는 경우).

편집 : 수정 col ->extendedCol

+0

추측은'extendedCol'가 col' 나는 메모리를 가지고 운송 중 어떤 시점에서 – niceman

+0

생각 '해야하는 방식으로 두 개의 메모리 위치에서 데이터를 분산 할 수있는 방법이 없습니다 단일 위치에 있어야합니다 (그렇지 않으면 실제로는 단일 메시지가 아닙니다). 많은 연구 논문들이 MPI에 '스트리밍'을 추가 할 것을 제안하고 있는데, 이는 당신이 원하는 것을 성취하는데 가깝습니다. (그러나 이것은 실제로 '메시지 전달'이 아닙니다.) – dlasalle