MPI 튜토리얼을 제공하는 원본게시글을 따라가며 이해한 내용들을 기록한 문서이다.
포트란으로 병렬컴퓨팅 배우기 ←링크
VI MPI 유도데이터타입 _____________________
- Derived Data Type.
코딩을 하다보면, 데이터를 읽어 올때 내장 된 데이터 타입 외의 데이터 구조를 사용하면 편한 경우가 있다. 예를 들어 1~100을 1~10, 10 단위로 나눠야하는 상황(1~10, ... , 91~100)을 생각해 보자. 이런경우 루프를 통해 정수를 하나씩 읽어오기에는 다소 비효율적이다. 그보다 정수 10개짜리 리스트 형식을 정의해 한번에 10개씩 읽어오면 코드는 훨씬 간결하해지고 가독성이 좋아질 수 있다.
데이터 구조를 지정해주는 기법이 MPI 표준에도 존재한다. MPI 기본 데이터 유형을 기반으로 고유 한 데이터 구조를 정의 할 수있는 기능이다. 아에 데이터 구조를 만든다기보다, 기 존재하는 유형을 바탕으로 하기 때문에 파생 데이터 형식이라 부른다. 이러한 유도데이터 타입으로는 기본적으로 Contiguous, Vector, Indexed, 그리고 Struct이 존재한다.
˙MPI_TYPE_CONTIGUOUS : 가장 간단한 기법으로 기 존재하는 데이터 유형이 반복되어있는 형식을 정의한다.
˙MPI_TYPE_VECTOR (hvector) : contiguous와 비슷하나, 데이터간 일정한 간격(hvector는 간격이 바이드 단위)을 둔다.
˙MPI_TYPE_INDEXED (hindexed) : 데이터의 시작지점(offset) 및 블록의 길이(blocklens)을 지정하여 데이터를 읽어온다.
˙MPI_TYPE_STRUCT (MPI_Type_create_struct in MPI-3.0) : 한번에 여러 데이터 형식을 지정할 수 있다.
당연히 위 짧은 설명과 코드의 파라미터만 봐서는 이해하기 어려우니, 예제를 통해서 알아보자.
VI.1 MPI_TYPE_STRUCT _________________________________
번에 10개씩 읽어오면 코드는 훨씬 간결하해지고 가독성이 좋아질 수 있다.
데이터 구조를 지정해주는 기법이 MPI 표준에도 존재한다. MPI 기본 데이터 유형을 기반으로 고유 한 데이터 구조를 정의 할 수있는 기능이다. 아에 데이터 구조를 만든다기보다, 기 존재하는 유형을 바탕으로 하기 때문에 파생 데이터 형식이라 부른다. 이러한 유도데이터 타입으로는 기본적으로 Contiguous, Vector, Indexed, 그리고 Struct이 존재한다.
VI.2 MPI_TYPE_STRUCT CODE ____________________________
언어가 포트란이라 아쉬운 사람은 C 코드도 원본게시글(링크)에 함께 첨부되어있으니 활용하면 좋을 것이다. 코드는 다음과 같다.
program struct
include 'mpif.h'
integer NELEM
parameter(NELEM=25)
integer numtasks, rank, source, dest, tag, i, ierr
integer stat(MPI_STATUS_SIZE)
type Particle
sequence
real*4 x, y, z, velocity
integer n, nn
end type Particle
type (Particle) p(0:NELEM), particles(0:NELEM)
integer particletype, oldtypes(2) ! required variables
integer blockcounts(2), offsets(2), extent
tag = 1
call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, numtasks, ierr)
! setup description of the 4 MPI_REAL fields x, y, z, velocity
offsets(1) = 0
oldtypes(1) = MPI_REAL
blockcounts(1) = 4
! setup description of the 2 MPI_INTEGER fields n, type
! need to first figure offset by getting size of MPI_REAL
call MPI_TYPE_EXTENT(MPI_REAL, extent, ierr)
offsets(2) = blockcounts(1)*extent
oldtypes(2) = MPI_INTEGER
blockcounts(2) = 2
! define structured type and commit it
call MPI_TYPE_STRUCT(2, blockcounts, offsets, oldtypes, &
particletype, ierr)
call MPI_TYPE_COMMIT(particletype, ierr)
! task 0 initializes the particle array and then sends it to each
! task
if (rank .eq. 0) then
do i=0, NELEM-1
particles(i) = Particle ( 1.0*i, -1.0*i, 1.0*i, 0.25, i, &
mod(i,2) )
end do
print *,""
do i=1, numtasks-1
call MPI_SEND(particles, NELEM, particletype, i, tag, &
MPI_COMM_WORLD, ierr)
end do
else
! all tasks receive particletype data
source = 0
call MPI_RECV(p, NELEM, particletype, source, tag, &
MPI_COMM_WORLD, stat, ierr)
print *, 'rank=',rank
write(*,*) 'p(rank)=', p(rank)
! free datatype when done using it
call MPI_TYPE_FREE(particletype, ierr)
call MPI_FINALIZE(ierr)
end
이번 예제 역시 마스터노드에서 자기 자신에게 send 시 멈추는 현상이 발생하였고 위의 코드는 그 현상을 고친상태이다. 컴파일을 하고 코드를 실행 시 다음과 같은 결과가 나왔다.
$ mpirun -n 4 ./struct_type.exe
rank= 2
p(rank)= 2.0000000 -2.0000000 2.0000000 0.25000000 2 0
rank= 1
p(rank)= 1.0000000 -1.0000000 1.0000000 0.25000000 1 1
rank= 3
p(rank)= 3.0000000 -3.0000000 3.0000000 0.25000000 3 1
'Engineer > 병렬컴퓨팅' 카테고리의 다른 글
개념-2 : Data parallelism vs. Task parallelism (0) | 2020.03.24 |
---|---|
개념-1 : Concurrency vs. Parallelism (0) | 2020.03.24 |
5. 유도데이터타입(CONTIGUOUS), 예제로 배우기 (0) | 2020.03.24 |
4. 집합통신-2, 예제(수치적분)로 배우기 (0) | 2020.03.24 |
3. 집합통신, 예제(수치적분)로 배우기 (0) | 2020.03.24 |
댓글