我正在尝试发送一个结构:
struct statpSwitch {
int isActive;
vector<statvRM> vRM;
};
包含另一个结构的向量:
struct statvRM {
int isActive;
int x, y;
};
使用MPI_Datatype
和MPI_Type_struct
。以下是代码:
int main(int argc, char** argv)
{
MPI_Init(&argc, &argv);
// Get ranks and cluster size
int size = 0, rank = 0, len = 0;
char hostname[MPI_MAX_PROCESSOR_NAME];
MPI_Comm mpiComm;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
statpSwitch pSwitch[1], pSwitch_recv[1];
if (rank != 0) {
statvRM vRM;
vRM.isActive = 5;
pSwitch[0].vRM.push_back(vRM);
pSwitch[0].vRM.push_back(vRM);
pSwitch[0].vRM.push_back(vRM);
pSwitch[0].vRM[1].isActive = 69;
pSwitch[0].isActive = 15;
}
MPI_Datatype A_type, B_type;
MPI_Type_contiguous(3, MPI_INT, &A_type);
int counts[2];
MPI_Aint displacements[2];
MPI_Datatype datatypes[2];
counts[0] = 1;
displacements[0] = 0;
datatypes[0] = MPI_INT;
counts[1] = 1;
MPI_Aint extent;
MPI_Type_extent(MPI_INT, &extent);
displacements[1] = pSwitch[0].vRM.size() * extent;
datatypes[1] = A_type;
MPI_Type_struct(2, counts, displacements, datatypes, &B_type);
MPI_Type_commit(&B_type);
// The 1D type is no longer needed
MPI_Type_free(&A_type);
if (rank != 0) {
std::cout << "sending..." << std::flush << std::endl;
MPI_Send(pSwitch, 1, B_type, 0, 123, MPI_COMM_WORLD);
std::cout << pSwitch[0].isActive << " " << pSwitch[0].vRM.at(1).isActive << std::endl;
} else {
MPI_Status status;
MPI_Recv(pSwitch_recv, 1, B_type, 1, 123, MPI_COMM_WORLD, &status);
cout << "received" << std::flush << endl;
std::cout << pSwitch_recv[0].isActive << endl;
cout << pSwitch_recv[0].vRM.at(1).isActive << std::endl;
}
}
但是MPI在MPI_Recv
期间崩溃了。作为参考,使用std::array
而不是std:vector
时完全相同的代码正在按预期工作:
struct statvRM {
int isActive;
int x, y;
};
struct statpSwitch {
int isActive;
array<statvRM,3> vRM;
};
int main(int argc, char** argv)
{
MPI_Init(&argc, &argv);
// Get ranks and cluster size
int size = 0, rank = 0, len = 0;
char hostname[MPI_MAX_PROCESSOR_NAME];
MPI_Comm mpiComm;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
statpSwitch pSwitch[1], pSwitch_recv[1];
if (rank != 0) {
statvRM vRM;
vRM.isActive = 5;
pSwitch[0].vRM[1].isActive = 69;
pSwitch[0].isActive = 15;
}
MPI_Datatype A_type, B_type;
MPI_Type_contiguous(3, MPI_INT, &A_type);
int counts[2];
MPI_Aint displacements[2];
MPI_Datatype datatypes[2];
counts[0] = 1;
displacements[0] = 0;
datatypes[0] = MPI_INT;
counts[1] = 1;
MPI_Aint extent;
MPI_Type_extent(MPI_INT, &extent);
displacements[1] = 3 * extent;
datatypes[1] = A_type;
MPI_Type_struct(2, counts, displacements, datatypes, &B_type);
MPI_Type_commit(&B_type);
// The 1D type is no longer needed
MPI_Type_free(&A_type);
if (rank != 0) {
std::cout << "sending..." << std::flush << std::endl;
MPI_Send(pSwitch, 1, B_type, 0, 123, MPI_COMM_WORLD);
std::cout << pSwitch[0].isActive << " " << pSwitch[0].vRM.at(1).isActive << std::endl;
} else {
MPI_Status status;
MPI_Recv(pSwitch_recv, 1, B_type, 1, 123, MPI_COMM_WORLD, &status);
cout << "received" << std::flush << endl;
std::cout << pSwitch_recv[0].isActive << endl;
cout << pSwitch_recv[0].vRM.at(1).isActive << std::endl;
}
}