我在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++)
的循环,一切都很好。当我使用循环时,它第一次运行良好,然后出现此错误消息:
PMPI_Isend中的致命错误:无效的数据类型,错误堆栈: PMPI_Isend(149):MPI_Isend(buf =(nil),count = 1,MPI_DATATYPE_NULL, dest = 1,tag = 0,MPI_COMM_WORLD,request = 0xbf8764b8)失败 PMPI_Isend(102):参数数据类型的数据类型是null数据类型 PMPI_Isend中的致命错误:无效的数据类型,错误堆栈: PMPI_Isend(149):MPI_Isend(buf =(nil),count = 1,MPI_DATATYPE_NULL, dest = 0,tag = 1,MPI_COMM_WORLD,request = 0xbf8e8e18)失败 PMPI_Isend(102):参数数据类型的数据类型为空数据类型
我认为我已经以某种方式重新初始化我的发送,recvs和状态。我的假设是否正确?如果是,我该如何解决?如果不是,你能看到任何问题吗?
这是整个程序,所以你可以自己执行它
mpiexec -n 2 ./name_exe
它仅运行2个进程!!!
答案 0 :(得分:2)
在for
循环中,您使用MPI_Type_free(&row);
,之后row
不再是已注册的MPI_Type
,因此您的第一个MPI_Isend
使用无效数据类型(如错误所示)。将此行移至for
循环之外。您还可以释放matrix
,这意味着在第二次迭代中,您正在尝试发送您不再拥有的内存,这会产生一个seg-fault。