0

考虑以下简单程序:

#include <mpi.h>                                                                                                                                                                                                                                 
#include <iostream>                                                                                                                                                                                                                              
#include <stdlib.h>                                                                                                                                                                                                                              
#include <stdio.h>                                                                                                                                                                                                                               
#include <string>                                                                                                                                                                                                                                
#include <vector>                                                                                                                                                                                                                                

using std::cout;                                                                                                                                                                                                                                 
using std::string;                                                                                                                                                                                                                               
using std::vector;                                                                                                                                                                                                                               

vector<float> test;                                                                                                                                                                                                                              
#ifdef GLOBAL                                                                                                                                                                                                                                    
string hostname;                                                                                                                                                                                                                                 
#endif                                                                                                                                                                                                                                           

int main(int argc, char** argv) {                                                                                                                                                                                                                
  int rank;  // The node id of this processor.                                                                                                                                                                                                   
  int size;  // The total number of nodes.                                                                                                                                                                                                       
#ifndef GLOBAL                                                                                                                                                                                                                                   
  string hostname;                                                                                                                                                                                                                               
#endif                                                                                                                                                                                                                                           
  MPI_Init(&argc, &argv);                                                                                                                                                                                                                        
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);                                                                                                                                                                                                          
  MPI_Comm_size(MPI_COMM_WORLD, &size);                                                                                                                                                                                                          

  cout << "Joining the job as processor: " << rank << std::endl;                                                                                                                                                                                 

  {                                                                                                                                                                                                                                              
    char buf[2048] = "HELLO";                                                                                                                                                                                                                    
    hostname.assign(buf, 2048);                                                                                                                                                                                                                  
  }                                                                                                                                                                                                                                              
  test.push_back(1.0f);                                                                                                                                                                                                                          

  cout << "Hostname: " << hostname << "::" << test[0] << std::endl;                                                                                                                                                                              

  MPI_Finalize();                                                                                                                                                                                                                                
  return 0;                                                                                                                                                                                                                                      
} 

如果我编译/运行它:

mpicxx -c test.cc && mpicxx -lstdc++ test.o -o test && ./test

没有分段错误,但如果我运行它:

mpicxx -DGLOBAL -c test.cc && mpicxx -lstdc++ test.o -o test && ./test

然后在 hostname.assign() 行出现分段错误。此外,如果我删除了这个赋值,一旦 main 方法返回,字符串析构函数就会出现分段错误,因此 assign 方法不是真正的罪魁祸首。

请注意,唯一的区别是声明“全局”变量主机名的位置。

我正在使用 MPICH2 版本 1.6 进行编译,并且由于我在超级计算机上运行它,因此我实际上无法更改它。

如果我删除 MPI_Init 等,错误就会消失,让我相信 MPI 和这个全局变量发生了一些意想不到的事情。

我在网上发现了其他一些发生在人们身上的例子,但他们都通过安装新版本的 MPICH 解决了他们的问题,这对我来说也是不可能的。

此外,我想知道为什么会发生这种情况,而不仅仅是一种解决方法。

谢谢你的时间。

4

1 回答 1

0

好的,经过大量调试后,我发现 MVAPICH2-1.6 库在以下位置定义了一个名为 hostname 的变量:

mpid/ch3/channels/mrail/src/rdma/ch3_shmem_coll.c

这是行(此版本的文件中为 55):

char hostname[SHMEM_COLL_HOSTNAME_LEN];

编译器没有抱怨这里的名称冲突,但这几乎可以肯定是罪魁祸首,因为在我的程序中更改变量名称消除了错误。我想这在 MVAPICH2 的更高版本中有所改变,但如果没有,我会提交错误。

于 2013-06-08T22:06:52.000 回答