在MPI中发送带有char[]的结构

Send struct with char[] in MPI

本文关键字:char 结构 MPI      更新时间:2023-10-16

我正试图将一些数据从工作程序发送到C++中MPI程序中的主程序(排名为0)。目标是传递2个字符串和一个整数。为此,我创建了一个结构。

结构

它被称为单词,定义如下:

struct word
{
    char word_name[str_size];
    char url[str_size];
    int counter;
};
/* Some important variables to the question */
MPI_Datatype mpi_word_type;
const int str_size = 200;

以前我通过char *尝试过,但它不起作用,因为进程不共享相同的内存空间。

到目前为止,如果我将变量从char[]更改为简单的char并尝试使用一个示例,我就可以发送结构了。如上所述,我无法消除分割错误错误。

发送零件-工人

我首先创建并填充一个示例结构,然后首先发送结构的大小,其次发送结构本身的大小。像这样:

word word_col;
std::string tmp = "somename";
strcpy(word_col.word_name, tmp.c_str());
std::string tmp2 = "someurl";
strcpy(word_col.url, tmp2.c_str());
word_col.counter = 10;
int size = sizeof(word_col);
MPI::COMM_WORLD.Send(&size, 1, MPI::INT, 0, 1);
MPI::COMM_WORLD.Send(&word_col, size, mpi_word_type, 0, 1);

接收部件-主

const int nitems = 3;
int blocklengths[3] = { str_size, str_size, 1 };
MPI_Datatype types[3] = { MPI::CHAR, MPI::CHAR, MPI::INT };
MPI_Aint offsets[3];
offsets[0] = (MPI_Aint) offsetof(struct word, word_name);
offsets[1] = (MPI_Aint) offsetof(struct word, url);
offsets[2] = (MPI_Aint) offsetof(struct word, counter);
MPI_Type_create_struct(nitems, blocklengths, offsets, types, &mpi_word_type);
MPI_Type_commit(&mpi_word_type);
...
for(...)
{
    word word_col;
    int size;
    MPI::COMM_WORLD.Recv(&size, 1, MPI::INT, MPI::ANY_TAG, 1, status);
    MPI::COMM_WORLD.Recv(&word_col, size, mpi_word_type, MPI::ANY_TAG, 1, status);
}

我已经为此挣扎了几个小时,我看到了很多关于这个的例子和其他问题,但我不知道这里的问题是什么。

这是错误的编程。您有未分配和未初始化的指针,您正试图将数据推送到该指针。您有两种选择:要么将您的结构定义为:

const int str_size = 200;
struct word
{
    char word_name[str_size]; // fixed sized char array
    char url[str_size]; // fixed sized char array
    int counter;
};

或者,

const int str_size = 200;
struct word
{
    char *word_name; /
    char *url;
    int counter;
    Word() {
      word_name = new char[str_size];
      url = new char[str_size];
    }
    ~Word() {
      delete [] word_name;
      delete [] url;
    }
};

其思想是,您需要为这些变量分配内存此外,在接收时,您使用了:

MPI::COMM_WORLD.Recv(&word_col, size, mpi_word_type, MPI::ANY_TAG, 1, status);

它不应该是下面的样子吗?

MPI::COMM_WORLD.Recv(&word_col, sizeof(word_col), mpi_word_type, MPI::ANY_TAG, 1, status);