【问题标题】:How to scatter an array of strings in MPI C++如何在 MPI C++ 中分散字符串数组
【发布时间】:2017-12-13 22:03:34
【问题描述】:

我想做的是对一些字符串运行基本的 MapReduce 操作。我想:

  1. 将字符串列表(平等地)分配给我的所有进程,
  2. 在进程中:将接收到的字符串映射到自定义类的对象(例如WordWithFrequency),
  3. 收集对象并将它们再次发送到进程以进行进一步操作。

这应该是一项简单的任务,但我找不到正确的方法。这是我损坏的代码:

#include <iostream>
#include <fstream>
#include <mpi.h>
#include <vector>

...

int main(int argc, char *argv[]) {
    // Initialize the MPI environment
    MPI_Init(&argc, &argv);

    // Find out the process rank and the world size
    int world_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
    int world_size;
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    vector<string> words = { "a", "bc", "d" };
    const int wordsLength = words.size();
    const int wordsPerProcess = wordsLength / world_size;

    string *subWords = new string[wordsPerProcess];
    MPI_Scatter(&words, wordsPerProcess, MPI_CHAR, subWords, wordsPerProcess, ???customDataType???, 0, MPI_COMM_WORLD);

    printf("Process %d got words:\n", world_rank);
    for (int i = 0; i < wordsPerProcess; ++i) {
        cout << subWords[i] << endl;
    }

    ...

输出是一些有趣的字母,从执行到执行:

Process 0 got words:
�R


Process 1 got words:

【问题讨论】:

  • 尝试使用std::vector 之类的东西,而不是new[]。由于内存管理问题大大减少,它会让您的生活显着更轻松。
  • @tadman 我认为(实际上,我确定)问题出在MPI_Scatter,而不是数组。我在这里做的事情完全错误,但我在互联网上找不到任何字符串散射的例子。附言。 std::vector 没有帮助。
  • 在这种特殊情况下,它不会神奇地解决您的所有问题,但从长远来看,它会很有用,因为您不会浪费时间跟踪内存泄漏。
  • stackoverflow.com/questions/47747287/… 的可能重复项 长话短说,MPI_Scatter() 不适用于指针数组。如果你真的想使用MPI_Scatter(),你应该使用char 的二维数组(例如,一个固定长度的“字符串”数组)
  • 我通过使用 Boost.MPI 解决了我的问题,它可以分散字符串向量而无需任何额外工作。它还使得序列化自定义对象变得超级容易。感谢您的帮助!

标签: c++ mpi


【解决方案1】:

使用 Boost.MPI 非常容易:

#include <boost/mpi.hpp>
...

int main(int argc, char *argv[]) {
    // Initialize the MPI environment.
    mpi::environment env(argc, argv);
    mpi::communicator world;

    vector<string> words = { "foo", "bar", "baz", "..." };
    const int wordCount = words.size();
    const int wordsPerProcess = wordCount / world.size();
    vector<vector<string> > wordsByProcess(world.size(), vector<string>());
    for (int j = 0; j < world.size(); ++j) {
        for (int k = 0, wordIndex = j * wordsPerProcess + k;
             k < wordsPerProcess && wordIndex < wordCount; ++k, ++wordIndex) {
            wordsByProcess[j].push_back(words[wordIndex]);
        }
    }

    vector<string> subWords;
    mpi::scatter(world, wordsByProcess, subWords, 0);
    // subWords is equal to wordsByProcess[world.rank()] here in every process.

Scatter 采用元素向量,该向量由将发送相应值的进程号索引。更多详情请见:http://www.boost.org/doc/libs/1_41_0/doc/html/boost/mpi/scatter.html

【讨论】:

    猜你喜欢
    • 2013-11-13
    • 2014-06-23
    • 2018-12-30
    • 2013-04-23
    • 2016-09-16
    • 2020-08-09
    • 2018-05-20
    • 2017-10-12
    • 1970-01-01
    相关资源
    最近更新 更多