Мысли:
MPI_Init
должно быть первым в вашей программе. - Только один ранг должен
scanf
. N
не передается между рядами, поэтому вы выделяете память неопределенного размера. - Определяйте переменные как можно ближе к точке их использования. Помещение
int i
в начале вашей функции - это катастрофа, ожидающая, что произойдет. - Барьер в конце не нужен.
- Все ряды должны распределить свои собственная память.
Это приводит нас к следующему коду:
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
int main(int argc, char **argv){
MPI_Init(&argc, &argv);
const int tag = 99;
const int tag1 = 100;
int rank, size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
double *a; //Pointer to the memory we will allocate
int N;
if (rank == 0){
scanf("%d", &N);
a = (double *)malloc(N * sizeof(double));
for(int j=0;j<N;++j){
a[j] = j+0.1;
}
for (int i = 1; i < size; i++){
MPI_Send(&N, 1, MPI_INT, i, tag1, MPI_COMM_WORLD);
MPI_Send(a, N, MPI_DOUBLE, i, tag, MPI_COMM_WORLD);
}
} else {
MPI_Status status;
MPI_Recv(&N, 1, MPI_INT, 0, tag1, MPI_COMM_WORLD, &status);
//Have to allocate memory on all ranks
a = (double *)malloc(N * sizeof(double));
MPI_Recv(a, N, MPI_DOUBLE, 0, tag, MPI_COMM_WORLD, &status);
// for(int j=0;j<N*2;++j)
// printf("%d %f\n", rank, a[j]);
}
printf("Message from process %d : %f\n", rank, a[rank]);
MPI_Finalize();
return 0;
}
Делаем лучше
Команда вещания - ваш друг здесь:
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
#define MPI_Error_Check(x) {const int err=x; if(x!=MPI_SUCCESS) { fprintf(stderr, "MPI ERROR %d at %d.", err, __LINE__);}}
int main(int argc, char **argv){
MPI_Init(&argc, &argv);
int rank, size;
MPI_Error_Check(MPI_Comm_rank(MPI_COMM_WORLD, &rank));
MPI_Error_Check(MPI_Comm_size(MPI_COMM_WORLD, &size));
int N;
if (rank==0){
scanf("%d", &N);
}
MPI_Error_Check(MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD));
double *a = (double *)malloc(N * sizeof(double));
if(rank==0){
for(int j=0;j<N;++j){
a[j] = j+0.1;
}
}
printf("Message from process %d : N=%d\n", rank, N);
MPI_Error_Check(MPI_Bcast(a, N, MPI_DOUBLE, 0, MPI_COMM_WORLD));
fprintf(stderr, "Message from process %d : %f\n", rank, a[rank]);
free(a);
MPI_Finalize();
return 0;
}
Делая это еще лучше
Самая быстрая форма общения - это вообще отсутствие общения. В вашем случае, когда известно значение N
, каждый ранг может воссоздать данные самостоятельно:
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
#define MPI_Error_Check(x) {const int err=x; if(x!=MPI_SUCCESS) { fprintf(stderr, "MPI ERROR %d at %d.", err, __LINE__);}}
int main(int argc, char **argv){
MPI_Init(&argc, &argv);
int rank, size;
MPI_Error_Check(MPI_Comm_rank(MPI_COMM_WORLD, &rank));
MPI_Error_Check(MPI_Comm_size(MPI_COMM_WORLD, &size));
int N;
if (rank==0){
scanf("%d", &N);
}
MPI_Error_Check(MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD));
double *a = (double *)malloc(N * sizeof(double));
for(int j=0;j<N;++j){
a[j] = j+0.1;
}
printf("Message from process %d : N=%d\n", rank, N);
fprintf(stderr, "Message from process %d : %f\n", rank, a[rank]);
free(a);
MPI_Finalize();
return 0;
}