いくつかの簡単な練習アプリの外で初めてMPIを使用し、何かがうまくいかない。私はいくつかのキーの値を送信することにより、プロセス間の粒子のセットを送りたいMPIのユーザ定義データ型は、私が安全にしていることですか?
class particle
{
public:
double _lastUpdate;
float _x, _y, _xvel, _yvel;
bool _isStatic;
bool _isForeign;
float _size;
private:
int _isStaticInt; // integer copy of _isStatic to be sent over MPI (since there's no MPI_BOOL :C)
};
:
私は、以下のメンバー(読みやすさのために省略方法や画面保護スペース)で定義されたクラスを持っています各パーティクルのメンバ、およびその場で他のパーティクルを複製します。そのために、MPIデータ型をそのように定義します。あなたが見ることができるように、メンバー_lastUpdate、_isStaticと_isForeignが含まれていません。
MPI_Datatype types[] = { MPI_FLOAT, MPI_FLOAT, MPI_FLOAT, MPI_FLOAT, MPI_INTEGER, MPI_FLOAT };
std::vector<int> len(6, 1);
std::vector<MPI_Aint> disp(6, 0);
particle temp;
MPI_Aint base;
MPI_Address(&temp, &base);
MPI_Address(&temp._x, &disp[0]);
MPI_Address(&temp._y, &disp[1]);
MPI_Address(&temp._xvel, &disp[2]);
MPI_Address(&temp._yvel, &disp[3]);
MPI_Address(&temp._isStaticInt, &disp[4]);
MPI_Address(&temp._size, &disp[5]);
for (int i=0; i<6; ++i)
{
disp[i] = disp[i] - base;
}
MPI_Type_struct(6, &len[0], &disp[0], types, &_particleType);
MPI_Type_commit(&_particleType);
これは、私は、粒子を送信する方法です。 'parts'は、送信したいパーティクルオブジェクトへのポインタを含むパーティクル*のベクトルで、 'size'はparts.size()です。
std::vector<int> len(size, 1);
std::vector<MPI_Aint> disp(size, 0);
MPI_Aint base;
MPI_Address(parts[0], &base); // datatype begins at the first selected object
for (int select = 1; select < size; ++select)
{
MPI_Address(parts[select], &disp[select]);
disp[select] = disp[select] - base;
}
MPI_Type_hindexed(size, &len[0], &disp[0], _particleType, &_sendType);
MPI_Type_commit(&_sendType);
MPI_Request payload_req;
MPI_Isend(parts[0], 1, _sendType, ngb, 0, _cartesian_comm, &payload_req);
受信手段にのみ、この場合には、同様に起こり、「部」は、そのメンバーたちが受け取るデータで満たされている、以前に作成した「ブランク」パーティクルオブジェクト、を指す粒子のベクトル*です:
std::vector<int> len(size, 1);
std::vector<MPI_Aint> disp(size, 0);
MPI_Aint base;
MPI_Address(parts[0], &base); // datatype begins at the first newly inserted object
for (int part = 1; part < size; ++part)
{
MPI_Address(parts[part], &disp[part]);
disp[part] = disp[part] - base;
}
MPI_Type_hindexed(size, &len[0], &disp[0], _particleType, &_recvType);
MPI_Type_commit(&_recvType);
MPI_Status status;
MPI_Recv(parts[0], size, _particleType, ngb, 0, _cartesian_comm, &status);
最初のパーティクル以外のすべての受信パーティクルには、メンバー内にデフォルトの "空白"値があります。私は小さなテストアプリを書いた前にそれは似たようなことをしましたが、それは完璧に機能しましたが、いくつかの単純な値しか伝えませんでした。これは私がここで気付いていないコーディングミスがない限り(完全に可能な)、この種のトリッキーは動作することが保証されておらず、その些細なことは偶然だけであることを信じています。
このタイプのメモリ操作が安全で信頼できるものであるかどうかは誰でも確認/拒否できますか?