gpt4 book ai didi

c - 使用 MPI Send/Recv 实现自己的矩阵乘法

转载 作者:行者123 更新时间:2023-11-30 16:13:32 29 4
gpt4 key购买 nike

我尝试编写一个名为matrixMultiply的函数,它只需要两个名为 a 和 b 的 4 x 4 矩阵,将它们相乘并将结果存储在 4 x 4 矩阵 c 中。之后,我想将该程序扩展为更通用的程序,适用于 n x n 矩阵。遗憾的是,程序可以编译,但在执行时却卡住了。如果有人能够告诉我我的错误在哪里,我将非常感激。

#import <stdio.h>
#import "mpi.h"

void matrixMultiply(int argc, char* argv[], int a[][4], int b[][4], int c[][4])
{
int n = 4;
int procs;
int rank;
int rootRank = 0;

MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD, &procs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

if(rank == rootRank) {
int current_row[4];
for(int i = 0; i < n; i++) {

int current_column[4];
for(int j = 0; j < n; j++) {

//getting the i-th row
for(int k = 0; k < n; k++) {
current_row[k] = a[i][k];
}

//getting the j-th column
for (int k = 0; k < n; k++)
{
current_column[k] = b[k][j];
}

//MPI_Send(void* data, int count, MPI_Datatype datatype, int destination, int tag, MPI_Comm communicator)
MPI_Bsend(current_row, 4, MPI_INT, i, 0, MPI_COMM_WORLD);
MPI_Bsend(current_column, 4, MPI_INT, i, 1, MPI_COMM_WORLD);

int result;
//MPI_Recv(void* data, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm communicator, MPI_Status* status)
MPI_Recv(&result, 1, MPI_INT, i ,2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
c[i][j]=result;
}
}

/* this code is only used to check the resulting matrix c*/
printf("c:\n");
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
printf("%d ", c[i][j]);
}
printf("\n");
}
printf("\n");

}
else {
int result = 0;
int local_row[4] = {0,0,0,0};
int local_column[4] = {2,2,2,2};

//MPI_Recv(void* data, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm communicator, MPI_Status* status)
MPI_Recv(local_row, 4, MPI_INT, rootRank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Recv(local_column, 4, MPI_INT, rootRank, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);

for(int i = 0; i < 4; i++) {
result+= local_row[i] * local_column[i];
}

//MPI_Send(void* data, int count, MPI_Datatype datatype, int destination, int tag, MPI_Comm communicator)
MPI_Bsend(&result, 1, MPI_INT, rootRank, 2, MPI_COMM_WORLD);
}
MPI_Finalize();
return;
}

int main(int argc, char* argv[]) {
int d[][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12},{13,14,15,16}};
int e[][4] = {{16,15,14,13}, {12,11,10,9}, {8,7,6,5}, {4,3,2,1}};
int f[][4] = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}};

matrixMultiply(argc, argv, d, e, f);

}

最佳答案

需要解决的几个问题:

MPI_Bsend(与MPI_Send相反)需要预先调用MPI_Buffer_attach。请参阅此处的注释:https://www.mpich.org/static/docs/latest/www3/MPI_Bsend.html或任何最新版本的 MPI 规范。

首先尝试进行该更改。这可能足以让它继续下去。如果不是,请仔细检查发送和接收的任何顺序(全局考虑),以查看系统中是否存在死锁。

顺便说一句,您可以通过切换到非阻塞发送和接收(MPI_IsendMPI_Irecv 及相关)来提高性能并避免一些死锁情况在它们全部启动后,通过 MPI_WaitallMPI_Testall 或类似方式完成它们。这将更类似于 MPI 实现通常在幕后执行集体操作的方式 - 与进行单独的发送和接收调用相比,这也可能具有性能优势,因为实现更多地了解硬件以及幕后发生的事情并且能够围绕它优化排序。您正在做的事情看起来类似于 MPI_Bcast 后跟 MPI_Gather,作为一种可能的替代模式,它将更加依赖于实现来为您进行优化。

关于c - 使用 MPI Send/Recv 实现自己的矩阵乘法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58015663/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com