Как поделиться массивом строк, используя открытый MPI - PullRequest
2 голосов
/ 05 июня 2019

Я новичок в openmpi и не знаю, как использовать scatter и collect для отправки массива строк всем процессорам. Я хотел бы разделить массив и отправить его каждому процессору, но все, что я могу разделить, это символы одного элемента массива. Может кто-нибудь помочь мне, пожалуйста?

Вот мой код:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mpi.h"

#define MASTER 0

#define BUF_SIZE 2048
#define CHAR_SIZE 900                                                       
#define CHARS 13                                                            
#define MAX_SIZE 3500                                                    
#define NUMBER_OF_FILES  2                                                   

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

    int number_of_words = 0;
    int total_rows = 0; 
    int i, j = 0;

    char **words = (char**) calloc(MAX_SIZE, sizeof (char*));

    for (i = 0; i < MAX_SIZE; i++) {
        words[i] = (char*) calloc(CHARS, sizeof (char));
    }

    char **local_words = (char**) calloc(MAX_SIZE, sizeof (char*));

    for (i = 0; i < MAX_SIZE; i++) {
        local_words[i] = (char*) calloc(CHARS, sizeof (char));
    }

    char **rec_words = (char**) calloc(MAX_SIZE, sizeof (char*));

    for (i = 0; i < MAX_SIZE; i++) {
        rec_words[i] = (char*) calloc(CHARS, sizeof (char));
    }

    char str_righe[BUF_SIZE][CHAR_SIZE]; 

    FILE *f = NULL;
    char f_title[10]; 
    char str_nfiles[10]; 

    char delim[10] = {10, 32, 33, 39, 44, 46, 58, 59, 63}; 

    char *ptr;

    int rank;
    int size;
    int message_length;

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

    for (i = 1; i <= NUMBER_OF_FILES; i++) {
        strcpy(f_title, "f");
        sprintf(str_nfiles, "%d", i);
        strcat(f_title, str_nfiles);
        strcat(f_title, ".txt");

        f = fopen(f_title, "r");
        while (fgets(str_righe[j], BUF_SIZE, f)) {
            str_righe[j][strlen(str_righe[j])] = '\0';
            j++;
        }
        fclose(f);
    }

    total_rows = j;

    for (i = 0; i < total_rows; ++i) {
        ptr = strtok(str_righe[i], delim);

        while (ptr != NULL) {
            strcpy(words[number_of_words], ptr);
            ptr = strtok(NULL, delim);
            number_of_words++;
        }
    }

    message_length = number_of_words / size;

    if (rank == MASTER) {
        for (i = 0; i < number_of_words; i++)
            printf("%s\n", words[i]);
    }

    MPI_Scatter(*words, message_length, MPI_CHAR, *local_words, message_length, MPI_CHAR, MASTER, MPI_COMM_WORLD);

    printf("rank %d, fragment: \t%s\n", rank, *local_words);

    MPI_Gather(*local_words, message_length, MPI_CHAR, *rec_words, message_length, MPI_CHAR, MASTER, MPI_COMM_WORLD);

    if (rank == MASTER) {
        printf("rank %d, gathered: \t%s\n", rank, *rec_words);
    }

    MPI_Finalize();

    return EXIT_SUCCESS;
}

Я ожидаю выхода:

iMac-di-iMac01:mpi macbook$ mpirun -n 2 main
Good
time
by
antonio
rank 0, fragment:   Good time
rank 1, fragment:   by antonio
rank 0, gathered:   Good time by antonio

Но фактический результат:

iMac-di-iMac01:mpi macbook$ mpirun -n 2 main
Good
time
by
antonio
rank 0, fragment:   Go
rank 1, fragment:   od
rank 0, gathered:   Good
...