여기는 지점 간 및 집합체 모두를 사용하는 작동 코드입니다 (집합 버전은 아래에 주석 처리되었지만 정상적으로 작동 함). 마스터의 수신 측에서 비 연속 데이터에 해당하는 벡터 유형을 정의해야합니다. 집합 수집을 사용하려면 집합 벡터가 정확한 위치에 모든 조각을 넣고 수집 버전을 사용해야하는지 확인하기 위해이 벡터의 크기를 망칠 필요가 있습니다.
배열 색인이 엉망이되어 버리기 쉽기 때문에 일반적으로 6x12 행렬에 2x3 배열의 프로세스를 사용하여 의도적으로 정사각형이되지 않도록했습니다.
들여 쓰기 들여 쓰기에 대한 사과 - 나는 탭/스페이스 문제를 가지고있는 것처럼 보입니다. 나는 미래에 정말 정렬해야합니다!
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#define M 6
#define N 12
#define MP 2
#define NP 3
#define MLOCAL (M/MP)
#define NLOCAL (N/NP)
#define TAG 0
int main(void)
{
int master[M][N];
int local[MLOCAL][NLOCAL];
MPI_Comm comm = MPI_COMM_WORLD;
int rank, size, src;
int i, j;
int istart, jstart;
int displs[MP*NP], counts[MP*NP];
MPI_Status status;
MPI_Request request;
MPI_Datatype block, blockresized;
MPI_Init(NULL, NULL);
MPI_Comm_size(comm, &size);
MPI_Comm_rank(comm, &rank);
if (size != MP*NP)
{
if (rank == 0) printf("Size %d not equal to MP*NP = %d\n", size, MP*NP);
MPI_Finalize();
return 1;
}
for (i=0; i < M; i++)
{
for (j=0; j < N; j++)
{
master[i][j] = rank;
}
}
for (i=0; i < MLOCAL; i++)
{
for (j=0; j < NLOCAL; j++)
{
local[i][j] = rank+1;
}
}
// Define vector type appropriate for subsections of master array
MPI_Type_vector(MLOCAL, NLOCAL, N, MPI_INT, &block);
MPI_Type_commit(&block);
// Non-blocking send to avoid deadlock with rank 0 sending to itself
MPI_Isend(local, MLOCAL*NLOCAL, MPI_INTEGER, 0, TAG, comm, &request);
// Receive from all the workers
if (rank == 0)
{
for (src=0; src < size; src++)
{
// Find out where this block should go
istart = (src/NP) * MLOCAL;
jstart = (src%NP) * NLOCAL;
// receive a single block
MPI_Recv(&master[istart][jstart], 1, block, src, TAG, comm, &status);
}
}
// Wait for send to complete
MPI_Wait(&request, &status);
/* comment out collective
// Using collectives -- currently commented out!
MPI_Type_create_resized(block, 0, sizeof(int), &blockresized);
MPI_Type_commit(&blockresized);
// Work out displacements in master in counts of integers
for (src=0; src < size; src++)
{
istart = (src/NP) * MLOCAL;
jstart = (src%NP) * NLOCAL;
displs[src] = istart*N + jstart;
counts[src] = 1;
}
// Call collective
MPI_Gatherv(local, MLOCAL*NLOCAL, MPI_INT,
master, counts, displs, blockresized,
0, comm);
*/
// Print out
if (rank == 0)
{
for (i=0; i < M; i++)
{
for (j=0; j < N; j++)
{
printf("%d ", master[i][j]);
}
printf("\n");
}
}
MPI_Finalize();
}
은 6 개 과정에서 확인을 작동하는 것 같다 :
mpiexec -n 6 ./arraygather
1 1 1 1 2 2 2 2 3 3 3 3
1 1 1 1 2 2 2 2 3 3 3 3
1 1 1 1 2 2 2 2 3 3 3 3
4 4 4 4 5 5 5 5 6 6 6 6
4 4 4 4 5 5 5 5 6 6 6 6
4 4 4 4 5 5 5 5 6 6 6 6
이 매트릭스는 프로세스 그리드에 정확히 분해 어떤 상황에서도 작동합니다. 프로세스가 모두 정확히 같은 크기의 부분 행렬을 가지고 있지 않으면 조금 더 복잡해집니다.
여기에서 원하는 답을 찾을 수 있습니다. http://stackoverflow.com/questions/9269399/sending-blocks-of-2d-array-in-c-using-mpi – Angelos