문제

간단한 연습 앱 외부에서 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);

이것이 내가 입자를 보내는 방법입니다. '부품'은 내가 보내고 싶은 입자 물체에 대한 포인터를 포함하는 입자의 벡터*이며 '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);

문제는 첫 번째 입자를 제외한 모든 입자가 멤버에 기본 "공백"값을 가지고 있다는 것입니다. 나는 그 전에 작은 테스트 앱을 썼다. 그로 인해 비슷한 일이 있었지만 몇 가지 간단한 값 만 전송했지만 완벽하게 작동했다. 이로 인해 코딩 실수가 없으면 여기에서 눈치 채지 못하는 경우 (전적으로 가능), 이런 종류의 데이터 유형의 속임수는 작동하는 것이 보장되지 않으며, 작동하는 작은 것은 우연히만 그렇게합니다.

이 유형의 메모리 조작이 안전하고 의존 해야하는지 확인/거부 할 수 있습니까?

도움이 되었습니까?

해결책

신경 쓰지 마십시오. 단순히 질문을 입력하면 무엇이 잘못되었는지 깨달았습니다.

수신 명령은 다음과 같아야합니다.

MPI_Recv(parts[0], 1, _recvType, ngb, 0, _cartesian_comm, &status);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top