登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

银河里的星星

落在人间

 
 
 

日志

 
 

open MPI MPI_Send recv 65536以上字节出错  

2010-04-09 21:30:23|  分类: 高性能计算 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
最近遇到一个超级难查的错误,一方面所因为程序所MPI并行程序,很难debug,基本没有啥可用的调试工具。其实之前用ubuntu编译完mpi程序后,执行即出现了错误,虽然没有解决,但我怀疑所环境问题。可能某些链接库的版本不对。
所以我用centos编译的open mpi是可以的,但是在将我的32位机与64位机并行时,在处理简单的程序时是没有问题的。
如下:
#include "mpi.h"
#include <stdio.h>
#include <math.h>
int main(int argc,char ** argv)
{
    int myid, numprocs;
    int  namelen;
    int type_size;
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    MPI_Init(&argc,&argv);
    MPI_Comm_rank(MPI_COMM_WORLD,&myid);
    MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
    MPI_Get_processor_name(processor_name,&namelen);
    fprintf(stderr,"Hello World! Process %d of %d on %s\n",myid, numprocs, processor_name);

    long send = -1;
    if(myid == 0) send = 0;
    MPI_Bcast ( &send, 1, MPI_LONG, 0, MPI_COMM_WORLD);
    printf("rank:%d %ld",myid,send);

    MPI_Finalize();
}
这个程序没有问题,虽然接受结果不对,这是因为32位机上long是32位,但是64机上的long则是64位。

当我再次运行一个网络测试程序时,却出现如下错误:
[client:20895] *** Process received signal ***
[client:20895] Signal: Segmentation fault (11)
[client:20895] Signal code: Address not mapped (1)
[client:20895] Failing at address: 0x300a15b58
[client:20895] [ 0] [0x554d40]
[client:20895] [ 1] [0x47e0e8]
[client:20895] [ 2] [0x4512b3]
[client:20895] [ 3] [0x5275eb]
[client:20895] [ 4] [0x520e08]
[client:20895] [ 5] [0x4aa365]
[client:20895] [ 6] [0x42f05b]
[client:20895] [ 7] [0x403b1e]
[client:20895] [ 8] [0x401cb4]
[client:20895] [ 9] [0x400310]
[client:20895] [10] [0x555e40]
[client:20895] [11] [0x4001b9]
[client:20895] *** End of error message ***
--------------------------------------------------------------------------
mpirun noticed that process rank 1 with PID 20895 on node client exited on signal 11 (Segmentation fault).
上面所采用-static编译后的运行错误提示。

那个网络测试程序其实很简单,就算测试节点间的网络传输延时及速率。从0字节开始测,然后是100000字节,200000,300000.........我们发现第一次测试可以正确完成。之后便失败。

于是怀疑与传输的字节大小有关,于是手工进行二分查找式的测试,从0->100000->50000->75000.......->65536,最后定位到16384个int也就是65536个字节。发现,16384之前大小的传送均是正确的,但是16385便开始出错了。

于是研究了这个16384,发现刚好是2的幂,这个发现让我很高兴,因为说明这个问题出现可能是有原因的。最后我怀疑这个值就是MPI_Send默认使用的系统缓存区的大小。当超过这个大小时,MPI_Send就down掉了。

虽然不确定更底层的原因。于是考虑采用另一种发送方式,MPI_Bsend,这样就可以利用我自己申请的缓存,而不受系统大小的限制了。经过实验发现可行。

同时为了验证这个猜想,将上面的简单程序,中发送的数据修改成65536byte,果然也down掉了。改成如下使用MPI_Bsend的形式,发现果然又可以了。

#include "mpi.h"
#include <stdio.h>
#include <math.h>
int main(int argc,char ** argv)
{
    int myid, numprocs;
    int  namelen;
    int type_size;
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    MPI_Comm comm = MPI_COMM_WORLD;
    MPI_Status status;

    MPI_Init(&argc,&argv);
    MPI_Comm_rank(MPI_COMM_WORLD,&myid);
    MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
    MPI_Get_processor_name(processor_name,&namelen);
    fprintf(stderr,"Hello World! Process %d of %d on %s\n",myid, numprocs, processor_name);

    MPI_Type_size(MPI_INT,&type_size);
    fprintf(stderr,"%s MPI_INT size:%d %d\n", processor_name,type_size,sizeof(int));
    MPI_Type_size(MPI_LONG,&type_size);
    fprintf(stderr,"%s MPI_LONG size:%d %d\n", processor_name,type_size,sizeof(long));
    MPI_Type_size(MPI_FLOAT,&type_size);
    fprintf(stderr,"%s MPI_FLOAT size:%d %d\n", processor_name,type_size,sizeof(float));
    MPI_Type_size(MPI_DOUBLE,&type_size);
    fprintf(stderr,"%s MPI_DOUBLE size:%d %d\n", processor_name,type_size,sizeof(double));
   
    int send = -1;

    int data_size = 8194,tag = 0;
    #define BUFFSIZE 1000000
    double *data_buffer = (double *)malloc(data_size*sizeof(double));   
    char *buffer = (char *)malloc(BUFFSIZE);
    int size;    

    MPI_Buffer_attach( buffer, BUFFSIZE);

    if(myid == 0)
        MPI_Bsend(data_buffer,data_size,MPI_DOUBLE,1,tag,comm);
    if(myid == 1)
        MPI_Recv(data_buffer,data_size,MPI_DOUBLE,0,tag,comm,&status);

    MPI_Buffer_detach(&buffer, &size);

    printf("rank:%d %d",myid,send);

    free(buffer);
    free(data_buffer);

    MPI_Finalize();
}

  评论这张
 
阅读(2475)| 评论(2)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018