본문 바로가기
Engineer/병렬컴퓨팅

6. 유도데이터타입2(STRUCT), 예제로 배우기

by _제이빈_ 2020. 3. 24.

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
반응형

댓글