1

私は次の問題を抱えています、私は2種類のデータ、1つのintと2つのcharを送信しようとしています、ここでは私のプログラムの一部です

#define Send(send_data, count, type, dest, tag) MPI_Send(send_data, count, type, dest, tag, GROUP)
#define Recv(recv_data, count, type, source, tag) MPI_Recv(recv_data, count, type, source, tag, GROUP, &status)
#define Recv(recv_data, count, type, source, tag) MPI_Recv(recv_data, count, type, source, tag, GROUP, &status)
#define Pack(data_in, count_in, type, data_out, count_out, pos) MPI_Pack(data_in, count_in, type, data_out, count_out, pos, GROUP)
#define Unpack(data_out, count_out, pos, data_in, count_in, type) MPI_Unpack(data_out, count_out, pos, data_in, count_in, type, GROUP)
#define Pack_size(count, type, size) MPI_Pack_size(count, type, GROUP, size)
#define MASTER 0


if( rank == 0 ){

    k1 = strlen(prog);
    k2 = strlen(gamesspath);

    for( i = 1; i < proc; i++ ){
      Send(&k1, 1, INT, i, 1);
      Send(&k2, 1, INT, i, 2);
    }
  }
  else{
    Recv(&k1, 1, INT, MASTER, 1);
    Recv(&k2, 1, INT, MASTER, 2);

    gamesspath = malloc( k2 * sizeof(char));
  }

  Pack_size(k1, CHAR, &size1);
  Pack_size(k2, CHAR, &size2);
  Pack_size(1, INT, &size3);

  buffer_size = size1 + size2 + size3;

  buffer = malloc( buffer_size * sizeof(char));

  if( rank == MASTER ){
    pos = 0;

    Pack(prog, k1, CHAR, buffer, buffer_size, &pos);
    Pack(gamesspath, k2, CHAR, buffer, buffer_size, &pos);
    Pack(&nindiv, 1, INT, buffer, buffer_size, &pos);
  }

  Bcast(buffer, buffer_size, PACKED);

  if( rank != MASTER ){
    pos = 0;

    Unpack(buffer, buffer_size, &pos, prog, k1, CHAR);
    Unpack(buffer, buffer_size, &pos, gamesspath, k2, CHAR);
    Unpack(buffer, buffer_size, &pos, &nindiv, 1, INT);
  }

  /*FIM DO ENVIO*/

  printf("PROG = %s, GAMESSPATH = %s, NINDIV = %d - rank %d\n", prog, gamesspath, nindiv, rank);

しかし、私は次の結果を得ています

PROG = GAMESS, GAMESSPATH = /usr/local/gamess/rungms1, NINDIV = 10 - rank 1
PROG = GAMESS, GAMESSPATH = /usr/local/gamess/rungms, NINDIV = 10 - rank 0

私の問題は、ランク1、/ usr / local / gamess / rungms1ランク0、/ usr / local / gamess/rungmsのGAMESSPATHにあります。

ランク1のGAMESSPATHの最後にあるように、番号1を表示しますが、エラーを見つけることができません。

4

1 に答える 1

1

C の文字列は null バイトで終了します。 strlennull バイトを除いた文字列の長さを返します。そのため、MPI を使用して文字列を送信すると、受信側で終端のヌル バイトの代わりに、最後にガベージ データがいくつかあります。

簡単な修正は、 によって返される値に 1 を追加することstrlenです。長さの値がオーバーフローする可能性がある場合でも、これにはセキュリティ上の影響があります。これはおそらく科学的なコードでは問題ではありませんが、注意が必要です。

また、なぜバッファをパックする必要があるのですか? これらの文字列は連続したストレージにあるようです。また、実際に長さを送信する必要はありません。受信者に最大バッファサイズまで受信するように指示し、送信者で実際の長さを使用するだけです。

于 2012-05-31T18:40:09.193 に答える