【发布时间】:2017-07-09 08:44:46
【问题描述】:
我是 MPI 编程的新手。因此,我尝试使用 MPI_Scatter 将具有静态大小的 char* 数组分配到几个较小的 char* 数组块中。但结果只对 ID 0 正确,其余的都有垃圾值。你知道它有什么问题吗?
#include "mpi.h"
#include <algorithm>
#include <functional>
#include <cstdlib>
#include <ctime>
#include <cctype>
#include <fstream>
#include <vector>
#include <string>
#include <iostream>
const static int ARRAY_SIZE = 130000;
using Lines = char[ARRAY_SIZE][16];
// To remove punctuations
struct letter_only: std::ctype<char>
{
letter_only(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table()
{
static std::vector<std::ctype_base::mask>
rc(std::ctype<char>::table_size,std::ctype_base::space);
std::fill(&rc['A'], &rc['z'+1], std::ctype_base::alpha);
return &rc[0];
}
};
int main(int argc, char* argv[]) {
int processId;
int fillarraycount=0;
int num_processes;
// Setup MPI
MPI_Init( &argc, &argv );
MPI_Comm_rank( MPI_COMM_WORLD, &processId);
MPI_Comm_size( MPI_COMM_WORLD, &num_processes);
Lines lines;
// Read the input file and put words into char array(lines)
if (processId == 0) {
std::ifstream file;
file.imbue(std::locale(std::locale(), new letter_only()));
file.open(argv[1]);
std::string workString;
int i = 0;
while(file >> workString){
memset(lines[i], '\0', 16);
memcpy(lines[i++], workString.c_str(), workString.length());
fillarraycount++;
}
}
int n =fillarraycount/num_processes;
char sublines[n][16];
MPI_Scatter(lines,n*16,MPI_CHAR,sublines,n*16,MPI_CHAR,0,MPI_COMM_WORLD);
std::cout<< processId<<" ";
for(int i=0;i<n;++i)
std::cout<<sublines[i]<<" ";
std::cout<<std::endl;
MPI_Finalize();
return 0;
}
我知道在那之后我也必须使用 MPI_gather,但我很困惑为什么 ID 0 上的子线产生了正确的数组块,而其他 ID 产生了垃圾值。
我尝试编译和测试程序:
模块加载 openmpi
mpic++ -std=c++11 try.cpp -o try
mpirun -np 5 试试 try.txt
在 try.txt 中的位置:
你好,这是试用文本文档
这又是尝试文本文档
is is notis si is is is is ha ha
【问题讨论】:
-
这可能无济于事,我记得遇到过类似的问题并通过使用指针和
malloc而不是数组来修复它。 (char [x][y] -> char *sublines = malloc(sizeof(char)*x*y))。唯一突出的其他事情是确保在编译时定义num_processes(否则声明这样的数组是无效的,不可能知道要分配多少内存),最后的健全性检查:你做了分散, 您是否将结果收集回来?你必须scatter and gather ;)