Transcript mpi

MPI API & Running
시스템 소프트웨어 연구실
권성주
1
MPI

MPI



Simply a library of definitions & functions
#include “mpi.h”
모든 MPI 함수는 MPI_ 로 명칭이 시작됨
2/23
Compile & Running(1)

mpicc : 컴파일


mpicc –o <목적파일> <소스파일>
mpirun : 실행


mpirun –np <프로세스수> <실행파일명>
mpirun 실행전 mpi 데몬 실행중이어야 함
• LAM : lamboot

mpi 작업 후 mpi 데몬 종료
• LAM : lamhalt
3/23
Compile & Running(2)

LAM 작동을 위한 사전 작업

rsh 점검
• 각 노드는 remote shell 이 작동중이어야 함
• setup 명령(레드햇)의 Firewall configuration에서 설정
• 544 포트(rsh)이 사용가능하도록 설정해 줘야 함
• /etc/rc.d/init.d/xinetd restart

사용할 노드 목록 지정
• /etc/lam/lam-bhost.def 파일에 지정
4/23
시작과 끝

int MPI_Init(int * argc_ptr, char ** argv_ptr[])





MPI를 시작시킴
다른 MPI 함수보다 먼저 호출되어야 함
한번만 호출되어야 함
인수는 MPI 설정과 관련된 인수를 넘김
MPI_Finalize(void)


MPI를 종료시키기 위해 사용됨
더 이상 MPI_ 함수를 사용할 수 없음
5/23
communicator

int MPI_Comm_rank(MPI_Comm comm,
int *rank)



comm 채널내에서 자신의 프로세스가 가지는 순위를 rank에 반
환함
첫번째 인수 comm은 communicator임
communicator란?
• 서로간에 메시지를 주고 받을 수 있는 프로세스의 그룹
• MPI_COMM_WORLD : 새로운 communicator를 설정하지 않았을
경우에 사용되는 채널

int MPI_Comm_size(MPI_Comm comm,
int* number_of_processes)

지정된 comm 채널 내에 있는 프로세스의 수를 반환
6/23
Message

자료 교환을 위한 메시지(envelope) 구성



전송자의 rank
수신자의 rank
Tag
• 정수값을 사용해 표현
• 채널내에서 다른 메시지와 혼동하지 않게 하기 위한
message type

communicator
7/23
Send Message

int MPI_Send(void *message,
int count,
MPI_Datatype datatype,
int dest,
int tag,
MPI_Comm comm)



datatype 형태의 자료 message를 dest 랭크의 프로
세스에게 전송함
message내용중 datatype 자료형 크기가 count 수만
큼 전송됨
반환값 : 오류 코드
8/23
MPI Datatypes
MPI datatype
C datatype
MPI_CHAR
signed char
MPI_SHORT
signed short int
MPI_INT
signed int
MPI_LONG
singed long int
MPI_UNSIGNED_CHAR
unsigned char
MPI_UNSIGNED_SHORT
unsigned short int
MPI_UNSIGNED
unsigned int
MPI_UNSIGNED_LONG
unsigned long int
MPI_FLOAT
float
MPI_DOUBLE
double
MPI_LONG_DOUBLE
long double
MPI_BYTE
MPI_PACKED
9/23
Message Receive

int MPI_Recv(void *message,
int count,
MPI_Datatype datatype,
int source,
int tag,
MPI_Comm comm,
MPI_Status* status)



source 프로세스로부터 tag 태그를 사용해서 보내온 메시지를
받음
source : 프로세스 랭크 혹은 MPI_ANY_SOURCE 사용 가능
tag : 전송자가 사용한 tag 혹은 MPI_ANY_TAG 사용 가능
10/23
Receive Info

int MPI_Get_count(MPI_Status* status,
MPI_Datatype datatype,
int* count_ptr)


받은 메시지의 크기를 알고자 할 경우 사용
Receive 후에 정보는 MPI_Status에 들어 있음
• status->MPI_SOURCE : 보낸 프로세스 랭크
• status->MPI_TAG : 보낼때 사용한 tag
• status->MPI_ERROR : 오류가 있을 경우 정보

count_ptr 에 크기를 반환함
11/23
#include <stdio.h>
#include "mpi.h"
main(int argc, char** argv) {
int my_rank;
int p;
int fact = 0, total, source, dest = 0;
int tag = 0;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &p);
fact = calcFact(my_rank + 1);
if (my_rank == 0) {
total = fact;
for (source = 1; source < p; source++) {
MPI_Recv(&fact, 1, MPI_INT,
source, tag,
MPI_COMM_WORLD, &status);
total = total + fact;
}
} else {
MPI_Send(&fact, 1, MPI_INT, dest, tag,
MPI_COMM_WORLD);
}
if (my_rank == 0) {
printf("Fact sum from 1 to %d! = %d\n",
p, total);
}
MPI_Finalize();
}
int calcFact(int cnt) {
int sum = 1, i;
for (i = 2; i <= cnt; i++)
sum *= i;
return sum;
}
Broadcast

Collective communication


communicator내의 모든 프로세스가 동시에 통신에 참여하는
경우
Broadcast



collective communication
single process sends same data to every process
int MPI_Bcast(void* message,
int count,
MPI_Datatype datatype,
int root,
MPI_Comm comm)
• 전송자와 수신자는 모두 같은 명령을 사용함
• root는 메시지를 보내게 되며, 다른 사용자는 메시지를 수신하게
됨
13/23
Broadcast 예
void Get_data(float* a_ptr, float *b_ptr,
int* n_ptr, int my_rank) {
if (my_rank == 0) {
printf(“Enter a, b, and n\n”);
scanf(“%f %f %d”, a_ptr, b_ptr, n_ptr);
}
MPI_Bcast(a_ptr, 1, MPI_FLOAT, 0, MPI_COMM_WORLD);
MPI_Bcast(b_ptr, 1, MPI_FLOAT, 0, MPI_COMM_WORLD);
MPI_Bcast(n_ptr, 1, MPI_INT, 0, MPI_COMM_WORLD);
}
14/23
Reduce

reduction operations

all process in communicator contribute data
• combined by binary operation
• etc) global sum, sub, max, min…

int MPI_Reduce(void* operand,
void* result,
int count,
MPI_Datatype datatype,
MPI_Op operator,
int root,
MPI_Comm comm)
• operand에 있는 자료에 대해 operator 연산을 수행한 후 결
과는 result에 반환함
15/23
Reduction operator
Operation Name
Meaning
MPI_MAX
Maximum
MPI_MIN
Minimum
MPI_SUM
Sum
MPI_PROD
Product
MPI_LAND
Logical and
MPI_BAND
Bitwise and
MPI_LOR
Logical or
MPI_BOR
Bitwise or
MPI_LXOR
Logical exclusive or
MPI_BXOR
Bitwise exclusive or
MPI_MAXLOC
Maximum and location of maximum
MPI_MINLOC
Minimum and location of minimum
16/23
Reduce 예
fact = calcFact(my_rank + 1);
MPI_Reduce(&fact, &total, 1, MPI_INT, MPI_SUM, 0,
MPI_COMM_WORLD);
if (my_rank == 0) {
…
17/23
All Reduce

MPI_Reduce의 문제점


root 로 지정한 프로세스만 결과를 받음
다음 계산을 위한 준비로 진행된 계산이라면 문제가
됨
• MPI_Reduce() 후에 MPI_Bcast()를 통해 해결 가능
• MPI_Allreduce()를 사용하면 더 효율적임

int MPI_Allreduce(void* operand,
void* result,
int count,
MPI_Datatype datatype,
MPI_Op operator,
MPI_Comm comm)
• MPI_Reduce와 같지만, reduction 결과를 모든 프로세스가
가지고 있게 됨
18/23
Gather & Scatter

matrix과 같은 data block을 이용한 계산


계산하고자 하는 행이나 열 전체를 프로세스간에 전
달할 필요가 있음
gather
• 다른 프로세스들이 계산한 내용을 모두 가져오는 것

scatter
• 자신이 가지고 있는 내용을 다른 프로세스들에게 넘겨 주는
것
19/23
MPI_Gather


프로세스들의 자료를 모음
int MPI_Gather(void* send_data,
int send_count,
MPI_Datatype send_type,
void* recv_data,
int recv_count,
MPI_Datatype recv_type,
int root,
MPI_Comm comm)


각 프로세스에 있는 send_data 위치의 자료를 모아서 root
rank 프로세스의 recv_data에 저장함
recv_ 인수들은 root 에게만 의미가 있음
20/23
#include <stdio.h>
#include <mpi.h>
#define N 4
main(int argc, char **argv){
int npes, mype;
int i, j;
double A[N][N], v[N];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &npes);
MPI_Comm_rank(MPI_COMM_WORLD, &mype);
if(npes != N){ printf("Use %d PEs\n",N); exit(9);}
for(i=0; i < N; i++) v[i] = (double) mype;
MPI_Gather(v,N,MPI_DOUBLE,
A,N,MPI_DOUBLE, 0,MPI_COMM_WORLD);
if(mype == 0)
for(i=0; i < N; i++){
for(j=0; j < N; j++) printf("%5f ", A[i][j]);
printf("\n");
}
MPI_Finalize();
}
MPI_Scatter


root의 자료를 프로세스들에게 분배
int MPI_Scatter(void* send_data,
int send_count,
MPI_Datatype send_type,
void* recv_data,
int recv_count,
MPI_Datatype recv_type,
int root,
MPI_Comm comm)


root 랭크 프로세스의 send_data 내용을 p 세그먼트로 나눔
send_count 수만큼을 프로세스에게 분배함
• 첫번째 세그먼트는 rank 0, 두번째 세그먼트는 rank 1.. 과 같은식
으로 분배
22/23
All Gather


분산된 배열을 모든 프로세스에게 분배함
int MPI_Allgather(void* send_data,
int send_count,
MPI_Datatype send_type,
void* recv_data,
int recv_count,
MPI_Datatype recv_type,
MPI_Comm comm)

각 프로세스의 send_data 내용을 recv_data에 가져옴
23/23
Barrier

int MPI_Barrier (MPI_Comm comm)


comm 그룹 멤버들이 모두 MPI_Barrier() 함수를 호출할 때까지
대기하게 됨
제어를 중제하고자 할 때 사용
24/23
MPI 관련 사이트

MPI for C Programmers


MPICH


http://www.tacc.utexas.edu/resources/user_guide
s/mpi.c/
http://www-unix.mcs.anl.gov/mpi/mpich/
MPICH-G2

http://www.hpclab.niu.edu/mpi/
25/23