- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当我使用超过 1 个处理器执行程序时,程序将停止工作。它在第一个 MPI_Send
处停止我做错了什么?
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 200000
#define SIZE2 256
#define VYVOD 1
int main(int argc, char *argv[])
{
int NX, NT;
double TK, UM, DX, DY, DT;
double starttime, endtime;
int numnode, rank, delta=0, ierr, NXnode;
double **U;
double **U1;
double *sosed1;
double *sosed2;
int i, j, k;
MPI_Status stats;
NX = 1*(SIZE2+1);
TK = 20.00;
UM = 10.0;
DX = 0.1;
DY = DX;
DT = 0.1;
NT = (TK/DT);
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&numnode);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
if(rank == 0)
printf("\nTotal nodes: %d\n", numnode);
NX = NX - 2;
NXnode = (NX-(NX%numnode))/numnode;
if (rank < (NX%numnode))
{
delta = rank * NXnode + rank + 1;
NXnode++;
}
else
{
delta = rank * NXnode + (NX%numnode) + 1;
}
if(rank == 0){
printf("Order counting complete, NXnode = %d\n", NXnode);
}
U = (double**)malloc(NXnode*sizeof(double*));
U1 = (double**)malloc(NXnode*sizeof(double*));
sosed1 = (double*)malloc(SIZE*sizeof(double));
sosed2 = (double*)malloc(SIZE*sizeof(double));
for (i=0; i < NXnode; i++)
{
U[i] = (double*)malloc(SIZE*sizeof(double));
U[i][0]=0;
U[i][SIZE-1]=0;
U1[i] = (double*)malloc(SIZE*sizeof(double));
U1[i][0]=0;
U1[i][SIZE-1]=0;
if (U[i]==NULL || U1[i]==NULL)
{
printf("Error at memory allocation!");
return 1;
}
}
MPI_Barrier(MPI_COMM_WORLD);
if(rank == 0){
starttime = MPI_Wtime();
printf("Array allocation complete\n");
}
for (i = 0; i < NXnode; i++)
{
for (j = 1; j < SIZE-1; j++)
{
if ((delta)<=(NXnode/2))
{
U1[i][j]=2*(UM/NXnode)*(delta+i);
}
else
{
U1[i][j]=-2*(UM/NXnode) + 2*UM;
}
}
}
printf("Array init 1 complete, rank %d\n", rank);
MPI_Barrier(MPI_COMM_WORLD);
if (rank > 0)
{
MPI_Send(&(U1[0][0]), SIZE, MPI_DOUBLE , rank-1, 0, MPI_COMM_WORLD);
MPI_Recv(&(sosed1[0]), SIZE, MPI_DOUBLE , rank-1, 1, MPI_COMM_WORLD, &stats);
}
else
{
int initInd = 0;
for (initInd = 0; initInd < SIZE; initInd++)
{
sosed1[initInd]=0;
}
}
if (rank < (numnode-1))
{
MPI_Send(&(U1[NXnode-1][0]), SIZE, MPI_DOUBLE , rank+1, 1, MPI_COMM_WORLD);
MPI_Recv(&(sosed2[0]), SIZE, MPI_DOUBLE , rank+1, 0, MPI_COMM_WORLD, &stats);
}
else
{
int initInd = 0;
for (initInd = 0; initInd < SIZE; initInd++)
{
sosed2[initInd]=0;
}
}
printf("Send complete, rank %d\n", rank);
MPI_Barrier(MPI_COMM_WORLD);
printf("Array init complete, rank %d\n", rank);
for (k = 1; k <= NT; k++)
{
int cycle = 0;
for (cycle=1; cycle < SIZE-1; cycle++)
{
U[0][cycle] = U1[0][cycle] + DT/(DX*DX)*(U1[1][cycle]-2*U1[0][cycle]+sosed1[cycle])+DT/(DY*DY)*(U1[0][cycle+1]+U1[0][cycle-1]-(U1[0][cycle]*2));
}
for (i=1; i<NXnode-1; i++)
{
for(j=1; j<SIZE-1; j++)
{
U[i][j] = U1[i][j] + DT/(DX*DX)*(U1[i+1][j]-2*U1[i][j]+U[i-1][j])+DT/(DY*DY)*(U1[i][j+1]+U1[i][j-1]-(U1[i][j]*2));
}
}
for (cycle=1; cycle < SIZE-1; cycle++)
{
U[NXnode-1][cycle]=U1[NXnode-1][cycle]+DT/(DX*DX)*(sosed2[cycle]-2*U1[NXnode-1][cycle]+U1[NXnode-2][cycle])+DT/(DY*DY)*(U1[NXnode-1][cycle+1]+U1[NXnode-1][cycle-1]-(U1[NXnode-1][cycle]*2));
}
/*U[0] = U1[0]+DT/(DX*DX)*(U1[0+1]-2*U1[0]+sosed1);
for (j = 0; j<NXnode; j++)
{
U[j]=U1[j]+DT/(DX*DX)*(U1[j+1]-2*U1[j]+U1[j-1]);
}
U[NXnode-1]=U1[NXnode-1]+DT/(DX*DX)*(sosed2-2*U1[NXnode-1]+U1[(NXnode-1)-1]);*/
if (rank > 0)
{
MPI_Send(&(U[0][0]), SIZE, MPI_DOUBLE , rank-1, 0, MPI_COMM_WORLD);
}
if (rank < (numnode-1))
{
MPI_Send(&(U[NXnode-1][0]), SIZE, MPI_DOUBLE , rank+1, 0, MPI_COMM_WORLD);
}
if (rank > 0)
{
MPI_Recv(&(sosed1[0]), SIZE, MPI_DOUBLE , rank-1, 0, MPI_COMM_WORLD, &stats);
}
if (rank < (numnode-1))
{
MPI_Recv(&(sosed2[0]), SIZE, MPI_DOUBLE , rank+1, 0, MPI_COMM_WORLD, &stats);
}
for (i = 0; i<NXnode; i++)
{
for (j=0; j<SIZE; j++)
{
U1[i][j]=U[i][j];
}
}
}
MPI_Barrier(MPI_COMM_WORLD);
printf("Array count complete, rank %d\n", rank);
if (rank == 0)
{
endtime=MPI_Wtime();
printf("\n## TIME: %f\n", endtime-starttime);
}
MPI_Finalize();
}
更新#1像这样尝试过,所以排名 0 将是第一个,仍然不起作用:
MPI_Barrier(MPI_COMM_WORLD);
if (rank == 0 && numnode > 1)
{
MPI_Recv(&(sosed2[0]), SIZE, MPI_DOUBLE , rank+1, 0, MPI_COMM_WORLD, &stats);
MPI_Send(&(U1[NXnode-1][0]), SIZE, MPI_DOUBLE , rank+1, 1, MPI_COMM_WORLD);
int initInd = 0;
for (initInd = 0; initInd < SIZE; initInd++)
{
sosed1[initInd]=0;
}
}
else if (rank == 0)
{
int initInd = 0;
for (initInd = 0; initInd < SIZE; initInd++)
{
sosed2[initInd]=0;
sosed1[initInd]=0;
}
}
else if (rank < (numnode-1))
{
MPI_Send(&(U1[0][0]), SIZE, MPI_DOUBLE , rank-1, 1, MPI_COMM_WORLD);
MPI_Recv(&(sosed1[0]), SIZE, MPI_DOUBLE , rank-1, 0, MPI_COMM_WORLD, &stats);
MPI_Recv(&(sosed2[0]), SIZE, MPI_DOUBLE , rank+1, 0, MPI_COMM_WORLD, &stats);
MPI_Send(&(U1[NXnode-1][0]), SIZE, MPI_DOUBLE , rank+1, 1, MPI_COMM_WORLD);
}
else if (rank == (numnode - 1))
{
MPI_Send(&(U1[0][0]), SIZE, MPI_DOUBLE , rank-1, 1, MPI_COMM_WORLD);
MPI_Recv(&(sosed1[0]), SIZE, MPI_DOUBLE , rank-1, 0, MPI_COMM_WORLD, &stats);
int initInd = 0;
for (initInd = 0; initInd < SIZE; initInd++)
{
sosed2[initInd]=0;
}
}
更新#2已解决,对所有发送/接收使用相同的标签。
最佳答案
MPI_Send
会阻塞执行,直到调用相应的 MPI_Recv
(可能在另一个进程中)。
在您的程序中,除了rank=0 之外的所有进程都在第一个屏障之后立即调用MPI_Send
,并且没有人准备好Recv
消息,因此 MPI_Send
无限阻塞。本质上,每个进程都在等待其消息被较低级别的进程接受(级别 2 正在等待级别 1,级别 1 正在等待级别 0),而级别 0 根本不接受任何消息(它会到下一个代码块,并依次调用 MPI_Send
),因此一切都会挂起。
看起来您缺少等级 = 0 的进程的通信部分(它应该执行类似 MPI_Recv(从等级 1); ...; MPI_Send(到等级 1);
的操作。
另一件事是,您将 MPI_Send
与标记 1
一起使用,但使用标记 0
调用 MPI_Recv
。这不会成双成对。您需要使用相同的标签,或者在接收操作中指定MPI_TAG_ANY
。
关于c - 程序在 MPI_Send 处停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28137351/
我有一个使用 openmpi 编译和运行的代码。最近,我想使用 Intel MPI 运行同样的代码。但是我的代码没有按预期工作。我深入研究了代码,发现 MPI_Send 在两个实现中的行为不同。 我从
我想将 MPI_Send 消息发送到单个但可变的主机。我的意思是,我在编译时不知道要发送消息的主机的级别。 很自然地,我写的内容如下: MPI_Send(&myIntData, 1, MPI_INT,
我可以在单个 MPI_SEND 中发送一个矩阵的行和另一个矩阵的列,我该如何执行此过程? MPI_SEND (row and column of the matrix ...) 最佳答案 由于 C/C
我有以下代码: double * myX; double * myY; double * myZ; int amount; int count; // number of process v
我正在编写 mpi 的 C++ 包装器。 我在 mpi 遇到了一个奇怪的错误:在我的例子中,错误只在消息足够大时出现,运行时错误如下: Fatal error in MPI_Send: Other M
如果我想定义自己的类型,并将其用作 MPI_Send 的数据类型以仅从矩阵中获取偶数行,是否必须静态分配该矩阵(发送缓冲区)? 我动态分配的时候好像有问题。这是因为地址需要连续才能发送数据吗? 最佳答
我正在使用 MPI 编写 Mergesort 来对整数数组进行排序。这个想法是在同一等级上对数组的左半部分进行归并排序,同时将数组的右半部分发送到子等级。所以如果有四个过程,它看起来像这样:
我必须在我的程序中使用 MPI API 发送/接收矩阵。为了发送矩阵,我使用了以下语法: MPI_Send(matrix, ...) <- USE THIS MPI_Send(&matrix, ..
在大量内核上调试我的程序时,我遇到了非常奇怪的虚拟内存不足错误。我的调查导致代码和平,主人向每个奴隶发送小消息。然后我写了一个小程序,其中 1 个主机使用 MPI_SEND 发送 10 个整数,所有从
这是我在 stackoverflow 中的第一个问题。我有两个进程,一个根 0 和一个从属 1。从属分配一个二维数组 (CHUNK_ROWS+2,CHUNK_COLUMNS+2) 并想发送一个 [CH
我正在尝试使用 MPI 形成环形通信,其中我的每个进程都将其结果发送到下一个进程,最后一个进程将结果发送到第 0 个进程。假设我有 4 个进程,那么我的第 0 个进程会将结果发送到第 1 个、第 1
我得到了一个小练习,我必须通过使用 MPI 来估计 n 个球体的总体积来实现蒙特卡罗算法,这些球体的中心坐标和半径在 3 维中。即使我们必须使用 MPI,我们也可以在本地机器上启动所有进程,因此没有网
当我使用超过 1 个处理器执行程序时,程序将停止工作。它在第一个 MPI_Send 处停止我做错了什么? #include "mpi.h" #include #include #include
我有一个主进程和更多从进程。我希望每个从进程向主进程发送一个整数,所以我想我应该使用 MPI_Gather 收集它们。但不知怎的,它不起作用,我开始认为 MPI_Gather 与 MPI_Send 不
我正在尝试将多列“B”矩阵从处理器 0 发送到不同的处理器。我正在尝试使用 MPI_Send 进行发送,但它不起作用。有人可以帮助我吗? 例如:方阵 B 的大小为 7。这样就应该被分发了。 处理器 0
最近才知道MPI_Send不能一次发送太长的数据,所以决定把数据分成几 block ,用for循环发送。下面是一个测试用例。这里的问题是,如果我使用少量数据并将其分成几 block ,程序将运行;但是
我正在尝试使用 MPI 在 C++ 中处理一些动态分配的多维数组。为了避免担心不连续的内存,我编写了一个类包装器,它允许我像访问二维数组一样访问一维数组。我正在尝试创建一个 MPI 数据类型以通过 M
这可能是一件微不足道的事情,但是: 底层数组的大小是否可以长于在 MPI_Send( ... ) 调用中与缓冲区指针一起发送的计数参数? 至于 MPI_Recv( ... ),我发现消息来源清楚地表明
我正在尝试运行下面使用并行编程的程序。如果我们使用 4 个处理器,我希望它们包含总和 1+2=3、3+4=7、11 和 15。所以我希望求和 vector 按顺序包含 3、7、11 和 15。但是,由
我正在学习 MPI_Send,但我对这种方法感到困惑。我写了一个简单的乒乓程序,rank-0 节点发送消息给 rank-1 节点,然后后者返回消息给前一个。 if (rank == 0) { /*
我是一名优秀的程序员,十分优秀!