Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1711616
  • 博文数量: 438
  • 博客积分: 9799
  • 博客等级: 中将
  • 技术积分: 6092
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-25 17:25
文章分类

全部博文(438)

文章存档

2019年(1)

2013年(8)

2012年(429)

分类: 云计算

2012-07-10 12:16:48

一般MPI程序

所有的MPI程序有以下通用的结构:

1、包含MPI头文件;

2、变量声明;

3、初始化MPI环境;

4、计算以及MPI通信调用;

5、关闭MPI通信。


MPI头文件包含MPI描述的定义以及函数原型。

之后是变量声明,每个进程调用一个MPI例程来初始化消息传递环境。所有的MPI通信例程的调用必须在初始化之后。

最后在程序结束前,每个进程都必须调用一个例程来终止MPI。在终止例如调用后不能用MPI例程被调用。注意任何进程在执行时不遵循这个约定的话,程序会表现为挂起。


MPI头文件

包含MPI函数/子例程的原型、宏定义、特殊常量、MPI使用的数据类型。C语言中使用#include 来包含该头文件。


MPI命名规范

所 有MPI项(例程、常量、类型等)都由MPI_开头来避免冲突。C语言里函数名以大写开头,其余为小写,比如MPI_Init。MPI常量均为大写,例如 MPI_COMM_WORLD。特殊定义的类型对应于许多MPI项,类型名和函数命名一样,例如:MPI_Comm对应于一个MPI类型 communicator。


MPI例程和返回值

在C里MPI例程被实现为函数。通常一个错误码会返回,用于测试例程是否成功。例如:

int err;

err = MPI_Init(&argc, &argv);


MPI_SUCCESS表示例程成功运行:

if (err == MPI_SUCCESS) {

    ...

}


MPI句柄

MPI定义并维护与通信相关的它自己的内部数据结构。你通过句柄引用这些数据结构。句柄通过各种MPI调用返回,并可作为其它MPI调用的参数。

在C语言里,句柄是指向特定数据类型的指针。数组以0开始索引。


MPI 数据类型

MIP提供了它自己的引用数据类型,对应于C的各种基本数据类型。变量通常声明为C类型,MPI类型名用于MPI例程的参数。

MPI隐藏了数据类型表示的细节,比如浮点数的表示。这是实现考虑的事情。

MIP允许异构环境下表示的自动转换。

作为一个通用规则,接收的MPI数据类型必须与发送时指定的MPI数据类型匹配。

此外,MPI允许基于基本类型构建任意数据类型。


C语言的基本MPI数据类型

MPI数据类型C类型
MPI_CHARsigned char
MPI_SHORTsigned short int
MPI_INTsigned int
MPI_LONGsigned long int
MPI_UNSIGNED_CHARunsigned char
MPI_UNSIGNED_SHORTunsigned short int
MPI_UNSIGNEDunsigned int
MPI_UNSIGNED_LONGunsigned long int
MPI_FLOATfloat
MPI_DOUBLEdouble
MPI_LONG_DOUBLElong double
MPI_BYTE(none)
MPI_PACKED(none)


C语言的特殊MPI数据类型

例如:

1、MPI_Comm:通信者;

2、MPI_Status:MPI调用的状态信息;

3、MPI_Datatype

这些数据类型可以用于变量声明,例如:

MPI_Comm some_comm;


初始化MPI

任何MPI程序里的第一个MPI例程调用必须是初始化例程MPI_Init。它建立MPI环境。出错时会返回一个错误码。它只能被调用一次。

int err;

err = MPI_Init(&argc, &argv);


通信者(Communicators)

表示可以和另一个进程通信的一组进程的句柄。

对于所有点对点通信和收集操作,都需要通信者名:

1、发送和接收调用里指明的通信者必须同意这次通信发生;

2、只当进程共享同一个通信者时,进程才可以通信。


可以有许多通信者,且某个进程可以是许多不同的通信者里的一个成员。在每个通信者里,进程被连续编号(以0开始)。这个标识号作为通信者里的进程的秩(rank):

1、秩也被用于指明发送和接收调用里的源和目标。

2、如果进程属于多个通信者,它的各个秩可以不同。


MPI自动提供一个基本的通信者MPI_COMM_WORLD。这由所有的进程组成。使用MPI_COMM_WORLD可以让每个进程和任何其它进程通信。你可以定义额外的通信者,包含可用进程的子集。


得到通信者的信息:秩

MPI_Comm_rank用于确定通信者里某个进程的秩。

1、秩是连续的,且从0开始。

2、在不同的通信者里,某个进程可能有不同的秩。

C函数原型:

int MPI_Comm_rank(MPI_Comm comm, int *rank);

参数comm是通信者,你可以使用MPI_COMM_WORLD,也可以使用自己定义的(MPI_Comm some_comm;)。


得到通信者的信息:尺寸

MPI_Comm_size用于获得通信者里的进程数。

C函数原型:

int MPI_Comm_size(MPI_Comm comm, int *size);

1、参数comm为通信者;

2、参数size是返回的整型变量的地址。


终止MPI

MPI_Finalize:

1、清除所有MPI数据结构,取消未完成的操作,等等。

2、必须在所有进程里调用。如果任何进程不遵守这个规则,它将表现为挂起。

一旦MPI_Finalize被调用,(包括MPI_Init在内的)所有其它MPI例程都不能被调用。

例:

int err;

err = MPI_Finalize();


样例程序

#include
#include

void main(int argc, char *argv[]) {
    int myrank, size;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    printf("Processor %d of %d: Hello World!\n", myrank, size);

    MPI_Finalize();
}

上面的代码使用的预定义的通信者MPI_COMM_WORLD;且没有测试例程的错误状态。

编译:

mpicc rank_size.c -o rank_size

运行:

$ mpirun -np 4 ./rank_size
Processor 0 of 4: Hello World!
Processor 3 of 4: Hello World!
Processor 1 of 4: Hello World!
Processor 2 of 4: Hello World!


阅读(4791) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~