我需要使用MPI_Bcast()在MPI中实现一个简单的代码。我希望使用MPI_Probe()使它更有用,所以我不必每次都手动将消息大小写入MPI_Recv()。
我曾经使用MPI_Send()执行此操作,但使用MPI_Bcast()时,程序会挂起在MPI_Probe()上。你知道为什么吗?
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#define ARR_LEN 1
int main() {
MPI_Init(NULL, NULL);
typedef struct Values {
int id;
char * c;
} Values;
Values val1;
val1.id = 5;
val1.c = "Ahoj";
MPI_Datatype valuesDatatypeTmp;
int blockLengths[2] = {1, 3};
MPI_Aint indices[2];
MPI_Address( &val1.id, &indices[0] );
MPI_Address( &val1.c, &indices[1] );
indices[1] -= indices[0];
indices[0] = 0;
MPI_Datatype types[2] = {MPI_INT, MPI_CHAR};
MPI_Type_create_struct( 2, blockLengths, indices, types, &valuesDatatypeTmp );
MPI_Datatype valuesDatatype;
MPI_Type_create_resized( valuesDatatypeTmp,
indices[0],
(MPI_Aint)sizeof(struct Values),
&valuesDatatype );
MPI_Type_free( &valuesDatatypeTmp );
MPI_Type_commit( &valuesDatatype );
//-----------------------//
//--- Message passing ---//
//-----------------------//
int world_size;
MPI_Comm_size( MPI_COMM_WORLD, &world_size );
int world_rank;
MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
MPI_Status status;
Values * buf;
Values val[ARR_LEN] = {val1};
switch( world_rank ) {
case 0:
printf("Toto je proces cislo %d - root.\n", world_rank);
MPI_Bcast( val, ARR_LEN, valuesDatatype, 0, MPI_COMM_WORLD );
break;
default:
MPI_Probe( 0, 0, MPI_COMM_WORLD, &status );
int status_size;
MPI_Get_count( &status, valuesDatatype, &status_size );
buf = (Values *) malloc( sizeof(struct Values) * status_size );
MPI_Recv( buf, status_size, valuesDatatype, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE );
printf( "Toto je proces cislo %d.\n", world_rank );
for( int i = 0; i < ARR_LEN; i++ ) {
printf("Prijata zprava je %d %s\n"\
"Delka zpravy byla %d\n",
buf[i].id,
buf[i].c,
status_size);
}
break;
}
MPI_Type_free( &valuesDatatype );
MPI_Finalize();
return 0;
}
答案 0 :(得分:0)
我发现代码无法正常工作,因为我正在错误地使用MPI_Bcast()。使用MPI_Bcast()时不使用MPI_Recv()。每个进程只使用MPI_Bcast(),因此root与每个人“共享”缓冲区。
我也找到了比我更好地解释这个问题的答案 - 我以前在某种程度上错过了它们:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#define ARR_LEN 1
int main() {
MPI_Init(NULL, NULL);
typedef struct Values {
int id;
char * c;
} Values;
Values val1;
val1.id = 5;
val1.c = "Ahoj";
MPI_Datatype valuesDatatypeTmp;
int blockLengths[2] = {1, 3};
MPI_Aint indices[2];
MPI_Address( &val1.id, &indices[0] );
MPI_Address( &val1.c, &indices[1] );
indices[1] -= indices[0];
indices[0] = 0;
MPI_Datatype types[2] = {MPI_INT, MPI_CHAR};
MPI_Type_create_struct( 2, blockLengths, indices, types, &valuesDatatypeTmp );
MPI_Datatype valuesDatatype;
MPI_Type_create_resized( valuesDatatypeTmp,
indices[0],
(MPI_Aint)sizeof(struct Values),
&valuesDatatype );
MPI_Type_free( &valuesDatatypeTmp );
MPI_Type_commit( &valuesDatatype );
int world_size;
MPI_Comm_size( MPI_COMM_WORLD, &world_size );
int world_rank;
MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
MPI_Status status;
Values * buf;
Values val[ARR_LEN] = {val1};
MPI_Bcast( val, ARR_LEN, valuesDatatype, 0, MPI_COMM_WORLD );
printf( "This is the processnumber %d.\n", world_rank );
for( int i = 0; i < ARR_LEN; i++ ) {
printf("Message received: %d %s\n",
val[i].id,
val[i].c
);
}
MPI_Type_free( &valuesDatatype );
MPI_Finalize();
return 0;
}