gpt4 book ai didi

c - 使用 MPI 库的递归函数

转载 作者:太空宇宙 更新时间:2023-11-04 02:21:31 25 4
gpt4 key购买 nike

我正在使用递归函数来查找 5x5 矩阵的行列式。虽然这听起来是一个微不足道的问题,但如果维度很大,可以使用 OpenMP 解决。我正在尝试使用 MPI 来解决这个问题,但是我无法理解如何处理累积结果的递归。

所以我的问题是,如何为此使用 MPI?

PS:矩阵是希尔伯特矩阵所以答案是0

我写了下面的代码,但我认为它只是将相同的部分做了 n 次,而不是划分问题然后累积结果。

#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define ROWS 5

double getDeterminant(double matrix[5][5], int iDim);
double matrix[ROWS][ROWS] = {
{1.0, -0.5, -0.33, -0.25,-0.2},
{-0.5, 0.33, -0.25, -0.2,-0.167},
{-0.33, -0.25, 0.2, -0.167,-0.1428},
{-0.25,-0.2, -0.167,0.1428,-0.125},
{-0.2, -0.167,-0.1428,-0.125,0.111},
};

int rank, size, tag = 0;

int main(int argc, char** argv)
{
//Status of messages for each individual rows
MPI_Status status[ROWS];

//Message ID or Rank
MPI_Request req[ROWS];

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

double result;
result = getDeterminant(matrix, ROWS);
printf("The determinant is %lf\n", result);

//Set barrier to wait for all processess
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();

return 0;
}

double getDeterminant(double matrix[ROWS][ROWS], int iDim)
{
int iCols, iMinorRow, iMinorCol, iTemp, iSign;
double c[5];
double tempMat[5][5];

double dDet;
dDet = 0;
if (iDim == 2)
{
dDet = (matrix[0][0] * matrix[1][1]) - (matrix[0][1] * matrix[1][0]);
return dDet;
}
else
{
for (iCols = 0; iCols < iDim; iCols++)
{
int temp_row = 0, temp_col = 0;
for (iMinorRow = 0; iMinorRow < iDim; iMinorRow++)
{
for (iMinorCol = 0; iMinorCol < iDim; iMinorCol++)
{
if (iMinorRow != 0 && iMinorCol != iCols)
{
tempMat[temp_row][temp_col] = matrix[iMinorRow][iMinorCol];
temp_col++;
if (temp_col >= iDim - 1)
{
temp_row++;
temp_col = 0;
}
}
}
}
//Hanlding the alternate signs while calculating diterminant
for (iTemp = 0, iSign = 1; iTemp < iCols; iTemp++)
{
iSign = (-1) * iSign;
}
//Evaluating what has been calculated if the resulting matrix is 2x2
c[iCols] = iSign * getDeterminant(tempMat, iDim - 1);
}
for (iCols = 0, dDet = 0.0; iCols < iDim; iCols++)
{
dDet = dDet + (matrix[0][iCols] * c[iCols]);
}
return dDet;
}
}

预期结果应该是一个非常小的接近于 0 的值。我得到了相同的结果但没有使用 MPI

最佳答案

提供的程序将在n个进程中执行。 mpirun 启动 n 个进程,它们都执行提供的代码。这是预期的行为。与 openmp 不同,MPI 不是共享内存编程模型,而是分布式内存编程模型。它使用消息传递与其他进程进行通信。MPI 中没有全局变量。您程序中的所有数据对于您的流程都是本地的。。如果您需要在进程之间共享数据,则必须使用 MPI_sendMPI_Bcast 等显式发送它。您可以使用集体操作,如MPI_Bcast,将其发送到所有进程或点对点操作,如MPI_send,以发送到具体流程。

为了让您的应用程序执行预期的行为,您必须针对 MPI 进行定制(不像在 openmp 中您可以使用编译指示)。所有进程都有一个标识符或等级。通常,等级 0(我们称之为您的主进程)应该使用 MPI_Send(或任何其他方法)将数据传递给所有进程,其余进程应该使用 MPI_Recv 接收它(对 MPI_Send 使用 MPI_Recv)。从主进程接收到本地数据后,本地进程应该对其进行一些计算,然后将结果发送回主进程。主进程将汇总结果。这是使用 MPI 的一个非常基本的场景。您可以使用 MPI IO 等。

MPI 本身不会为同步或数据共享做任何事情。它只是启动应用程序实例 n 次并提供所需的例程。应用程序开发人员负责进程间的通信(数据结构等)、同步(使用 MPI_Barrier)等。

以下是一个使用 MPI 的简单发送接收程序。当您运行下面的代码时,假设 n 为 2,将启动该程序的两个副本。在程序中,使用MPI_Comm_rank(),每个进程都会得到它的id。我们可以使用此 ID 进行进一步的计算/控制代码流。在下面的代码中,级别为 0 的进程将使用 MPI_Send 发送变量 number,级别为 1 的进程将使用 MPI_Recv 接收该值.我们可以看到 ifelse if 区分进程并改变控制流来发送和接收数据。这是一个非常基本的 MPI 程序,可在进程之间共享数据。

// Find out rank, size
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);

int number;
if (world_rank == 0) {
number = -1;
MPI_Send(&number, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
} else if (world_rank == 1) {
MPI_Recv(&number, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
printf("Process 1 received number %d from process 0\n",
number);
}

Here是关于 MPI 的教程。

关于c - 使用 MPI 库的递归函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57328442/

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