2017-04-06 2 views
0

입자 시뮬레이션을 수행하고 있으며 다른 세 가지 배열의 일부를 다른 프로세스로 보내야합니다. MPI 사용자 정의 유형을 사용하여이를 수행하는 방법은 무엇입니까?세 가지 다른 행렬의 부분에 대한 MPI 사용자 정의 형식

예를 들어, 프로세스 1에서 데이터 유형이 double, A, B 및 C 인 3 개의 행렬이 있다고 가정합니다. 이제 A, B 및 C의 처음 두 행을 프로세스 2로 보내려고합니다. MPI 사용자 정의 유형을 사용하여 이러한 행렬에 대한 C 유형 저장을 가정하면 어떻게됩니까? 고맙습니다.

현재이 행렬의 처음 두 행을 단일 버퍼에 복사하고 MPI 전송을 수행합니다. 여기에는 기본적으로 다음 단계가 포함됩니다.

Copy the first two rows of A, B, and C to a send_buffer on Process 1. 
Send the send_buffer from Process 1 to Process 2. 
On Process 2, use recv_buffer to receive data from Process 1. 
On Process 2, copy data from recv_buffer to A, B, C on Process 2. 

이 작업을 수행하는 것이 더 좋은 방법이 있기를 바랍니다. 감사.

+0

지금까지 수행 한 작업을 보여주는 최소한의 코드를 제공해주십시오. – Shibli

+0

* 인접 프로세스 *는 무엇을 의미합니까? 귀하의 매트릭스는 현재 어디에 저장되어 있습니까? 프로그램에서 전반적인 순위는 무엇입니까? – Zulan

+0

예제를 추가하여 더 명확하게하려고 노력했습니다. – Bill

답변

0

아래 코드에서 행렬의 행 범위를 전달하기 위해 MPI 데이터 형식이 정의됩니다. 세 개의 행렬이있는 경우 세 개의 송수신이 있습니다. 다음 코드를 자신의 코드와 비교하여 어떤 코드가 더 나은 지 확인할 수 있습니다.

매트릭스를 하나씩 옮기는 것이 효율적이지 않다면 모든 매트릭스를 구조체에 넣고 MPI 데이터 유형을 만들거나 MPI_PACK을 사용해보십시오.

#include <mpi.h> 
#include <stdio.h> 
#include <stdlib.h> 

void make_layout(int row_begin, int row_end, int ncol, MPI_Datatype* mpi_dtype) 
{ 
    int nblock = 1; 
    int block_count = (row_end - row_begin + 1) * ncol; 
    MPI_Aint lb, extent; 
    MPI_Type_get_extent(MPI_DOUBLE, &lb, &extent); 
    MPI_Aint offset = row_begin * ncol * extent; 
    MPI_Datatype block_type = MPI_DOUBLE; 

    MPI_Type_create_struct(nblock, &block_count, &offset, &block_type, mpi_dtype); 
    MPI_Type_commit(mpi_dtype); 
} 

double** allocate(int nrow, int ncol) 
{ 
    double *data = (double *)malloc(nrow*ncol*sizeof(double)); 
    double **array= (double **)malloc(nrow*sizeof(double*)); 
    for (int i=0; i<nrow; i++) 
     array[i] = &(data[ncol*i]); 

    return array; 
} 

int main() 
{ 
    MPI_Init(NULL, NULL); 

    int rank; 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

    // make 3x3 matrix. 
    int nrow = 3; 
    int ncol = 3; 
    double** A = allocate(nrow, ncol); 

    // make mpi datatype to send rows [0, 1] excluding row 2. 
    // you can send any range of rows i.e. rows [row_begin, row_end]. 
    int row_begin = 0; 
    int row_end = 1; // inclusive. 
    MPI_Datatype mpi_dtype; 
    make_layout(row_begin, row_end, ncol, &mpi_dtype); 

    if (rank == 0) 
     MPI_Send(&(A[0][0]), 1, mpi_dtype, 1, 0, MPI_COMM_WORLD); 
    else 
     MPI_Recv(&(A[0][0]), 1, mpi_dtype, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);   

    MPI_Type_free(&mpi_dtype); 
    MPI_Finalize(); 

    return 0; 
} 
+0

자세한 설명을 해주셔서 감사합니다. 그것들을 구조체로 만드는 것은 좋은 생각입니다. Btw, 나는이 답변을 투표하려고했지만 15 가지 평판이 없으며 내 투표가 표시되지 않습니다. – Bill

+0

예,이 [이유] (https://meta.stackexchange.com/a/41350)로 인해 투표를하려면 15 명의 담당자가 필요합니다. – Shibli