2012年1月29日星期日

MPI_Send 超过65535字节 会默默像死锁一样的死去

zz:http://duanple.blog.163.com/blog/static/709717672010399302350/

最近遇到一个超级难查的错误,一方面所因为程序所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 co
de: 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();
}




2011年12月9日星期五

zz 关于g++ memcpy’ was not declared in this scope解决方法

使用如下2行即可
#include<iostream>
#include <cstring>
地址:http://blog.chinaunix.net/u1/38994/showart_2187440.html

2011年12月3日星期六

vs2008 c++ 程序运行 命令行窗口瞬间消失

ctrl+f5

zz:win7+CUDA4.0+VS2008

原文:http://blog.csdn.net/asz9255/article/details/6375281  

准备好cuda4.0 64位toolkit,sdk,驱动。注意在安装vs2008时,一定要选择安装64位编译器。如果已经安装了,可在进入维护界面,升级,在VC++里,勾上64编译器。
    安装好toolkit,sdk后,跟CUDA3.2一样设置环境变量,我的电脑-》属性-》高级-》环境变量:在系统变量Path的值中加入,……\NVIDIA GPU Computing SDK 3.2\C\bin\win32\Debug和……\NVIDIA GPU Computing SDK 3.2\C\bin\win32\Release(SDK安装路径)。
    大功告成,注销系统,打开VS2008,可以新建CUDA项目了。


编译一个例子,不出意外的话,会报错缺少cutil64。因为CUDA4.0不在包括cutil32和和cutil64,所以我们得人工编译生成。
    在......SDK/C/Common中,打开vs2008工程,在32位和64位下,分别在debug和release下重新编译工程,生成的lib在......SDK/C/Common/lib中。
   打开VS,在Tool –> Options –> Projects and Solutions –> VC++ Directories 添加刚才生成的两个lib文件。
   就是这样!!!

    Tool->Options->Projects and Solutions->VC++ Directories

 Include files中添加路径(最后):
    ....../NVIDIA Corporation/NVIDIA CUDA SDK/common/inc
   ....../NVIDIA Corporation/NVIDIA GPU Computing SDK 4.0/shared/inc

 Library files中添加路径(最后):
  ....../NVIDIA Corporation/NVIDIA CUDA SDK/common/lib
  ....../NVIDIA Corporation/NVIDIA GPU Computing SDK 4.0/shared/lib

 Source files中添加路径(最后):
    ....../NVIDIA Corporation/NVIDIA CUDA SDK/common/src  
   ....../NVIDIA Corporation/NVIDIA GPU Computing SDK 4.0/shared/src


 模板:

CUDA VS Wizard,下载地址:http://sourceforge.net/projects/cudavswizard/files/,有32位和64位两个版本,选择和自己操作系统对应的版本即可,下载后安装

高亮:
F:\。。。\NVIDIA GPU Computing SDK 4.0\C\doc\syntax_highlighting\visual_studio_8

1. If you don't have a usertype.dat file in your "Microsoft Visual Studio 8\Common7\IDE" folder, then copy the included usertype.dat file there.  If you do, append the contents of the included usertype.dat onto the end of the "Microsoft Visual Studio 8\Common7\IDE\usertype.dat"

2. Start Visual Studio 8.  Select the menu "Tools->Options...".  Open "Text Editor" in the tree view on the left, and click on "File Extension".  Type cu in the "Extension" box, set the editor to "Microsoft Visual C++" and click "Add".  Click "OK" on the dialog box. 

3. Restart Visual Studio and your CUDA code should now have syntax highlighting.






无法打开sdk例子的解决办法:
It appears that the CUDA SDK 4.0 Installer may be removing the NvCudaRuntimeApi.rules and CUDA rules files located in the Visual Studio Directory. Someone at NVIDIA will be investigating in detail what exactly is happening during SDK installation. There is a copy of the the *.rules files installed in the CUDA toolkit directory. You can copy the *.rules files from:

C:\Program Files\NVIDIA Corporation\NVIDIA GPU Computing Toolkit\CUDA\r4.0\extras\visual_studio_integration\ rules\*.rules

to

${Your Visual Studio Location}\VC\VCProjectDefaults\

2011年12月2日星期五

MPICH2 + Netbeans

My computer is 64 bit but the linker of Netbeans 7 does not work with mpich2-1.4.1p1-win-x86-64.msi but works with mpich2-1.4.1p1-win-ia32.msi

打开wmpiregister.exe
注册当前用户名 和 密码

用管理员权限打开cmd   
smpd -install





The steps to compile it:
  • File / New Project … / C/C++ Aplication, name it and go with defaults
  • Replace content of main.cpp with the code above.
  • Rightclick on project name on the left, select Properties:
  1. Categories / Build / C++ Compiler -> Include directories add value C:/Program Files (x86)/MPICH2/include
  2. Categories / Build / Linker -> Additional Library Directories add C:/Program Files (x86)/MPICH2/lib
  3. Categories / Build / Linker -> Libraries click “Add Option” and select “Static Bindings” (will add flag -static to the linker)
  4. Categories / Build / Linker -> Add Library ... and select one by one, all .lib files from C:/Program Files (x86)/MPICH2/lib

2011年11月7日星期一

zz eclipse运行C++控制台不输出结果的解决办法

解决方法:

Run Configurations -> Environment

Name
: PATH
Value : C:\MinGW\bin

在运行设置中增加 Path=C:\MinGW\bin
eclipse运行C++控制台不输出结果的解决办法

eclipse运行C++控制台不输出结果的解决办法