【问题标题】:MPI_Bcast send stringMPI_Bcast 发送字符串
【发布时间】:2012-06-06 00:02:42
【问题描述】:

我遇到以下问题,我正在尝试发送 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 级的 GAMESSPATH 中,/usr/local/gamess/rungms1 排名 0,/usr/local/gamess/rungms

您是否注意到,在排名 1 的 GAMESS PATH 末尾,出现了数字 1, 但我找不到错误。

【问题讨论】:

    标签: c string mpi


    【解决方案1】:

    C 中的字符串以空字节结束。 strlen 返回不含空字节的字符串长度。因此,当您使用 MPI 发送字符串时,而不是在接收端终止空字节,最后会出现一些垃圾数据。

    一个简单的解决方法是将strlen 返回的值加1。如果长度值可能溢出,这确实有安全隐患。这在科学代码中可能不是问题,但需要注意。

    另外,为什么需要打包缓冲区?看起来这些字符串在连续存储中。您也不需要发送长度:只需告诉接收方接收最大缓冲区大小,并在发送方使用实际长度。

    【讨论】:

    • 我计算精确的pack_size以避免内存问题,因为程序在开始时分配了大量的内存,而打包数据的原因只是为了最小化级别之间的通信。编辑:只有 MASTER 等级知道 prog 和 gamesspath 的大小,然后我需要发送到其他等级
    • 你是对的,对于较大的消息,知道大小是有意义的。对于单个路径,您可以简单地调用长度为MAX_PATHMPI_Recv,以接收到该长度的消息。在发件人处,您将使用实际长度调用MPI_Send。接收方收到消息后,可以根据需要使用MPI_Get_count查找消息的实际长度。
    • 另外,MPI_Pack 引入了额外的内存副本。这会影响性能,除非绝对必要,否则最好避免。如果您的数据结构比简单数组更复杂,您可以尝试使用 MPI 数据类型来描述这些结构。
    猜你喜欢
    • 2013-10-14
    • 1970-01-01
    • 2017-01-07
    • 2014-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-22
    相关资源
    最近更新 更多