2017-02-20 2 views
0

Ich bin neu in MPI-Programmierung. Also versuche ich MPI_Scatter zu verwenden, um ein Array von char *, das eine statische Größe hat, in mehrere kleinere Blöcke von char * zu verteilen. Aber das Ergebnis ist nur für die ID 0 korrekt und der Rest hat einen Müllwert. Weißt du, was damit nicht stimmt?Verwendung von MPI_Scatter mit char * Array

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

Ich weiß, ich habe MPI_gather danach zu verwenden, aber ich bin verwirrt, warum die Subleitungen auf ID 0 die richtigen Brocken des Arrays hergestellt, aber die andere IDs Müll Wert erzeugt.

ich versuchte, Kompilieren und Testen des Programms mit:
Modullast openmpi
MPIC -std ++ = C++ 11 try.cpp -o versuchen
mpirun -NP 5 Versuchen try.txt

wo in try.txt:
hallo das ist der Versuch Textdokument
wieder das ist der Versuch Textdokument
ist, notis si wird ist ha ha

+0

Dies wird wahrscheinlich nicht helfen, ich erinnere mich, in ein ähnliches Problem zu laufen und reparierte es mit Hilfe von Zeigern und 'malloc' anstelle von Arrays. ('char [x] [y] -> char * Unterzeilen = malloc (sizeof (char) * x * y)'). Die einzigen anderen Dinge, die herausragen, sind, dass 'num_processes' zur Kompilierzeit definiert ist (sonst ist es nicht möglich das Array zu deklarieren, es ist nicht möglich zu wissen wie viel Speicher zuzuordnen ist) und die letzte Plausibilitätsprüfung: Sie haben die Streuung gemacht , ** hast du deine Ergebnisse zurück ** gesammelt? Sie müssen [streuen und sammeln] (http://mpitutorial.com/tutorials/mpi-scatter-gather-and-allgather/);) – sjm324

+1

Bitte geben Sie eine [mcve]. – Zulan

Antwort

0

auf den Rängen andere als 0, n ist 0, weil fillarraycount niemals inkrementiert wird. Wenn fillarraycount dynamisch ist, müssen Sie zuerst an alle Ränge senden.

+0

danke für die Antwort! Kannst du etwas mehr erklären, ich möchte das Problem wirklich vollständig verstehen .. danke! –

+0

ah ich habe es. Danke für die Hilfe!! –