[root@localhost mpi]# mpicc -c base.c
[root@localhost mpi]# mpicc -o base base.o
[root@localhost mpi]# mpirun -np 4 ./base

mpicc cos.c -o cos -lm

一.运行实例
1.hello world

#include <stdio.h>
#include "mpi.h"
int main(int argc, char**argv){
MPI_Init(&argc, &argv);
printf("Hello world.\n");
MPI_Finalize();
return 0;
}

2.每个进程输出自己是第几个进程

#include <stdio.h>
#include "mpi.h"
int main(int argc, char **argv){
MPI_Comm comm = MPI_COMM_WORLD;
int size, rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(comm, &size);
MPI_Comm_rank(comm, &rank);
printf("This is process %d of %d processes.\n", rank, size);
MPI_Finalize();
return 0;
}

3.点对点。0号进程给1号进程发消息,1号进程接收消息

#include<stdio.h>
#include<mpi.h>
#include<string.h>
int main(int argc, char **argv){
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Status status; int size, rank; char str[100];
MPI_Init(&argc, &argv);
MPI_Comm_size(comm, &size); MPI_Comm_rank(comm, &rank);
if (rank == 0) {
strcpy(str, "hello world");
printf("Process 0 send 1 to process %s.\n", str);
MPI_Send(str, strlen(str) + 1, MPI_CHAR, 1, 99, comm);
}
else if (rank == 1) {
MPI_Recv(str, 100, MPI_CHAR, 0, 99, comm, &status);
printf("Process 1 receives messages %s.\n", str);
}
MPI_Finalize();
return 0;
}

4.点对点。进程之间互相接收和发送消息
#include<stdio.h>
#include<mpi.h>
#include<string.h>
int main(int argc, char **argv){
const int limit = 10;
int rank, count = 0;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
while (count < limit){
if (rank == 0){
count++;
MPI_Send(&count, 1, MPI_INT, 1, 10, MPI_COMM_WORLD);
printf("0 sent %d to 1\n", count);
MPI_Recv(&count, 1, MPI_INT, 1, 20, MPI_COMM_WORLD, &status);
printf("0 received %d from 1\n", count);
}
else {
MPI_Recv(&count, 1, MPI_INT, 0, 10, MPI_COMM_WORLD, &status);
printf("1 received %d from 0\n", count);
count++;
MPI_Send(&count, 1, MPI_INT, 0, 20, MPI_COMM_WORLD);
printf("1 sent %d to 0\n", count);
}
}
MPI_Finalize();
}

5.点对点。进程之间循环发送一个数,0->1->2->0(假设开启了两个进程)

#include<stdio.h>
#include<mpi.h>
#include<string.h>
int main(int argc, char** argv){
int rank, size, token, source, dest;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
source = rank == 0 ? size -1 : rank - 1;
dest = (rank + 1) % size;
token = 100;
if (rank == 0){
MPI_Ssend(&token, 1, MPI_INT, dest, 1, MPI_COMM_WORLD);
printf("Process %d sends token to %d.\n", rank, dest);
MPI_Recv(&token, 1, MPI_INT, source, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("Process %d receives token from %d.\n", rank, source);
}
else {
MPI_Recv(&token, 1, MPI_INT, source, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("Process %d receives token from %d.\n", rank, source);
MPI_Ssend(&token, 1, MPI_INT, dest, 1, MPI_COMM_WORLD);
printf("Process %d sends token to %d.\n", rank, dest);
}
MPI_Finalize();
return 0;
}

6.给0号进程赋值。然后把0号进程的值广播出去。每个进程接收到的值和0号进程一样

#include<stdio.h>
#include<mpi.h>
#include<string.h>
int main(int argc, char** argv){
int arr[3], i, rank;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank == 0){
for (i = 0; i < 3; i++)
arr[i] = i + 1;
}
MPI_Bcast(arr, 3, MPI_INT, 0, MPI_COMM_WORLD);
printf("Process %d receives:", rank);
for (i = 0; i < 3; i++)
printf("%d ", arr[i]);
putchar('\n');
MPI_Finalize();
return 0;
}

7.0号进程收集其他所有进程的值
#include<stdio.h>
#include<mpi.h>
#include<stdlib.h>
int main(int argc, char **argv){
int rank, size, sbuf[3], *rbuf, i;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
for (i = 0; i < 3; i++)
sbuf[i] = rank * 10 + i;
if (rank == 0)
rbuf = (int*)malloc(sizeof(int) * 3 * size);
MPI_Gather(sbuf, 3, MPI_INT, rbuf, 3, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0){
printf("Process 0 receives:");
for (i = 0; i < size * 3; i++)
printf("%d ", rbuf[i]);
putchar('\n');
}
MPI_Finalize();
return 0;
}

8.把0号进程的值发给所有进程,每个进程得到的值不一样
#include<stdio.h>
#include<mpi.h>
#include<stdlib.h>
int main(int argc, char** argv){
int rank, size, *sbuf, rbuf[3], i;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank == 0){
sbuf = (int *) malloc(sizeof(int) * 3 * size);
for (i = 0; i < size * 3; i++)
sbuf[i] = i + 1;
}
MPI_Scatter(sbuf, 3, MPI_INT, rbuf, 3, MPI_INT, 0, MPI_COMM_WORLD);
printf("Process %d receives: ", rank);
for (i = 0; i < 3; i++)
printf("%d ", rbuf[i]);
putchar('\n');
MPI_Finalize();
return 0;
}

9.与gather不同,所有进程都收集到其他进程的消息
#include<stdio.h>
#include<mpi.h>
#include<stdlib.h>
int main(int argc, char **argv){
int rank, size, sbuf[3], *rbuf, i;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
for (i = 0; i < 3; i++)
sbuf[i] = rank * 10 + i;
rbuf = (int*)malloc(sizeof(int) * 3 * size);
MPI_Allgather(sbuf, 3, MPI_INT, rbuf, 3, MPI_INT, MPI_COMM_WORLD);
printf("Process %d receives:", rank);
for (i = 0; i < size * 3; i++)
printf("%d ", rbuf[i]);
putchar('\n');
free(rbuf);
MPI_Finalize();
return 0;
}

10.有三个任务,把

task1 task2 task3
0 1 2
3 4 5
6 7 8
9 10 11
转换成:
rank0 rank1 rank2 rank3
0 3 6 9
1 4 7 10
2 5 8 11
#include<stdio.h>
#include<mpi.h>
#include<stdlib.h>
int main(int argc, char** argv){
int rank, size, *sbuf, *rbuf, i;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
sbuf = (int*)malloc(size * 3 * sizeof(int));
rbuf = (int*)malloc(size * 3 * sizeof(int));
for (i = 0; i < size * 3; i++)
sbuf[i] = rank * 10 + i;
printf("Before exchange, process %d has ", rank);
for (i = 0; i < size * 3; i++)
printf("%d ", sbuf[i]);
putchar('\n');
MPI_Alltoall(sbuf, 3, MPI_INT, rbuf, 3, MPI_INT, MPI_COMM_WORLD);
printf("After exchange, process %d has ", rank);
for (i = 0; i < size * 3; i++)
printf("%d ", rbuf[i]);
putchar('\n');
MPI_Finalize();
free(sbuf);
free(rbuf);
return 0;
}

11.对每个任务(一列)求和
#include<stdio.h>
#include<mpi.h>
#include<stdlib.h>
int main(int argc, char** argv) {
int size, rank, sbuf[3], rbuf[3], i;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
for (i = 0; i < 3; i++) sbuf[i] = rank * 10 + i;
printf("Process %d has: ", rank);
for (i = 0; i < 3; i++) printf("%d ", sbuf[i]);
putchar('\n');
MPI_Reduce(sbuf, rbuf, 3, MPI_INT, MPI_SUM, 0,MPI_COMM_WORLD);
if (rank == 0) {
printf("Total sum = ");
for (i = 0; i < 3; i++) printf("%d ",rbuf[i]);
putchar('\n');
}
MPI_Finalize();
}

12.对每个任务(一列)求最大值,并求出其所在进程编号,0号进程输出结果
#include<stdio.h>
#include<mpi.h>
#include<stdlib.h>
typedef struct{ int val; int rank;}DATATYPE;
int main(int argc, char** argv){
int size, rank, i; DATATYPE sbuf[3], rbuf[3];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
srand(time(NULL) + rank);
printf("Process %d has ", rank);
for (i = 0; i < 3; i++){
sbuf[i].val = rand() % 100;
sbuf[i].rank = rank;
printf("%d ", sbuf[i].val);
}
putchar('\n');
MPI_Reduce(sbuf, rbuf, 3, MPI_2INT, MPI_MAXLOC, 0, MPI_COMM_WORLD);
if (rank == 0){
printf("max value and location are:\n");
for (i = 0; i < 3; i++) printf("value = %d, location = %d\n", rbuf
[i].val, rbuf[i].rank);
}
MPI_Finalize();
return 0;
}

13.对每一列求最大值,每个进程都得到结果并输出
#include<stdio.h>
#include<mpi.h>
#include<stdlib.h>
int main(int argc, char** argv) {
int size, rank, sbuf[3], rbuf[3], i;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
for (i = 0; i < 3; i++) sbuf[i] = rank * 10 + i;
printf("Process %d has: ", rank);
for (i = 0; i < 3; i++) printf("%d ", sbuf[i]);
putchar('\n');
MPI_Allreduce(sbuf, rbuf, 3, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
printf("Total sum of process %d = ", rank);
for (i = 0; i < 3; i++) printf("%d ",rbuf[i]);
putchar('\n');
MPI_Finalize();
}

14.每遍历一个进程对其与前面的进程的每一列求和
#include<stdio.h>
#include<mpi.h>
#include<stdlib.h>
int main(int argc, char** argv) {
int size, rank, sbuf[3], rbuf[3], i;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
for (i = 0; i < 3; i++) sbuf[i] = rank * 10 + i;
printf("Process %d has: ", rank);
for (i = 0; i < 3; i++) printf("%d ", sbuf[i]); putchar('\n');
MPI_Scan(sbuf, rbuf, 3, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
printf("Process %d has results ", rank);
for (i = 0; i < 3; i++) printf("%d ", rbuf[i]);
putchar('\n');
MPI_Finalize();
}

二.函数
1.send

MPI_Send(
void* data,// starting address of the data to be sent
int count,//number of elements to be sent (not bytes)
MPI_Datatype datatype,//MPI datatype of each element
int destination, //rank of destination process
int tag,//message identifier (set by user)
MPI_Comm comm) //MPI communicator of processors involved

2.recv

MPI_Recv(
void* data, //starting address of buffer to store message
int count, //number of elements to be received (not bytes)
MPI_Datatype datatype, //MPI datatype of each element
int source,// rank of source process
int tag,//message identifier (set by user)
MPI_Comm comm, //MPI communicator of processors involved
MPI_Status* status) //structure of information about the message

3.Broadcast把一个进程的内容发送给所有进程广播

int MPI_Bcast(
void* buffer,//starting address of buffer
int count, //number of entries in buffer
MPI_Datatype datatype,//data type of buffer
int root, //rank of broadcast root
MPI_Comm comm)//communicator

4.gather0号进程收集其他进程的消息

int MPI_Gather(
const void* sendbuf, //starting address of send buffer
int sendcount, //number of elements in send buffer
MPI_Datatype sendtype,//data type of send buffer elements
void* recvbuf, //address of receive buffer (significant only at root)
int recvcount,//number of elements for any single receive (significant only at root)
MPI_Datatype recvtype,//data type of recv buffer elements(significant only at root)
int root,//rank of receiving process
MPI_Comm comm)//communicator

5.scatter 把0号进程的值发给所有进程,每个进程得到的值不一样

int MPI_Scatter (
void * sendbuf , // pointer to send buffer
int sendcount , // items to send per process
MPI_Datatype sendtype , // type of send buffer data
void * recvbuf , // pointer to receive buffer
int recvcount , // number of items to receive
MPI_Datatype recvtype , // type of receive buffer data
int root , // rank of sending process
MPI_Comm comm ) // MPI communicator to use

6.allgather与gather不同,allgather不只0号进程收集其他进程的消息,所有进程都会收集到其他进程的消息

int MPI_Allgather (
void * sendbuf , // pointer to send buffer
int sendcount , // number of items to send
MPI_Datatype sendtype , // type of send buffer data
void * recvbuf , // pointer to receive buffer
int recvcount , // items to receive per process
MPI_Datatype recvtype , // type of receive buffer data
MPI_Comm comm ) // MPI communicator to use

7.alltoall

int MPI_Alltoall(
const void *sendbuf,
int sendcount, //number of elements to send to each process
MPI_Datatype sendtype, //data type of send buffer elements
void *recvbuf, //address of receive buffer
int recvcount, //number of elements received from any process
MPI_Datatype recvtype, //data type of receive buffer elements
MPI_Comm comm) //communicator

8.reduce

MPI_Reduce(
void* send_data, //address of send buffer
void* recv_data, //address of receive buffer
int count,//number of elements in send buffer
MPI_Datatype datatype, //data type of elements of send buffer
MPI_Op op, //reduce operation MPI的操作函数PPT87页
int root, rank of root process
MPI_Comm communicator) //communicator

9.Allreduce

MPI_Allreduce(
void* send_data, //address of send buffer
void* recv_data,//address of receive buffer
int count, //number of elements in send buffer
MPI_Datatype datatype, //data type of elements of send buffer
MPI_Op op, //reduce operation
MPI_Comm communicator) //communicator

10.Scan

int MPI_Scan(
const void* sendbuf,//address of send buffer
void* recvbuf, //address of receive buffer
int count, //number of elements in send buffer
MPI_Datatype datatype, //data type of elements of send buffer
MPI_Op op,//reduce operation
MPI_Comm comm) //communicator

云计算--MPI的更多相关文章

  1. 【转】OpenStack和Docker、ServerLess能不能决定云计算胜负吗?

    还记得在十多年前,SaaS鼻祖SalesForce喊出的口号『No Software』吗?SalesForce在这个口号声中开创了SaaS行业,并成为当今市值460亿美元的SaaS之王.今天谈谈『No ...

  2. 从CPU/OS到虚拟机和云计算

      从CPU/OS到虚拟机和云计算  作者:张冬            关于软硬件谁为主导这个话题,套用一句谚语就是三十年河东三十年河西.风水轮流转.软件和硬件一定是相互促进.相互拆台又相互搭台的. ...

  3. 云计算下PAAS的解析一

    云计算下PAAS的解析一       PaaS是Platform-as-a-Service的缩写,意思是平台即服务. 把服务器平台作为一种服务提供的商业模式.通过网络进行程序提供的服务称之为SaaS( ...

  4. 查找素数Eratosthenes筛法的mpi程序

    思路: 只保留奇数 (1)由输入的整数n确定存储奇数(不包括1)的数组大小: n=(n%2==0)?(n/2-1):((n-1)/2);//n为存储奇数的数组大小,不包括基数1 (2)由数组大小n.进 ...

  5. kmeans算法并行化的mpi程序

    用c语言写了kmeans算法的串行程序,再用mpi来写并行版的,貌似参照着串行版来写并行版,效果不是很赏心悦目~ 并行化思路: 使用主从模式.由一个节点充当主节点负责数据的划分与分配,其他节点完成本地 ...

  6. DevOps是云计算时代的开发与运营

    DevOps(英文Development和Operations的组合)是一组过程.方法与系统的统称,用于促进开发(应用程序/软件工程).技术运营和质量保障(QA)部门之间的沟通.协作与整合.[1] 它 ...

  7. 云计算之路-阿里云上:从ASP.NET线程角度对“黑色30秒”问题的全新分析

    在这篇博文中,我们抛开对阿里云的怀疑,完全从ASP.NET的角度进行分析,看能不能找到针对问题现象的更合理的解释. “黑色30秒”问题现象的主要特征是:排队的请求(Requests Queued)突增 ...

  8. SOA、ESB、NServiceBus、云计算 总结

    SOA SOA 是通过功能组件化.服务化,来实现系统集成.解决信息孤岛,这是其主要目标.而更进一步则是实现更快响应业务的变化.更快推出新的应用系统.与此同时,SOA 还实现了整合资源,资源复用. SO ...

  9. 云计算与 OpenStack - 每天5分钟玩转 OpenStack(14)

    “云计算” 算是近年来最热的词了.现在 IT 行业见面不说这三个字您都不好意思跟人家打招呼. 对于云计算,学术界有各种定义,大家有兴趣可以百度一下. CloudMan 这里主要想从技术的角度谈谈对云计 ...

随机推荐

  1. 《Linux内核设计与实现》读书笔记——第一、 二章

    <Linux内核设计与实现>读书笔记--第一. 二章 标签(空格分隔): 20135321余佳源 第一章 Linux内核简介 1.Unix内核特点 十分简洁:仅提供几百个系统调用并且有明确 ...

  2. C语言版本:单链表的实现(优化版本)

    未优化版本:http://www.cnblogs.com/duwenxing/p/7569376.html slist.h #ifndef __SLIST_H__ #define __SLIST_H_ ...

  3. k8s 实验过程中遇到的两个小问题 端口 和 批量删除Error的pods

    1. 自己kubeadm搭建的一套k8s系统 然后进行做实验 发现了几个问题 jenkins 创建 salves的时候总是有问题.  提示注册不上 然后 我修改了下yaml文件 暴露端口 50000 ...

  4. 异步查询json传日期格式到前台,变成了时间戳的格式

    问题: 使用mybatis 查询mysql数据库,其中一个日期格式的字段,由异步查询使用 json传递到前台,变成了时间戳,而不是日期格式了.如何使查询出的日期展示成日期格式呢 解决办法: 1.尝试使 ...

  5. 洛谷 P2671 求和 解题报告

    P2671 求和 题目描述 一条狭长的纸带被均匀划分出了\(n\)个格子,格子编号从\(1\)到\(n\) .每个格子上都染了一种颜色\(color_i\)用\([1,m]\)当中的一个整数表示),并 ...

  6. bzoj3612 平衡 (dp)

    设f[i][j]为把i拆成j个不重复的.大于0小于等于N的数的方案数 我们考虑一个方案是怎么来的:(初始状态是f[0][0]=1) 如果这个方案里有1,那它是先把原来的状态的每个数加1.然后再增加一个 ...

  7. LOJ#2983. 「WC2019」数树

    传送门 抄题解 \(Task0\),随便做一下,设 \(cnt\) 为相同的边的个数,输出 \(y^{n-cnt}\) \(Task1\),给定其中一棵树 设初始答案为 \(y^n\),首先可以发现, ...

  8. 洛谷P3302 森林

    题意:给定森林,可以把两棵树连起来或者询问链上第k大. 解:启发式合并. 我一开始想到了启发式合并但是发现这样做之后一棵子树就不是一段连续的区间了,那就不能子树xxx了,很迷惘. 后来看了题解发现本来 ...

  9. WebService注解总结

    @WebService 1.serviceName: 对外发布的服务名,指定 Web Service 的服务名称:wsdl:service.缺省值为 Java 类的简单名称 + Service.(字符 ...

  10. C++11 & C++14 & C++17新特性

    C++11:C++11包括大量的新特性:包括lambda表达式,类型推导关键字auto.decltype,和模板的大量改进. 新的关键字 auto C++11中引入auto第一种作用是为了自动类型推导 ...