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() 行にセグメンテーション違反があります。さらに、この割り当てを削除すると、メイン メソッドが戻ると文字列デストラクタにセグメンテーション違反が発生するため、割り当てメソッドが実際の原因ではありません。

唯一の違いは、「グローバル」変数のホスト名が宣言される場所であることに注意してください。

私は MPICH2 バージョン 1.6 でコンパイルしていますが、これをスーパーコンピューターで実行しているため、これを変更するオプションは実際にはありません。

MPI_Init などを削除すると、エラーがなくなり、MPI とこのグローバル変数で予期しないことが起こっていると思います。

オンラインでこれが起こっている他の例をいくつか見つけましたが、MPICH の新しいバージョンをインストールすることですべての問題を解決しました。

さらに、単なる回避策ではなく、なぜこれが起こっているのかを知りたいです。

御時間ありがとうございます。

4

1 に答える 1

0

OK、かなりのデバッグを行った後、MVAPICH2-1.6 ライブラリでホスト名という変数が次の場所で定義されていることがわかりました。

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

行は次のとおりです (このバージョンのファイルでは 55)。

char hostname[SHMEM_COLL_HOSTNAME_LEN];

コンパイラはここで名前の衝突について文句を言いませんでしたが、私のプログラムで変数名を変更するとエラーが解消されたので、これが原因であることはほぼ間違いありません。これは MVAPICH2 の以降のバージョンで変更されると思いますが、そうでない場合はバグを報告します。

于 2013-06-08T22:06:52.000 に答える