블록 순환 분포를 얻는 방법은?
나는 나의 매트릭스를 블록 순환 방식으로 배포하려고 합니다.저는 이 질문(MPI IO 읽기 및 쓰기 블록 순환 행렬)을 통해 많은 것을 배웠지만, 그것은 제가 정말로 필요로 하는 것이 아닙니다.
제 문제를 설명해 드리겠습니다.
첫 번째 프로세서가 굵게 표시된 요소를 얻을 수 있도록 차원 2 x 3의 프로세서 그리드에 배포하고자 하는 차원 12 x 12 행렬이 있다고 가정합니다.
A = 1 2 3 4 5 6 7 8 9 10 11 1213 14 15 16 17 18 19 20 21 22 23 2425 26 27 28 29 30 31 32 33 34 35 3637 38 39 40 41 42 43 44 45 46 47 4849 50 51 52 53 54 55 56 57 58 59 6061 62 63 64 65 66 67 68 69 70 71 7273 74 75 76 77 78 79 80 81 82 83 8485 86 87 88 89 90 91 92 93 94 95 9697 98 99 100 101 102 103 104 105 106 107 108109 110 111 112 113 114 115 116 117 118 119 120121 122 123 124 125 126 127 128 129 130 131 132133 134 135 136 137 138 139 140 141 142 143 144
그래서 기본적으로 행렬을 2 x 2 차원의 블록으로 분할한 다음 이 블록을 1부터 6까지 숫자로 표시한 프로세서에 다음과 같은 방식으로 배포하고자 합니다.
1 2 3 1 2 34 5 6 4 5 61 2 3 1 2 34 5 6 4 5 6
위 링크된 질문과 같이 이를 달성하려고 했지만 문제는 첫 번째 프로세서를 위한 로컬 어레이가 열 단위로 형성된다는 것입니다. 즉, 이렇게 보입니다.
1, 13, 49, 61, 97, 109, 2, 14, 50, 62, 98, 110, 7, 19, 55, 67, 103, 115, 8, 20, 56, 68, 104, 116
이것이 내 C 코드입니다.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mpi.h"
#define N 12
#define P 2
#define Q 3
int main(int argc, char **argv) {
int rank;
int size;
double *A;
int A_size;
MPI_Datatype filetype;
MPI_File fin;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
/**
* Reading from file.
*/
int gsizes[2], distribs[2], dargs[2], psizes[2];
gsizes[0] = N; /* no. of rows in global array */
gsizes[1] = N; /* no. of columns in global array*/
distribs[0] = MPI_DISTRIBUTE_CYCLIC;
distribs[1] = MPI_DISTRIBUTE_CYCLIC;
dargs[0] = 2; // no of rows in block
dargs[1] = 2; // no of cols in block
psizes[0] = P; /* no. of processes in vertical dimension
of process grid */
psizes[1] = Q; /* no. of processes in horizontal dimension
of process grid */
MPI_Type_create_darray(P * Q, rank, 2, gsizes, distribs, dargs, psizes,
MPI_ORDER_FORTRAN, MPI_DOUBLE, &filetype);
MPI_Type_commit(&filetype);
MPI_File_open(MPI_COMM_WORLD, "A.txt",
MPI_MODE_RDONLY,
MPI_INFO_NULL, &fin);
MPI_File_set_view(fin, 0, MPI_DOUBLE, filetype, "native",
MPI_INFO_NULL);
A_size = (N * N) / (P * Q);
A = (double*) malloc(A_size * sizeof(double));
MPI_File_read_all(fin, A, A_size,
MPI_DOUBLE, &status);
MPI_File_close(&fin);
printf("\n======\ni = %d\n", rank);
printf("A : ");
for (int i = 0; i < A_size; i++) {
printf("%lg ", A[i]);
}
MPI_Finalize();
return 0;
}
제가 정말로 원하는 것은 이 2 x 2 블록이 연속적으로 쓰여지는 것입니다. 즉, 첫 번째 프로세서의 로컬 어레이는 다음과 같습니다.
1, 13, 2, 14, 49, 61, 50, 62, 97, 109, 98, 110, ...
벡터나 서브어레이와 같은 다른 MPI_Data 유형을 정의해야 한다고 가정하지만, 어떻게 하면 이를 달성할 수 있을지 모르겠습니다.
편집
저는 제 문제를 부분적으로 해결했다고 생각합니다.기본적으로 각 프로세서는 FORTRAN 순서로 4 x 6 행렬로 끝나고 MPI_Create_subarray(...)를 사용하면 쉽게 2 x 2 블록을 추출할 수 있습니다.
그러나 각 프로세서가 블록 행을 각 프로세서에 동일한 열로 전송하고 그 반대의 경우도 마찬가지입니다.프로세서에 그리드 번호가 부여됨
1 2 34 5 6
예를 들어, 첫 번째 단계에서 프로세서 1은 블록 행을 전송해야 합니다.
1 2 7 813 14 19 20
프로세서 4; 및 해당 블록 열에 연결합니다.
1 213 1449 5061 6297 98109 110
프로세서 2와 3에 연결합니다.
데카르트 통신기를 만들고 MPI_Cart_sub()을 사용하여 행 및 열 단위 통신기도 만들었습니다.
MPI_Bcast()를 사용해야 할 것 같은데 MPI_Bcast()와 MPI_Type_create_subarray()를 결합하는 방법을 모르겠습니다.먼저 추출된 서브어레이를 local_array에 복사한 다음 Bcast(local_array)를 복사해야 합니다.그러나 MPI_Type_create_subarray()는 서브어레이에서 "뷰"만 제공하고 실제로는 제공하지 않습니다. 따라서 제가 생각해낸 가장 좋은 해결책은 Irecv root->root입니다.
좀 더 우아한 해결책이 있을까요?
아직까지는 당신의 실행이 정확한 것 같습니다.첫 번째 프로세서의 로컬 배열을 인쇄하는 방법이 문제입니다.로컬 배열은 파일을 읽는 방식과 프로세스 간에 데이터가 분산되기 때문에 열 단위로 형성됩니다.
첫 번째 프로세서의 로컬 배열을 행 단위로 인쇄하려면 다음과 같이 코드를 수정할 수 있습니다.
if (rank == 0) {
printf("\nLocal Array for Processor 0\n");
for (i = 0; i < P * Q; i++) {
for (j = 0; j < dargs[0] * dargs[1]; j++) {
printf("%.0f ", A[i * dargs[0] * dargs[1] + j]);
if ((j + 1) % dargs[1] == 0)
printf("\n");
}
printf("\n");
}
}
이렇게 하면 다음과 같이 첫 번째 프로세서의 로컬 배열이 행 단위로 인쇄됩니다.
Local Array for Processor 0
1 2 3 4
13 14 15 16
49 50 51 52
61 62 63 64
97 98 99 100
109 110 111 112
2 3 4 5
14 15 16 17
50 51 52 53
62 63 64 65
103 104 105 106
115 116 117 118
출력에는 첫 번째 프로세서의 로컬 배열만 표시됩니다.각 프로세서의 로컬 배열을 비슷한 방식으로 인쇄하려면 루프를 수정해야 합니다.
언급URL : https://stackoverflow.com/questions/28128605/how-to-get-block-cyclic-distribution
'programing' 카테고리의 다른 글
쿼리 작성기가 타임스탬프를 삽입하지 않음 (0) | 2023.09.16 |
---|---|
trigger mysql에서 select에서 값을 가져와 IF의 조건에 사용하는 방법 (0) | 2023.09.16 |
WordPress 퍼말링크 시스템은 어떻게 작동합니까? (0) | 2023.09.16 |
오류 1265.txt 파일에서 데이터를 로드하려고 할 때 열에 대한 데이터가 잘림 (0) | 2023.09.16 |
동일한 페이지에 리액트 루트(수백 개)가 여러 개일 경우 성능 문제가 발생합니까? (0) | 2023.09.16 |