C - MPI текстовый файл открыт - PullRequest
0 голосов
/ 05 июня 2018

Привет, ребята, я учусь программировать в MPI, и я столкнулся с этим вопросом.Допустим, у меня есть файл .txt с 3 000 000 строк / строк с текстом (это словарь), так что это будет строка массива, как я могу разделить их на части для обработки 4 процессорами?т.е. я хочу, чтобы процессор 0 позаботился об обработке строк 1-750 000, процессор 1 позаботился о 750 001-1 500 000 и так далее.Затем каждый процесс берет часть данных и помещает в функцию, например, find_some_word.

Теперь я получаю это, но я не знаю, как получить одно слово для ранга из моего куска.Эта часть прокомментирована в программе, как это сделать

#include <stdio.h>
#include <mpi.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#include <conio.h>

bool if_anagram(char *a, char *b)
{

    int dl1 = strlen(a), dl2 = strlen(b);


    if(dl1!=dl2) return false;
    if(strcmp(a,b) == 0) return false;

    int licz[0x100]={}; 

    for(int i=0;i<dl1;i++)    
        licz[(unsigned char) a[i]]++; 
    for(int i=0;i<dl1;i++)
        licz[(unsigned char) b[i]]--;       
    for(int i=0;i<256;i++)      
        if(licz[i]!=0) 
            return false; 

  return true; 
} 

void parprocess(MPI_File *in, char *a, const int rank, const int size, const int overlap) {

    MPI_Offset globalstart;
    int mysize;
    char *chunk;

    /* read in relevant chunk of file into "chunk",
     * which starts at location in the file globalstart
     * and has size mysize 
     */
    {
        MPI_Offset globalend;
        MPI_Offset filesize;

        /* figure out who reads what */
        MPI_File_get_size(*in, &filesize);
        filesize--;  /* get rid of text file eof */
        mysize = filesize/size;
        globalstart = rank * mysize;
        globalend   = globalstart + mysize - 1;
        if (rank == size-1) globalend = filesize-1;

        /* add overlap to the end of everyone's chunk except last proc... */
        if (rank != size-1)
            globalend += overlap;

        mysize =  globalend - globalstart + 1;

        /* allocate memory */
        chunk = malloc( (mysize + 1)*sizeof(char));

        /* everyone reads in their part */
        MPI_File_read_at_all(*in, globalstart, chunk, mysize, MPI_CHAR, MPI_STATUS_IGNORE);
        chunk[mysize] = '\0';
    }


    /*
     * everyone calculate what their start and end *really* are by going 
     * from the first newline after start to the first newline after the
     * overlap region starts (eg, after end - overlap + 1)
     */

    int locstart=0, locend=mysize-1;
    if (rank != 0) {
        while(chunk[locstart] != '\n') locstart++;
        locstart++;
    }
    if (rank != size-1) {
        locend-=overlap;
        while(chunk[locend] != '\n') locend++;
    }
    mysize = locend-locstart+1;

    /* "Process" our chunk by replacing non-space characters with '1' for
     * rank 1, '2' for rank 2, etc... 
     */

    char b[101];
    for (int i=locstart; i<=locend; i++) {
                                                // THIS PART
        //fscanf (chunk,"%s",b);                // how get a single word from chunk
        //if(if_anagram(a,b)){
            //printf("Word %s is anagram!\n", b);

    //  It is orginal part  
    //    char c = chunk[i];
     //   chunk[i] = ( isspace(c) ? c : '1' + (char)rank );
    //    printf("Wyraz %d\n", rank);
        }
    //}

}

int main(int argc, char **argv) {

    MPI_File in;
    int rank, size;
    int ierr;
    const int overlap = 100;
    char a[101];


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

    if (argc != 2) {
        if (rank == 0) fprintf(stderr, "Usage: %s infilename\n", argv[0]);
        MPI_Finalize();
        exit(1);
    }

    ierr = MPI_File_open(MPI_COMM_WORLD, argv[1], MPI_MODE_RDONLY, MPI_INFO_NULL, &in);
    if (ierr) {
        if (rank == 0) fprintf(stderr, "%s: Couldn't open file %s\n", argv[0], argv[1]);
        MPI_Finalize();
        exit(2);
    }

        printf("Put word: ");
        scanf ("%s", a);
    printf("\n");

    parprocess(&in, a, rank, size, overlap);


    MPI_File_close(&in);
    MPI_Finalize();
    return 0;
}

1 Ответ

0 голосов
/ 18 июня 2018

Хороший учебник по вводу / выводу: https://www.tacc.utexas.edu/documents/13601/900558/MPI-IO-Final.pdf/eea9d7d3-4b81-471c-b244-41498070e35d

Тогда нужно понимать, что MPI-IO не может прочесть мысли файла :-).Это «только» позволяет процессу пропустить часть файла (в байтах), если вы хотите пропустить определенное количество строк и каждая строка имеет разный размер, у вас нет другого решения, кроме как прочитать весь файл, чтобы найти'\ п'.MPI-IO не волшебник ...

Лучшим решением было бы создать (один раз) заголовок, который описывает, где заканчиваются группы строк.Вы можете получить количество байтов для каждой группы из 10 000 строк, а затем использовать это в качестве заголовка в вашем файле.Вы сможете пропустить несколько блоков.Очевидно, чтобы вы прочитали весь файл один раз ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...