gpt4 book ai didi

c - C中的MPI。在 I_send 和 Irecv 中使用循环

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

我在 c 中有一个简单的 MPI 代码,我试图在其中学习如何在进程之间进行通信。这是代码:

已编辑代码 -> 问题已解决

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <mpi.h>
#include <unistd.h>

#define ONE 0
#define TWO 1

int main(int argc, char * argv[])
{
int dimension = 5,t;
float ** matrix;
float * mat1;
float * mat2,*mat;
int i,j,numNeighbor, processReceived,rank,size,retval;
int k = 0;
retval = MPI_Init(&argc, &argv);

MPI_Request sendRequest[2], recvRequest[2];
MPI_Status status[2];//osa kai auta pou perimenw apo to receive
MPI_Datatype row;

MPI_Type_vector(dimension, 1, dimension, MPI_FLOAT, &row);
MPI_Type_commit(&row);

if(retval != MPI_SUCCESS)
{
MPI_Abort(MPI_COMM_WORLD, retval);
return EXIT_FAILURE;
}
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
mat1 = malloc(dimension*sizeof(float));
mat2 = malloc(dimension*sizeof(float));
matrix = malloc(dimension*sizeof(float*));
mat = malloc(dimension*dimension*sizeof(float));

for(i=0; i<dimension; i++)
{
matrix[i] = mat + i*dimension;
}

printf("MATRIX OF RANK %d\n", rank);
for(i=0; i<dimension; i++)
{
for(j=0; j<dimension; j++)
{
matrix[i][j] = (float)(rank+1)*(i*2+j);
printf("%2.1f ",matrix[i][j]);
}
printf("\n");
}
printf("\n");

for(t=0; t<10; t++) //<----------------------PROBLEM WITH THIS LOOP
{
MPI_Isend(&(matrix[0][0]), 1, row, 1-rank, rank, MPI_COMM_WORLD, sendRequest + ONE);
MPI_Isend(&(matrix[0][0]), dimension, MPI_FLOAT, 1-rank, rank, MPI_COMM_WORLD, sendRequest + TWO);

MPI_Irecv(mat1,dimension, MPI_FLOAT, 1-rank, 1-rank, MPI_COMM_WORLD, recvRequest + ONE);
MPI_Irecv(mat2,dimension, MPI_FLOAT, 1-rank, 1-rank, MPI_COMM_WORLD, recvRequest + TWO);


for(i=0; i<2; i++)
{
MPI_Waitany(2,recvRequest, &processReceived, status);
printf("Process Received : %d of rank : %d\n", processReceived,rank);
if(processReceived == ONE)
{
printf("%d ",rank);
for(j=0; j<dimension; j++) printf("# %6.1f ",mat1[j]);
printf("\n");
}

if(processReceived == TWO)
{
printf("%d ",rank);
for(j=0; j<dimension; j++) printf("@ %6.1f ",mat2[j]);
printf("\n");
}
}

MPI_Waitall(2, sendRequest, status);
MPI_Type_free(&row);
}
free(mat1);
free(mat2);
free(mat);
free(matrix);

MPI_Finalize();
return 0;
}

我执行这个程序时没有带大箭头的循环 for(t=0; t<10; t++)一切都很好。当我使用循环时,它第一次运行良好,然后出现此错误消息:

Fatal error in PMPI_Isend: Invalid datatype, error stack: PMPI_Isend(149): MPI_Isend(buf=(nil), count=1, MPI_DATATYPE_NULL, dest=1, tag=0, MPI_COMM_WORLD, request=0xbf8764b8) failed PMPI_Isend(102): Datatype for argument datatype is a null datatype Fatal error in PMPI_Isend: Invalid datatype, error stack: PMPI_Isend(149): MPI_Isend(buf=(nil), count=1, MPI_DATATYPE_NULL, dest=0, tag=1, MPI_COMM_WORLD, request=0xbf8e8e18) failed PMPI_Isend(102): Datatype for argument datatype is a null datatype

我假设我有办法重新初始化我的发送、接收和状态。我的假设正确吗?如果是,我该如何解决?如果没有,你能看出什么问题吗?

这是整个程序,你可以自己执行

mpiexec -n 2 ./name_exe

它只运行 2 个进程!!!

最佳答案

在您的 for 循环中,您使用 MPI_Type_free(&row);,之后 row 不再是已注册的 MPI_Type,因此您的第一个 MPI_Isend 使用了无效的数据类型(如错误提示的那样)。将此行移到 for 循环之外。您还释放了 matrix,这意味着在第二次迭代中,您正在尝试发送您不再拥有的内存,这应该会产生段错误。

关于c - C中的MPI。在 I_send 和 Irecv 中使用循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34419906/

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