MPI 分散/发送数据到进程

MPI Scatter / Send data to processes

我运行我的代码使用 n = 2。我一直在努力研究,但我不明白为什么我多次尝试 运行 我的代码时得到不同的输出. 下面你可以看到当我 运行 和 n = 2 时我的输出,而我的 txt.file 每行包含 73 个字符,并且由 4 行组成。

这是我第一次输出,运行是预期和想要的输出

这是我第二次 运行 代码的输出

这是我运行代码第三次的输出

我不知道如何防止图像 2 中发生错误(在第二个打印行中有 \274),但特别是错误我第三次得到 运行ning代码。我必须使用 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;
}

我相信你的大部分问题来自

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 returns

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 returns

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