C++ MPI 广播向量

4

我有一个MPI库的问题。

我需要从文件中读取文本,并将其发送到其他进程,例如作为向量。

我编写了以下代码:

#include "mpi.h"
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include<string>
#include <fstream>
#include <cstring>
#include <vector>
class PatternAndText
{
public:
    static std::string textPreparaation()
    {
        std::ifstream t("file.txt");
        std::string str((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
        std::string text = str;
        return text;
    }

};

int main(int argc, char* argv[])
{
   int size, rank ;
   std::string text;
   std::vector<char> cstr;

    MPI_Init(&argc, &argv);
    MPI_Status status;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    if (rank == 0)
    {
      text = PatternAndText::textPreparaation();
      std::vector<char> cstr(text.c_str(), text.c_str() + text.size() + 1);   
   }

   MPI_Bcast(cstr.data(), cstr.size(), MPI_CHAR,0,MPI_COMM_WORLD);

    if (rank  != 0 )
   {
      std::cout<<"\n";
      std::cout<<cstr[1]<<" "<<rank;
      std::cout<<"\n";
   }

        MPI_Finalize();
        return 0; 
}

我希望能够通过主进程读取文件中的文本并将其广播给其他人。

当我尝试运行时,它会提示:


[alek:26408] *** Process received signal ***
[alek:26408] Signal: Segmentation fault (11)
[alek:26408] Signal code: Address not mapped (1)
[alek:26408] Failing at address: 0x1
[alek:26408] [ 0] /lib/x86_64-linux-gnu/libc.so.6(+0x3ef20)[0x7fc7c1a8af20]
[alek:26408] [ 1] spli(+0xc63d)[0x55b0104bb63d]
[alek:26408] [ 2] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x7fc7c1a6db97]
[alek:26408] [ 3] spli(+0xc3ba)[0x55b0104bb3ba]
[alek:26408] *** End of error message ***

[alek:26406] *** Process received signal ***
[alek:26406] Signal: Segmentation fault (11)
[alek:26406] Signal code: Address not mapped (1)
[alek:26406] Failing at address: 0x1
[alek:26406] [ 0] /lib/x86_64-linux-gnu/libc.so.6(+0x3ef20)[0x7f01ef5f5f20]
[alek:26406] [ 1] spli(+0xc63d)[0x5579714df63d]
[alek:26406] [ 2] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x7f01ef5d8b97]
[alek:26406] [ 3] spli(+0xc3ba)[0x5579714df3ba]
[alek:26406] *** End of error message ***

[alek:26414] *** Process received signal ***
[alek:26414] Signal: Segmentation fault (11)
[alek:26414] Signal code: Address not mapped (1)
[alek:26414] Failing at address: 0x1



[alek:26413] *** Process received signal ***

[alek:26422] *** Process received signal ***
[alek:26417] *** Process received signal ***
[alek:26417] Signal: Segmentation fault (11)
[alek:26417] Signal code: Address not mapped (1)
[alek:26417] Failing at address: 0x1
[alek:26413] Signal: Segmentation fault (11)
[alek:26413] Signal code: Address not mapped (1)
[alek:26413] Failing at address: 0x1
[alek:26422] Signal: Segmentation fault (11)
[alek:26422] Signal code: Address not mapped (1)
[alek:26422] Failing at address: 0x1
[alek:26413] [alek:26425] *** Process received signal ***
[alek:26425] Signal: Segmentation fault (11)
[alek:26425] Signal code: Address not mapped (1)
[alek:26425] Failing at address: 0x1
[alek:26414] [ 0] [alek:26422] [ 0] /lib/x86_64-linux-gnu/libc.so.6(+0x3ef20)[0x7ff9c3740f20]
[alek:26414] [ 1] spli(+0xc63d)[0x563e8a58563d]
[alek:26417] [ 0] [alek:26425] [ 0] [ 0] [alek:26414] [ 2] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7/lib/x86_64-linux-gnu/libc.so.6/lib/x86_64-linux-gnu/libc.so.6(+0x3ef20)[0x7f5a4dd75f20]
[alek:26417] /lib/x86_64-linux-gnu/libc.so.6(/lib/x86_64-linux-gnu/libc.so.6(+0x3ef20)[0x7f90009f0f20]
[alek:26425] [ 1] spli(+0xc63d))[0x7ff9c3723b97]
[alek:26414] [ 3] spli+0x3ef20)[0x7f2a6faf6f20]
[alek:26413] [ 1] spli(+0xc63d)[0x5557de07763d]
[0x557dee98063d]
[alek:26425] [ 2] (+0xc3ba)[0x563e8a5853ba]
[alek:26414] *** End of error message ***
(+0x3ef20)[0x7f8c41861f20]
[alek:26422] [ 1] spli(+0xc63d)[ 1] spli(+0xc63d)[0x5650e93dc63d]
[alek:26417] [alek:26413] [ 2] [0x561eb2de463d]
[alek:26422] [ 2] [ 2] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x7f2a6fad9b97]
[alek:26413] [ 3] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x7f5a4dd58b97]
[alek:26417] [ 3] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x7f8c41844b97]
[alek:26422] [ 3] spli(+0xc3ba)[0x5557de0773ba]
[alek:26413] *** End of error message ***
spli(+0xc3ba)[0x5650e93dc3ba]
[alek:26417] *** End of error message ***
spli(+0xc3ba)[0x561eb2de43ba]
[alek:26422] *** End of error message ***
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x7f90009d3b97]
[alek:26425] [ 3] spli(+0xc3ba)[0x557dee9803ba]
[alek:26425] *** End of error message ***

[alek:26411] *** Process received signal ***
[alek:26411] Signal: Segmentation fault (11)
[alek:26411] Signal code: Address not mapped (1)
[alek:26411] Failing at address: 0x1
[alek:26411] [ 0] /lib/x86_64-linux-gnu/libc.so.6(+0x3ef20)[0x7f1a339adf20]
[alek:26411] [ 1] spli(+0xc63d)[0x555737c1263d]
[alek:26411] [ 2] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x7f1a33990b97]
[alek:26411] [ 3] spli(+0xc3ba)[0x555737c123ba]
[alek:26411] *** End of error message ***
[warn] Epoll ADD(4) on fd 88 failed.  Old events were 0; read change was 0 (none); write change was 1 (add): Bad file descriptor
--------------------------------------------------------------------------
mpirun noticed that process rank 5 with PID 0 on node alek exited on signal 11 (Segmentation fault).
--------------------------------------------------------------------------

当我检查大小时,代替[0]的进程会输出0。我应该改变什么来使它正常工作?

1个回答

5
  1. The local variable std::vector<char> cstr inside if (rank == 0) {...} shadows that inside main. The variable cstr inside main is not affected.

    To assign data to cstr, use cstr.assign(...):

    if (rank == 0) {
        const std::string text = PatternAndText::textPreparaation();
        cstr.assign(text.c_str(), text.c_str() + text.size() + 1);
    }
    
  2. Other processes should first allocate storage in cstr by calling cstr.resize(...). To do that they should know its size. You can first broadcast size and then resize cstr:

    unsigned long long size = cstr.size();
    MPI_Bcast(&size, 1, MPI_UNSIGNED_LONG_LONG, 0, MPI_COMM_WORLD);
    if (rank != 0)
        cstr.resize(size);
    

    before broadcasting the vector itself:

    MPI_Bcast(cstr.data(), size, MPI_CHAR, 0, MPI_COMM_WORLD);
    

1
它给了我比我预期的更多的解释,谢谢,现在它可以工作了。 - alekq

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接