首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

MPI_Sendcount=零,但接收到64byte

2013-01-23 
MPI_Sendcount0,但接收到64byteif(rank0){while(apa+num) {printf(%f,*ap++)if((ap-a)%totalsize

MPI_Sendcount=0,但接收到64byte

if(rank==0){
        while(ap<a+num) {printf("%f  ",*ap++);if((ap-a)%totalsize==0) putchar('\n');}
        //printf("rank:%d\n",rank);
        MPI_Send(MPI_BOTTOM,0,MPI_BYTE,1,0,MPI_COMM_WORLD);
    }
    if(rank==1){
        MPI_Recv(MPI_BOTTOM,0,MPI_BYTE,0,0,MPI_COMM_WORLD,&status);
        while(ap<a+num) {printf("%f  ",*ap++);if((ap-a)%totalsize==0) putchar('\n');}
        //printf("rank:%d\n",rank);
        MPI_Send(MPI_BOTTOM,0,MPI_BYTE,2,1,MPI_COMM_WORLD);
    }

问题出在这一段,运行是报错如下
[cli_1]: aborting job:
Fatal error in MPI_Recv: Message truncated, error stack:
MPI_Recv(179).......................: MPI_Recv(buf=0x1e463180, count=0, MPI_BYTE, src=0, tag=0, MPI_COMM_WORLD, status=0x7fffa5244580) failed
MPIDI_CH3U_Request_unpack_uebuf(579): Message truncated; 64 bytes received but buffer size is 0
rank 1 in job 148  dell26_53858   caused collective abort of all ranks
  exit status of rank 1: return code 13 
按理说一个字节也没有发,但接收了64.而且确实如果用一个64字节的buffer接收(只改这一处),就没有问题。这是为什么呢?而且,问题只出在这一对上,程序里其它几乎完全一样的语句都没有问题(rank=3和=4的部分)。非常的困惑。

以下是完整的代码,用来算jacobi迭代的

#include <stdio.h>
#include <mpi.h>
#include <stdlib.h>
#define totalsize 16
#define mysize 4
#define steps 10

main(int argc, char **argv){
    float *a,*ap;
    int rank;
    int i,num=totalsize*mysize+totalsize;
    void calc(int x,float *a);
    void *buffer;
    MPI_Status status;

    MPI_Init(&argc,&argv);
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);

    if((a=(float *)calloc(totalsize+num,sizeof(float)))==NULL) {puts("malloc error!\n");exit(1);}
    if((buffer=malloc(1024))==NULL) {puts("malloc error!\n");exit(1);}

    calc( 8 , a );
    MPI_Barrier(MPI_COMM_WORLD);
    //if(rank==0) puts("calc ok");
    ap=a+totalsize;
    if(rank==0){
        while(ap<a+num) {printf("%f  ",*ap++);if((ap-a)%totalsize==0) putchar('\n');}
        //printf("rank:%d\n",rank);
        MPI_Send(MPI_BOTTOM,0,MPI_BYTE,1,0,MPI_COMM_WORLD);
    }
    if(rank==1){
        MPI_Recv(MPI_BOTTOM,0,MPI_BYTE,0,0,MPI_COMM_WORLD,&status);
        while(ap<a+num) {printf("%f  ",*ap++);if((ap-a)%totalsize==0) putchar('\n');}
        //printf("rank:%d\n",rank);
        MPI_Send(MPI_BOTTOM,0,MPI_BYTE,2,1,MPI_COMM_WORLD);
    }


    if(rank==2){
        MPI_Recv(MPI_BOTTOM,0,MPI_BYTE,1,1,MPI_COMM_WORLD,&status);
        while(ap<a+num) {printf("%f  ",*ap++);if((ap-a)%totalsize==0) putchar('\n');}
        //printf("rank:%d\n",rank);
        MPI_Send(MPI_BOTTOM,0,MPI_BYTE,3,2,MPI_COMM_WORLD);
    }
    if(rank==3){
        MPI_Recv(MPI_BOTTOM,0,MPI_BYTE,2,2,MPI_COMM_WORLD,&status);
        while(ap<a+num) {printf("%f  ",*ap++);if((ap-a)%totalsize==0) putchar('\n');}
        //printf("rank:%d\n",rank);
    }
    MPI_Finalize();
}

void calc(int x,float *a){
    int rank,size;
    int i,j,k,begin=1,end=mysize+1,num=totalsize*(mysize+2);
    float *b,*ap,*bp;
    MPI_Status status;

    MPI_Comm_rank(MPI_COMM_WORLD,&rank);

    if((b=calloc(num,sizeof(float)))==NULL) {puts("malloc error!\n");exit(1);}

    //initialize
    if(rank==0){
        ap=a+totalsize;
        bp=b+totalsize;
        while(ap<a+totalsize*2) {*ap++=x;*bp++=x;}
    }
    else if(rank==3){
        ap=a+totalsize*mysize;
        bp=b+totalsize*mysize;
        while(ap<a+totalsize*mysize+totalsize) {*ap++=x;*bp++=x;}
    }
    ap=a;
    bp=a+totalsize-1;
    while(ap<a+num){
        *ap=x,*bp=x;
        ap+=totalsize;
        bp+=totalsize;
    }
    ap=b;
    bp=b+totalsize-1;
    while(ap<b+num){
        *ap=x,*bp=x;
        ap+=totalsize;
        bp+=totalsize;
    }
    for(i=0;i<steps;i++){
        //syncronise
        if(rank==0) MPI_Send(a+num-2*totalsize,totalsize,MPI_FLOAT,1,0,MPI_COMM_WORLD);
        if(rank==3) MPI_Send(a+totalsize,totalsize,MPI_FLOAT,2,1,MPI_COMM_WORLD);
        else{
            MPI_Sendrecv(a+totalsize,totalsize,MPI_FLOAT,rank-1,2,a,totalsize,MPI_FLOAT,rank-1,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
            MPI_Sendrecv(a+num-2*totalsize,totalsize,MPI_FLOAT,rank+1,3,a+num-totalsize,totalsize,MPI_FLOAT,rank+1,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
        }

        MPI_Barrier(MPI_COMM_WORLD);

        //calc
        if(rank==0) begin=2;


        else if(rank==3) end=mysize;
        bp=b+1+totalsize*begin;
        while(bp<b+totalsize*end){
        //while(bp<b+totalsize*(begin+1)){
            ap=bp-b+a;
            *bp++=(*(ap-totalsize)+*(ap+totalsize)+*(ap-1)+*(ap+1))/4;
            if((bp-b+1)%totalsize==0) bp+=2;
        }
        ap=a,bp=b;
        while(ap<a+num) *ap++=*bp++;
    }
}


程序的其它部分都能正常运行。运行时使用4个线程。
编译貌似用的是impi 3.2.1.009 64位文件夹里的mpicc

BTW,MPI_Barrier有时候并不能把线程停下,有时候会出现有些线程越过barrier的情况,也一并问一下。

小弟新学mpi,而且本来C的基础也一般,所以,请多指教了。 MPI buffer
[解决办法]
88-92行。你synchronize的时候1和2是sendrecv,但是0和3只send不recv,导致1和2send过去的会被后面Barrier之后的recv接受。然后这边send >0 bytes,那边recv 0 bytes,爆了。
[解决办法]
特供将buf中字节写入日志文件使用:
void HexDump(char *buf,int len) {
    int i,j,k;
    char binstr[80];

    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%04x -",i);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            printf("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');


        }
        printf("%s\n",binstr);
    }
}

热点排行