简体   繁体   中英

MPI_Bcast send string

i'm having the following problem, i'm trying to send 2 types of data, 1 int, and 2 char, here part of my program

#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);

but i'm getting the following result

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

my problem is in GAMESSPATH in rank 1, /usr/local/gamess/rungms1 rank 0, /usr/local/gamess/rungms

as can you notice at the end of GAMESS PATH in rank 1, apperas the number 1, but i can't finde the error.

Strings in C are terminated with a null byte. strlen returns the length of the string without the null byte. So when you send the string using MPI, instead of the terminating null byte at the receiver there is some garbage data at the end.

A simple fix would be to add 1 to the value returned by strlen . This does have security implications though if the length value can overflow. This is probably not a concern in scientific code, but something to be aware of.

Also, why do you need to pack the buffers? It looks like these strings are in contiguous storage. You also don't really need to send the length: just tell the receiver to receive up to the maximum buffer size, and use the actual length at the sender.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM