云计算--MPI
[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的更多相关文章
- 【转】OpenStack和Docker、ServerLess能不能决定云计算胜负吗?
还记得在十多年前,SaaS鼻祖SalesForce喊出的口号『No Software』吗?SalesForce在这个口号声中开创了SaaS行业,并成为当今市值460亿美元的SaaS之王.今天谈谈『No ...
- 从CPU/OS到虚拟机和云计算
从CPU/OS到虚拟机和云计算 作者:张冬 关于软硬件谁为主导这个话题,套用一句谚语就是三十年河东三十年河西.风水轮流转.软件和硬件一定是相互促进.相互拆台又相互搭台的. ...
- 云计算下PAAS的解析一
云计算下PAAS的解析一 PaaS是Platform-as-a-Service的缩写,意思是平台即服务. 把服务器平台作为一种服务提供的商业模式.通过网络进行程序提供的服务称之为SaaS( ...
- 查找素数Eratosthenes筛法的mpi程序
思路: 只保留奇数 (1)由输入的整数n确定存储奇数(不包括1)的数组大小: n=(n%2==0)?(n/2-1):((n-1)/2);//n为存储奇数的数组大小,不包括基数1 (2)由数组大小n.进 ...
- kmeans算法并行化的mpi程序
用c语言写了kmeans算法的串行程序,再用mpi来写并行版的,貌似参照着串行版来写并行版,效果不是很赏心悦目~ 并行化思路: 使用主从模式.由一个节点充当主节点负责数据的划分与分配,其他节点完成本地 ...
- DevOps是云计算时代的开发与运营
DevOps(英文Development和Operations的组合)是一组过程.方法与系统的统称,用于促进开发(应用程序/软件工程).技术运营和质量保障(QA)部门之间的沟通.协作与整合.[1] 它 ...
- 云计算之路-阿里云上:从ASP.NET线程角度对“黑色30秒”问题的全新分析
在这篇博文中,我们抛开对阿里云的怀疑,完全从ASP.NET的角度进行分析,看能不能找到针对问题现象的更合理的解释. “黑色30秒”问题现象的主要特征是:排队的请求(Requests Queued)突增 ...
- SOA、ESB、NServiceBus、云计算 总结
SOA SOA 是通过功能组件化.服务化,来实现系统集成.解决信息孤岛,这是其主要目标.而更进一步则是实现更快响应业务的变化.更快推出新的应用系统.与此同时,SOA 还实现了整合资源,资源复用. SO ...
- 云计算与 OpenStack - 每天5分钟玩转 OpenStack(14)
“云计算” 算是近年来最热的词了.现在 IT 行业见面不说这三个字您都不好意思跟人家打招呼. 对于云计算,学术界有各种定义,大家有兴趣可以百度一下. CloudMan 这里主要想从技术的角度谈谈对云计 ...
随机推荐
- 《Linux内核分析》-- 扒开系统调用的三层皮(下)之system_call中断处理过程 20135311傅冬菁
20135311傅冬菁 原创作品 <Linux内核分析>MOOC课程 分析system_call中断处理过程 内容分析与总结: 系统调用在内核代码中的工作机制和初始化 系统调用在用户态中 ...
- 《实时控制软件设计》之Automation Studio开发环境
Automation Studio是贝加莱公司的控制软件开发平台,软件可运行在贝加莱的基于PC的控制器上,基于Automation Studio我们可构建一个完整的控制软件构建.测试和仿真运行平台.本 ...
- ubuntu18.04配置nvidia docker和远程连接ssh+远程桌面连接(一)
ubuntu18.04配置nvidia docker和远程连接ssh+远程桌面连接(一) 本教程适用于想要在远程服务器上配置docker图形界面用于深度学习的用户. (一)ubuntu18.04配置n ...
- jQuery~DOM基础操作
操作DOM 1.什么是DOM:document object model文档对象模型 2.树形结构 3.什么是节点(node):DOM结构中最小单位,元素.文本.属性...创建节点 var $div ...
- Ubuntu忘记MySQL密码重设方法
====================忘了mysql密码,从网上找到的解决方案记录在这里==================== 结束当前正在运行的mysql进程 # /etc/init.d/mys ...
- HTTTP及TCP的超时以及KEEP-ALIVE机制小结
一.HTTP的超时和Keep Alive HTTP Keepalive 机制是http 1.1中增加的一个功能. 在HTTP 1.0中,客户端每发起一个http 请求,等收到接收方的应答之后就断开TC ...
- 【题解】 [POI2012]FES-Festival (差分约束)
懒得复制题面,戳我戳我 Question: (因为网上找不到好的翻译,这里简单复述一下) 告诉你\(m1+m2\)个约束条件,然后要你找出\(X_1-X_n\)这些数字,求满足要求的数列中不同的数字个 ...
- 【BZOJ1432】[ZJOI2009]Function(找规律)
[BZOJ1432][ZJOI2009]Function(找规律) 题面 BZOJ 洛谷 题解 这...找找规律吧. #include<iostream> using namespace ...
- luogu2375 动物园 (kmp)
首先求出fail数组,如果没有不重叠的限制的话,我们可以在求fail的时候递推出个数cnt[i]=cnt[fail[i]]+1(这个cnt是算上自己本身==自己本身的) 然后如果是要求不重叠的话,就是 ...
- SpringBoot中使用SpringDataJPA
SpringDataJPA的使用 JPA是什么? JPA(Java Persistence API)是Sun官方提出的Java持久化规范. 为Java开发人员提供了一种对象/关联映射工具来管理Java ...