MPI Scatter / отправка данных в процессы - PullRequest
0 голосов
/ 25 октября 2018

Я выполняю свой код, используя n = 2. Я пытался исследовать, но я не понимаю, почему я получаю разные выходные данные, когда я пытаюсь запустить свой код несколько раз.Ниже вы можете видеть мой вывод, когда я запускаю с n = 2, и мой txt.file содержит 73 символа в каждой строке и состоит из 4 строк.

Это мой вывод в первый раз и запуск, и это ожидаемый и требуемый вывод This is my output the first time and run and is the expected and wanted output

Это вывод во второй раз, когда я запускаю код This is the output the second time I run the code

Это вывод в третий раз, когда я запускаю код This is the output the third time I run the code

Я не знаю, что делать, чтобы предотвратить ошибки, возникающие на изображении 2 (где у вас есть \ 274 во второй напечатанной строке) ино особенно с ошибками я получаю в третий раз запуск кода.Должен ли я использовать MPI_Allocate?Я освобождаю матрицу рано?

Это мой код:

#define MAXCHAR 73
#define MAXLENGTH 100

int main(int argc, char** argv) {
FILE *fp;
char* filename = "/Users/test.txt";
char *line = malloc(MAXCHAR);
char (*matA)[MAXCHAR] = NULL;
char str[MAXCHAR];
int rowCount, num_rows, i, my_id, 
root_process,num_procs,rows_per_process;

MPI_Init(&argc, &argv);
root_process = 0;



/* find out MY process ID, and how many processes were started. */
MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);


// READ TXT FILE INTO DYNAMIC ARRAY
if(my_id == root_process){
    fp = fopen(filename, "r");
    if (fp == NULL){
        printf("Could not open file %s",filename);
        return 1;
    }
    //NUMBER OF lines
    size_t count=1000;
    rowCount=0;
    while(getline(&line, &count, fp)!=-1) {
        rowCount++;
    }
    //REWIND file
    rewind(fp);

    matA = malloc(rowCount*sizeof(matA));
    i = 0;
    while (fgets(str, MAXCHAR, fp) != NULL){
        for (size_t j = 0; j < MAXCHAR; j++) {
            if(str[j] == '\n'){
                continue;
            }
            matA[i][j] = str[j];
        }
        i++;
        num_rows = i;
    }
    fclose(fp);

}

// BCAST rowCount to Calculate rows each process will receive
MPI_Bcast(&rowCount, 1, MPI_INT, 0, MPI_COMM_WORLD);
rows_per_process = rowCount/num_procs;



char(*part_matrix)[MAXCHAR];
part_matrix = malloc(rows_per_process*sizeof(*part_matrix));


MPI_Scatter(&(matA[0][0]), rows_per_process*73, MPI_CHAR, &(part_matrix[0][0]), rows_per_process*73, MPI_CHAR, 0, MPI_COMM_WORLD);
printf("Process %i received %i rows:\n", my_id, rows_per_process);

// PRINTING
for (size_t i = 0; i < rows_per_process; i++) {
    printf("PROCESS %i PRINTS LINE NUMBER %zu:\n", my_id, i);
    for (size_t j = 0; j < MAXCHAR; j++) {
        printf("%c", part_matrix[i][j]);
    }
    printf("\n" );
}

free(part_matrix);
MPI_Finalize();
return 0;
}

1 Ответ

0 голосов
/ 31 октября 2018

Я полагаю, что большая часть вашей проблемы связана с тем, что

char (*matA)[MAXCHAR] = NULL;
matA = malloc(rowCount*sizeof(matA));

- странный способ размещения ваших данных.

char *matA = NULL;
matA = malloc(rowCount*MAXCHAR*sizeof(char));

кажется более разумным

То же самое касается

char *part_matrix=NULL;
part_matrix = (char*) malloc(rows_per_process*MAXCHAR*sizeof(char));

Таким образом, вы уверены, что matA и part_matrix непрерывны в памяти и при использовании функций MPI никакого вреда не будет (в отношении памяти).

MPI_Scatter simply becomes MPI_Scatter(matA, rows_per_process*MAXCHAR, MPI_CHAR, part_matrix, rows_per_process*MAXCHAR, MPI_CHAR, 0, MPI_COMM_WORLD);

Я изменил способ чтения вашего файла, чтобы заставить его работать ...

matA = (char*)malloc(rowCount*MAXCHAR*sizeof(char));
i = 0;
while (getline(&line, &count, fp)!=-1){
    for (j = 0; j < MAXCHAR; j++) {
        matA[i*MAXCHAR+j] = line[j];
    }
    i++;
    num_rows = i;
}

Итак, вы получили полный рабочий пример с test.txt, равным

AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA  
BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB  
CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC  
DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD  

основной файл

#include <stdlib.h>
#include <stdio.h>
#include "mpi.h"
#define MAXCHAR 73
#define MAXLENGTH 100

int main(int argc, char** argv) {
FILE *fp;
char* filename = "test.txt";
char *line = (char*) malloc(MAXLENGTH);
char * matA= NULL;
char str[MAXCHAR];
int rowCount, num_rows, i, my_id, 
root_process,num_procs,rows_per_process, j;

MPI_Init(&argc, &argv);
root_process = 0;



/* find out MY process ID, and how many processes were started. */
MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);

// READ TXT FILE INTO DYNAMIC ARRAY
if(my_id == root_process){
    fp = fopen(filename, "r");
    if (fp == NULL){
        printf("Could not open file %s",filename);
        return 1;
    }
    //NUMBER OF lines
    size_t count=1000;
    rowCount=0;
    while(getline(&line, &count, fp)!=-1) {
        rowCount++;
    }
    //REWIND file
    rewind(fp);

    matA = (char*)malloc(rowCount*MAXCHAR*sizeof(char));
    i = 0;
    while (getline(&line, &count, fp)!=-1){
        for (j = 0; j < MAXCHAR; j++) {
            matA[i*MAXCHAR+j] = line[j];
        }
        i++;
        num_rows = i;
    }
    fclose(fp);
}

// BCAST rowCount to Calculate rows each process will receive
MPI_Bcast(&rowCount, 1, MPI_INT, 0, MPI_COMM_WORLD);
rows_per_process = rowCount/num_procs;


char *part_matrix = NULL;
part_matrix = (char*) malloc(rows_per_process*MAXCHAR*sizeof(char));


MPI_Scatter(matA, rows_per_process*MAXCHAR, MPI_CHAR, part_matrix, rows_per_process*MAXCHAR, MPI_CHAR, 0, MPI_COMM_WORLD);

if(my_id == root_process){
free(matA);
}

printf("Process %i received %i rows:\n", my_id, rows_per_process);
// PRINTING
for (i = 0; i < rows_per_process; i++) {
    printf("PROCESS %i PRINTS LINE NUMBER %zu:\n", my_id, i);
    for (j = 0; j < MAXCHAR; j++) {
        printf("%c", part_matrix[i*MAXCHAR+j]);
    }
    printf("\n" );
}

free(part_matrix);
MPI_Finalize();
return 0;
}

mpirun -n 4 возвращает

PROCESS 0 PRINTS LINE NUMBER 0:
AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA
Process 1 received 1 rows:
PROCESS 1 PRINTS LINE NUMBER 0:
BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB
Process 2 received 1 rows:
PROCESS 2 PRINTS LINE NUMBER 0:
CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC
Process 3 received 1 rows:
PROCESS 3 PRINTS LINE NUMBER 0:
DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD

mpirun -n 2 возвращает

Process 0 received 2 rows:
PROCESS 0 PRINTS LINE NUMBER 0:
AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA
PROCESS 0 PRINTS LINE NUMBER 1:
BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB
Process 1 received 2 rows:
PROCESS 1 PRINTS LINE NUMBER 0:
CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC
PROCESS 1 PRINTS LINE NUMBER 1:
DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...