2009-07-23 7 views
0

몇 가지 간단한 연습용 앱 외부에서 처음 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'는 보내려는 입자 객체에 대한 포인터를 포함하는 particle 벡터입니다. '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); 

첫 번째 입자를 제외한 모든 수신 된 입자는 구성원에 기본 "빈 값"이 있습니다. 그 전에 비슷한 테스트를 해본 적은 테스트 앱을 작성했는데 몇 가지 간단한 값만 전송 했음에도 불구하고 완벽하게 작동했습니다. 이것은 코딩 실수가 없다면 전적으로 가능할 것입니다. 이런 종류의 데이터 유형의 속임수는 작동하는 것이 보장되지 않으며, 우연히 만 작동하는 작은 것입니다.

이 유형의 메모리 조작이 안전하고 의존해야한다면 누구라도 확인/거부 할 수 있습니까?

답변

1

간단히 질문을 입력하면 나에게 무엇이 잘못되었는지 알 수있게되었습니다.

명령은해야 나타납니다

MPI_Recv(parts[0], 1, _recvType, ngb, 0, _cartesian_comm, &status);