【发布时间】:2019-12-18 00:56:48
【问题描述】:
我厌倦了将 DBL 类型数组转换为 char 数组,使用 MPI_Bcast 广播它并转换回 DBL 数组。 DBL 数组可以是以下任何一种:
- 双
- 长双
- mpf_float_50(在 boost/multiprecision/ 包中定义的类型)。
前两种工作正常:
mpicxx -D_DBL main.cpp -o main && mpirun -np 2 main
或
mpicxx -D_LDBL main.cpp -o main && mpirun -np 2 main
给予
before for rank=0
0
0.1
after for rank=1
0
0.1
after for rank=0
0
0.1
但对于
mpicxx -D_EDBL50 main.cpp -o main -lgmp && mpirun -np 2 main
one has
before for rank=0
0
0.1
after for rank=0
0
0.1
after for rank=1
0
[Fominskoe:06235] *** Process received signal ***
[Fominskoe:06235] Signal: Segmentation fault (11)
[Fominskoe:06235] Signal code: Address not mapped (1)
[Fominskoe:06235] Failing at address: 0x55892d02d450
[Fominskoe:06235] [ 0] /lib/x86_64-linux-gnu/libc.so.6(+0x3ef20)
[0x7f26e6333f20]
[Fominskoe:06235] [ 1] /usr/lib/x86_64-linux-
gnu/libgmp.so.10(__gmpn_copyi+0x4d)[0x7f26e71f5213]
[Fominskoe:06235]
* 错误信息结束 *
mpirun 注意到节点 Fominskoe 上 PID 为 0 的进程等级 1 在信号 11 上退出(分段错误)。
我注意到最后一个选择 mpirun -np 1 主要
给出正确答案:
before for rank=0
0
0.1
after for rank=0
0
0.1
#include "mpi.h"
#if defined(_DBL)
typedef double DBL;
#endif
#if defined(_LDBL)
typedef long double DBL;
#endif
#if defined(_EDBL50)
#include <boost/multiprecision/gmp.hpp>
using namespace boost::multiprecision;
typedef mpf_float_50 DBL;
#endif
using namespace std;
int main(int argc, char* argv[])
{
MPI::Init (argc, argv);
int proc_num = MPI::COMM_WORLD.Get_size ( );
int my_rank = MPI::COMM_WORLD.Get_rank ( );
int N=2;
DBL DB[N];
int CN=N*sizeof(DBL);
char CH[CN];
if ( !my_rank ){
cout<<"before for rank="<<my_rank<<endl;
for (int i=0; i<N; i++) { // init array
DB[i]=i*0.1;
cout<<DB[i]<<endl;
}
char* ptr=(char*)(&DB[0]);
for (int i=0; i<CN; i++)
CH[i]=*ptr++;
for (int i=0; i<N; i++) // clean
DB[i]=0;
}
MPI_Bcast (CH, CN, MPI_CHAR, 0, MPI_COMM_WORLD);
int ii=0;
DBL* V;
cout<<"\nafter for rank="<<my_rank<<endl;
for (int i=0; i<N; i++) {
V=(DBL*)(&CH[ii]);
DB[i]=*V;
cout<< DB[i]<<endl;
ii+=sizeof(DBL);
// if (my_rank)
// break;
}
MPI::Finalize();
return 0;
}
如果 MPI 被移除,则转换 DBL->char->DBL 适用于所有三种类型。
Ubuntu 18.04, gcc, mpicxx -- Open MPI C++ wrapper compiler, libboost-all-dev, libboost-tools-dev
有什么想法吗?
【问题讨论】:
-
我确定问题在于
mpf_float_50是复杂类型,无法以您尝试的简单方式进行序列化。 -
Plus
DB[i]=0;正在对您刚刚按字节复制到CH的对象调用析构函数。 -
也许搜索“序列化”?您的循环只是 memcpy,仅适用于普通类型。