MPI Tutorial 1 - Hello MPI World!

What is MPI?

Example - Hello MPI World!

這個範例將演示如何初始化MPI,以及MPI的一些基本參數。

Hello_MPI_World.c

1
2
3
4
5
6
7
8
9
10
11
#include <mpi.h>
#include <stdio.h>

int main(int agrc, char* argv[]) {
MPI_Init(NULL,NULL);
int size, rank;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
printf("Hello world from rank %d, the world size is %d.\n",rank,size);
MPI_Finalize();
}

執行mpicc -O3 ./Hello_MPI_World.c編譯,接著執行mpirun -np <處理器數量> <編譯完的檔案>

以我的執行結果為例mpirun -np 8 ./a.out,我使用8個處理器。

1
2
3
4
5
6
7
8
Hello world from rank 5, the world size is 8.
Hello world from rank 7, the world size is 8.
Hello world from rank 4, the world size is 8.
Hello world from rank 2, the world size is 8.
Hello world from rank 6, the world size is 8.
Hello world from rank 3, the world size is 8.
Hello world from rank 0, the world size is 8.
Hello world from rank 1, the world size is 8.

從結果你能看到,代碼中只有一行printf,但是卻輸出八行字串,這是因為在MPI程式中,每個處理器都會執行一遍main(),所以你會看到八行Hello world。

注意MPI在執行上面的範例時並沒有照著處理器的編號依序執行,而是並行執行,因此輸出並不會按照順序,而是誰先執行誰就先輸出。如果你再執行一遍,你會發現輸出的順序不一樣。

仔細看一下Hello_MPI_World.c,除了開頭要#include <mpi.h>,還有四個重要的函式,一般寫MPI程式基本跑不掉這四個函式。

MPI_Init()

1
2
3
MPI_Init(
int* argc,
char** argv)

MPI_Init() 用來初始化MPI的全域和局部變數,基本上它的兩個arguments不是很重要。

MPI_Comm_size()

1
2
3
MPI_Comm_size(
MPI_Comm communicator,
int* size)

MPI_Comm_size()會回傳一個整數,代表程式使用的處理器數量,範例中使用的MPI_COMM_WORLD包含所有能用的處理器,如果我們給它8個處理器,MPI_Comm_size(MPI_COMM_WORLD, &size)將會回傳8並存到size變數裡。

MPI_Comm_rank()

1
2
3
MPI_Comm_rank(
MPI_Comm communicator,
int* rank)

MPI_Comm_rank()會回傳該處理器的編號,即rank,從0開始。如同之前說的每個處理器都會執行一次main(),但是不同的是處理器的rank都不一樣,有了rank我們就能用來分配工作給指定的處理器。

MPI_Finalize()

1
MPI_Finalize()

MPI_Finalize()會放在程式的結尾,用來清除MPI環境,執行後就不能再使用任何MPI函式。

:mega: 值得注意的是,MPI裡的函式會是變數都是MPI_開頭,且函式後面接的第一個字母是大寫,其餘小寫。另外MPI的變數都是大寫。