2010-06-05 2 views
0

에서 MPI로 평행선의 사각형 행렬을 곱하려고합니다.MPI_Type_Vector 및 MPI_Gather를 사용하여 C

MPI_Type_vector를 사용하여 사각형 서브 매트릭스 (float 배열)를 프로세스에 보내서 하위 제품을 계산할 수 있습니다. 그런 다음 다음 반복을 위해이 부분 행렬은 MPI_Type_contiguous (전체 하위 행렬이 전송 됨) 프로세스로 이웃 프로세스로 전송됩니다. 이 부분은 예상대로 작동하며 지역 결과는 정확합니다.

그런 다음 인접한 유형의 MPI_Gather를 사용하여 모든 로컬 결과를 루트 프로세스로 다시 보냅니다. 문제는 최종 매트릭스가 서브 매트릭스별로 서브 매트릭스 대신 라인별로 빌드된다는 것입니다 (분명히,이 방법으로).

나는 최종 행렬을 재 배열하는 추악한 절차를 썼지 만, MPI_Type_vectors를 전송하는 "역"연산을 수행하는 직접적인 방법이 있는지 알고 싶습니다 (즉, 값의 배열을 전송하여 직접 수신 배열의 부분 배열 형식).

예, 시도하고 내 긴 텍스트 명확히 :

A [16] 및 B [16]

사람들은 정말, 2 차원 배열 인을 [4] [4], B [ 4] [4].

은 곱셈되는 4x4 행렬이고; C [4] [4] 결과를 포함합니다. 4 개의 프로세스가 사용된다 (0 내지 3의 Pi) :

Pi는 subAi [4] 및 subBi [4]의 2 개의 서브 매트릭스를 얻는다. 그들의 제품은 subCi [4]에 로컬로 저장됩니다. 예컨대

는 P0 가져 :

subA0 [4]를 포함하는 A [0], A [1], A [4] 및 [5]; B [0], B [1], B [4] 및 B [5]를 포함하는
subB0 [4].

모든 것이 계산 된 후 루트 프로세스는 모든 subCi [4]를 수집합니다.

이어서 C [4] [4]가 포함

[
SUBC 0 [0] SUBC 0 [1] SUBC 0 [2] SUBC 0 [3]
subC1 [0] subC1 [1] subC1 [2] subC1 [3]
subC2 [0] subC2 [1] subC2 [2] subC2 [3]
subC3 [0], subC3 [1], subC3 [2], subC3 [3]

및 I는 싶습니다 : 0 [0] SUBC 0 [1] subC1 [0] subC1 [1]

[
SUBC SUBC 0 [2] SUBC 0 [3] subC1 [2] subC1 [3]
subC2 [0] subC2 [1] subC3 [0] subC3 [1]
subC2 [2], subC2 [3], subC3 [2], subC3 [3]

추가 작업없이. 누군가가 방법을 알고 있습니까?

귀하의 조언에 감사드립니다. '고성능 마크'에 대한 대답

추가 정보 :

1 글쎄, 내 초기 행렬이 2 차원 배열 인 (A의 형태로 [4] [4]). (그런데

MPI_Type_vector(2, 2, 4, MPI_FLOAT, &subMatrix); 

을 : 나는

은 내가 예를 들어, 다음과 같이 MPI_Type_vector을 정의했다 ... 내가 지금은 나쁜 생각이었다 참조, 내 질문을 쓰는 동안은 짧은 만들고 싶었다 평평한 배열의 경우 차이점을 볼 수 없습니다.)

2 나는 MPI 전문가가 아니므로 이상한 일을 할 수도 있습니다. 여기 이 실시 예에 적용되는 내 코드의 비트 (만이 다루어진다는, B가 매우 유사)이다 루트로부터 슬레이브 프로세스 행렬 전송

:

Master { 
    for (i = 0 ; i < 2 ; i++) 
     for (j = 0 ; j < 2 ; j++) 
      MPI_Send(&A[j * 2][(i + j) % 2 * 2], 1, subMatrix, i + j * 2, 42, MPI_COMM_WORLD); 
} 

노예 나타날

MPI_Recv(subA, 4, MPI_FLOAT, 0, 42, MPI_COMM_WORLD, &status); 

그런 다음, 프로세스는 교류 MPI_Send 및 subMatrixLocal의 MPI_Recv 통해 완료 :

MPI_Type_contiguous(4, MPI_FLOAT, &subMatrixLocal); 
작업이 완료 모든 주민들 후

, 나는 C에 모든 SUBC 매트릭스를 수집 :

MPI_Gather(subC, 1, subMatrixLocal, C, 1, subMatrixLocal, 0, MPI_COMM_WORLD); 

그리고 내가 순서를 변경해야하는 이전에 언급 결과를 얻을 ...

그리고 제안 된 알고리즘에 대해 : 다음 단계는 정사각형 매트릭스 제품이 효율적인 GPU로 행렬 곱셈을 수행하는 것입니다. MPI는 CPU에서 CPU로 행렬을 전송하는 데 사용됩니다. 물론 글로벌 효율성이 테스트 될 것입니다.

0 당신은 "같은 유형 정의가 역 동작에도 적용되어야합니다"라고하셨습니다. 그러나, 내 MPI_Vector_type "큰"행렬을 잘 작동하지만 하위 행렬에 직접 사용하는 것은 불가능합니다 (MPI_Vector_type (2, 2, 4)를 2x2 행렬에 적용하면 잘못된 결과가 나타납니다. 마지막 두 값은 정의 된 배열의 "외부"입니다 ...). 다른 MPI_Vector_type을 만들어 보내거나 받아야한다는 것을 의미합니까?

답변

1

질문에 대한 대답 은 MPI_Type_vectors를 전송하는 'inverse'작업을 직접 수행하는 방법이 있습니다. 예 :입니다. 하나의 프로세스에서 다른 프로세스로 서브 매트릭스를 전송하기 위해 타입 벡터를 이미 정의한 경우, 동일한 유형 정의를 역 연산에도 적용 할 수 있습니다.

그러나 귀하의 설명에 다소 혼란스럽고 몇 가지 추가 질문이 있습니다. 당신이 그 (것)들에 응답하는 경우에 나는 더 나은 통보를 제공 할 수 있을지도 모른다.

  1. 행렬을 A [16], B [16]이라고 쓰고 4x4라고 말하면됩니다. 벌써 평평하게 했니? 나는 그들이 A [4] [4] 등일 것이라고 예상했다. 행렬을 평평하게했다면 왜 그렇게했을 까? mpi_type_vector를 정의하여 2D 행렬의 부분 행렬을 정의 할 수 있습니다.
  2. 나에게 조금 이상한 것 같지만 반드시 틀린 것은 아니지만 이상하게 보일 수 있습니다. 나는 평소에 흩어짐과 일치하는 수집품을 보려고 기대할 것이다. 아마도 사용중인 작업을 명확히하기 위해 코드를 충분히 게시 할 수 있습니다.

마지막으로, 부분 행렬 곱셈에 의한 행렬 곱셈은 아마도 MPI를 사용한 효율적인 접근법이 아니라고 생각합니다. 당신이 운동으로 이것을하는 경우에 계속하십시오. 그러나 구현하기 쉬운 더 나은 알고리즘은 아마도 구현하기가 더 쉽습니다.

  1. mpi_broadcast 매트릭스 B는 모든 프로세스에 적용됩니다.
  2. 디렉터 프로세스는 A의 행을 루프에서 작업자 프로세스로 보냅니다.
  3. 작업자 프로세스는 C 행을 계산하고이를 디렉터 프로세스로 다시 보냅니다.
  4. 디렉터 프로세스는 C 행을 수신하여 올바른 위치에 배치합니다.
+0

귀하의 질문에 답변을 드릴 수 있도록 내 게시물을 편집했습니다. 관심을 가져 주셔서 감사합니다. –