C中的MPI。在 I_send 和 Irecv 中使用循环
MPI in c. Using Loop in I_send and Irecv
我在 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 中有一个简单的 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
,这意味着在第二次迭代中,您正在尝试发送您不再拥有的内存,这应该会产生段错误。