[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内核分析作业 NO.1

    通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的 于佳心 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/cour ...

  2. KNY三人组对YiSmile小程序的项目总结

    设想和目标 1.我们的小程序要解决什么问题? 针对于本校学生,服务于本校学生.由于丢东西,找东西的事情每天都在上演,空间说说,朋友圈,官方QQ,信息比较冗杂,没有一个固定的平台来专门提供学生.此外,教 ...

  3. 2017-08-20 block,inline和inline-block概念和区别

    display:inline.block.inline-block的区别 display:block就是将元素显示为块级元素. block元素的特点是: 总是在新行上开始: 高度,行高以及顶和底边距都 ...

  4. 第八周PSP(11.5--11.9)

    2016.11.5 2016.11.6 2016.11.7 2016.11.8 2016.11.9

  5. Dubbo和Spring Cloud微服务架构比较

    Dubbo 出生于阿里系,是阿里巴巴服务化治理的核心框架,并被广泛应用于中国各互联网公司:只需要通过 Spring 配置的方式即可完成服务化,对于应用无入侵,设计的目的还是服务于自身的业务为主. 微服 ...

  6. Django通用视图APIView和视图集ViewSet的介绍和使用(Django编程-1)

    1.APIView DRF框架的视图的基类是 APIView APIView的基本使用和View类似 Django默认的View请求对象是 HttpRequest,REST framework 的请求 ...

  7. 【刷题】LOJ 6227 「网络流 24 题」最长k可重线段集问题

    题目描述 给定平面 \(\text{xoy}\) 上 \(n\) 个开线段组成的集合 \(\text{I}\) ,和一个正整数 \(k\) ,试设计一个算法. 从开线段集合 \(\text{I}\) ...

  8. NOIP2018退役总结

    NOIP2018退役总结 先说下成绩,应该压线二等. 也没有什么可以抱怨的,真的是心态的问题. 在Day1的时候这么简单的一套卷子,却打了三道暴力,175本来就是省二的水平.回来以后心态就崩了,因为D ...

  9. 【转】为什么 MQTT 是最适合物联网的网络协议

    初识 MQTT 为什么 MQTT 是最适合物联网的网络协议 Michael Yuan2017 年 6 月 14 日发布 WeiboGoogle+用电子邮件发送本页面 0 物联网 (IoT) 设备必须连 ...

  10. o2o优惠券使用预测

    前沿: 这是天池的一个新人实战塞题目,原址 https://tianchi.aliyun.com/getStart/information.htm?spm=5176.100067.5678.2.e13 ...