MPI在c。在I_send和Irecv

时间:2015-12-22 16:06:32

标签: c mpi

我在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个进程!!!

1 个答案:

答案 0 :(得分:2)

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