考试比较难,课程比较繁琐。把老师每节课留的课后题都做一些,考试基本就是这些东西
高性能计算2022 加粗样式 考试
1. 启动MPI程序时系统生成的是1维程序···
- 写出一个子程序或函数生成行和列通讯子
思路:
首先进行参数合法性的检查,然后将通信子对应的进程组进行划分,再将通信子对应的进程组进行列划分,最后将通信子中的进程编号使用MPI_Comm_rank进行分发
int getComm(int myid, int np, int p, int q, int myrow,int mycol, MPI_Comm *rowComm,MPI_Comm *colComm){
if(np < p * q) return 1;
int key, color;
if(myid < p * q)
col = myid / q;
else
color = MPI_UNDEEFINED
key = myid;
MPI_Comm_split(MPI_COMM_WORLD, color, key, rowComm);
if(myid < p*q)
color = myid % q;
else
col = MPI_UNDEEFINED;
key = myid;
MPI_Comm_split(MPI_COMM_WORLD, color,key,colComm);
if(myid < p*q){
MPI_Comm_rank(colComm, &myrow);
MPI_Comm_rank(rowComm, &mycol);
}
return 0;
}
- 卷帘方式计算值
使用卷帘存储方式,即对于一般的mn 矩阵和一般的处理器阵列pq,矩阵元素a i j a_{ij}a ij 存放在处理器P k l P_{kl}P k l 中,其中k=i mod p, l=j mod q。用一个8行8列的矩阵在3*2的处理器阵列进行处理,可知对于a i j = a s t k l a_{ij} = a^{kl}_{st}a ij =a s t k l 有,k = i m o d p , l = j m o d q , s = i / p , t = j / q k=i\space{mod}\space p, l = j \space mod \space q,s = i/p, t = j/q k =i m o d p ,l =j m o d q ,s =i /p ,t =j /q
- 广播进程的实现
思路:
现在第0行的行进程中广播p 00 p_{00}p 00 上的数据A,此时整行都有该数据,然后再各个列通讯子中广播到整列
int broadcastRowCol(int myid, int np, int myrow, int mycol, float *a, int count, MPI_Comm rowComm,MPI_Comm colComm){
if(myrow == 0)
MPI_Bcast(a, count, MPI_FLOAT, 0, rowComm);
MPI_Bcast(a, count, MPI_FLOAT, 0, colComm);
}
2. 分块矩阵
- 一次性发送和接收A 00 A_{00}A 00 和A 20 A_{20}A 20
思路: 使用MPI_Type_vector 函数构建一个vector 的类型,命名为submat,然后使其extent ,即延伸尺寸正好可以覆盖第一行和第二行矩阵块,然后我们如果使用两个submat 变量,第一个submat 变量传输的内容是A 00 A_{00}A 00 ,但其延伸尺寸覆盖过了第一行其他矩阵块和第二行矩阵块,第二个submat 的起点正好是A 20 A_{20}A 20 ,可以传输A 20 A_{20}A 20 矩阵块。
MPI_Datatype submat_base, submat;
MPI_Type_vector(m, m, n, MPI_FLOAT, &submat_base);
int array_of_blocklens[2] = {1,1};
int array_of_disps[2] = {0,2*m*n*sizeof(float)};
MPI_Datatype array_of_types[2] = {submat_base, MPI_UB};
MPI_Type_struct(2, array_of_blocklens, array_of_disps, array_of_types, &submat);
MPI_Type_commit(&submat);
- 只传输A 00 A_{00}A 00 和A 20 A_{20}A 20
思路:
以直接利用MPI_Type_indexed 将所需的内容索引到数据类型里就行了。沿用第1 问中的假设条件,先进行赋值块大小和块间隔,然后更正第二个矩阵块的间隔,最后提交结果
MPI_Datatype submat;
int *array_of_blocklens = new int[2 * m];
int *array_of_disps = new int[2 * m];
for(int i=0; i<2*m; i++){
array_of_blocklens[i] = m;
array_of_disps[i] = i * n;
}
for(int i=m; i<2*m; i++)
array_of_disps[i] = (i + 2 * m) * n;
MPI_Type_indexed(2*m, array_of_blocklens, array_of_disps, MPI_FLOAT, &submat);
MPI_Type_commit(&submat);
3. 自定义数据结构的分发
思路:
采用MPI_Type_struct 方法,将需要传输的内容整合成一个MPI 结构体进行传输。首先初始化进程环境,然后获取通信子的进程编号和进程个数,再使用MPI的进行自定义数据类型和打包
#include
#include
typedef struct{
int m[3];
float a[2];
char c[5];
}dataType;
int main(int argc, char**argv)
{
MPI_Init(&argc, &argv);
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Datatype newType;
int blocks[3] = {3, 2, 5};
MPI_Aint disps[3] = {0, 12, 20};
MPI_Datatype types[3] = {MPI_INT, MPI_FLOAT, MPI_CHAR};
MPI_Type_struct(3, blocks, disps, types, &newType);
MPI_Type_commit(&newType);
dataType t1 = {{1, 2, 3}, {4.0, 5.0}, {'a', 'b', 'c', 'd', '\0'}};
dataType t2;
if (rank == 0)
MPI_Send(&t1, 1, newType, 1, 0, MPI_COMM_WORLD);
else{
MPI_Recv(&t2, 1, newType, 0, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
printf("%d %d %d %f %f %s\n", t2.m[0], t2.m[1], t2.m[2], t2.a[0], t2.a[1],
t2.c);
}
MPI_Type_free(&newType);
MPI_Finalize();
}
4. MPI_Allgather的实现
- 一个如何实现的详细并行方法
思路:
MPI_Alltoall 的功能是全交换,即各个进程都在向所有进程发送对应的分段,同时从所以进程接收发来的分段。这里给出一种简单的实现方式,即每个进程使用一个循环向其他进程发送分段,同时循环中接受其他进程发来的分段,而自己发给自己的部分直接使用memcpy 拷贝 - MPI_Allgather子程序的实现
int myAlltoall(const void *sendbuf, int sendcount,
MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
{
int rank, size;
int type_size;
MPI_Type_size(sendtype, &type_size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
for (int i = 0; i < size; ++i){
if (i == rank){
memcpy(sendbuf + i * sendcount * type_size, recvbuf +
i * recvcount *type_size, sendcount * type_size);
continue;
}
MPI_Send(sendbuf + i * sendcount * type_size, sendcount,
sendtype, i, 0, MPI_COMM_WORLD);
MPI_Recv(recvbuf + i * recvcount * type_size,
recvcount, recvtype, i, 0,
MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
return 0;
}
Original: https://blog.csdn.net/qq_43840665/article/details/128749341
Author: 逆羽飘扬
Title: 国科大-高性能计算考试
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/814363/
转载文章受原作者版权保护。转载请注明原作者出处!