1

大学の演習中に、変数の奇妙な動作に遭遇しました。

/* Main parameters                                                          */
double sizeX, sizeY;      /* Size of the global domain                      */
int nPartX, nPartY;       /* Particle number in x, y direction              */
int nPart;                /* Total number of particles                      */
int nCellX, nCellY;       /* (Global) number of cells in x, y direction     */
int steps;                /* Number of timesteps                            */
double dt;                /* Stepsize for timesteps                         */
int logs;                 /* Whether or not we want to keep logfiles        */

void ReadInput(const char *fname)
{
  FILE *fp;
  char c;

  Debug("ReadInput", 0);
  if(rank == 0)
  {
    fp = fopen(fname, "r");
    if(!fp) Debug("Cannot open input file", 1);
    if(fscanf(fp, "sizeX: %lf\n", &sizeX) != 1) Debug("sizeX?",  1);
    if(fscanf(fp, "sizeY: %lf\n", &sizeY) != 1) Debug("sizeY?",  1);
    if(fscanf(fp, "nPartX:%i\n", &nPartX) != 1) Debug("nPartX?", 1);
    if(fscanf(fp, "nPartY:%i\n", &nPartY) != 1) Debug("nPartY?", 1);
    if(fscanf(fp, "nCellX:%i\n", &nCellX) != 1) Debug("nCellX?", 1); //read value is 10
    if(fscanf(fp, "nCellY:%i\n", &nCellY) != 1) Debug("nCellY?", 1);    
    if(fscanf(fp, "steps: %li\n", &steps) != 1) Debug("steps?",  1);    
//here the nCellX variable value 10 is changed somehow to 0
    if(fscanf(fp, "dt:    %lf\n", &dt)    != 1) Debug("dt?",     1);
    if(fscanf(fp, "logs:  %c\n",  &c)     != 1) Debug("logs?",   1);
    logs = (c == 'y');
    fclose(fp);
  }

  printf("(%i) reporting in...\n", rank);

  MPI_Bcast(&sizeX, 1, MPI_DOUBLE, 0, grid_comm);  
  MPI_Bcast(&sizeY, 1, MPI_DOUBLE, 0, grid_comm);
  MPI_Bcast(&nPartX,1, MPI_INT,    0, grid_comm);  
  MPI_Bcast(&nPartY,1, MPI_INT,    0, grid_comm);
  MPI_Bcast(&nCellX,1, MPI_INT,    0, grid_comm);
  MPI_Bcast(&nCellY,1, MPI_INT,    0, grid_comm);
  MPI_Bcast(&steps, 1, MPI_INT,    0, grid_comm);
  MPI_Bcast(&dt,    1, MPI_DOUBLE, 0, grid_comm);
  MPI_Bcast(&logs,  1, MPI_INT,    0, grid_comm);
  nPart = nPartX * nPartY;
  dt2 = dt * dt;
}

先生と私は、変数名を「nCellX」から「nCellX_2」に変更すると、問題がなくなり、コードが期待どおりに動作するという結論に達しました。もう 1 つの興味深い点は、この問題が発生するのはこの 1 つのグローバル変数だけで、他の変数は正しく機能することです。この種の問題に遭遇した人もいるのだろうかと思っていました。ガイドライン/説明をいただければ幸いです。

この問題が十分に明確でない場合はお知らせください。また、完全なコードが必要な場合は、それも提供できます。一般に、コードは Particle-in-Cell の並列アルゴリズムです。

4

2 に答える 2

5

次のコード行が問題を引き起こしている可能性があります。

if(fscanf(fp, "steps: %li\n", &steps) != 1) Debug("steps?",  1);

%li長整数を示します。これは64ビットの場合stepsがありint、はは32ビットの場合があります。フォーマット指定子は、%iの代わりに使用する必要があり%liます。

実際に問題があるかどうかは、環境によって異なります(たとえば、64ビットアプリケーションを構築する場合に問題になる可能性があります)。64ビットと32ビットの不一致がある場合、呼び出しはメモリを上書きし、メモリレイアウトでfscanf続く変数を破壊する可能性があります(それは可能性があります)。オプションを使用すると、この状況について警告する必要があることに注意してください。nCellXの名前を別の名前に変更すると問題が隠される理由は明らかではありませんが、名前を変更するとメモリ内の変数のレイアウトが変更される可能性があるようです。私はそれがC標準によって許可されていないことを疑っています(私は見ていませんが)。stepsnCellX-Wall

于 2012-03-23T13:46:55.883 に答える