Я пытаюсь реализовать умножение матрицы на вектор с использованием MPI (то есть матрица nxn
, умноженная на вектор nx1
).
Изначально я решил использовать несколько вызовов MPI_Bcast
(прежде чем я заметилMPI_AllGather
...) и я наткнулся на какое-то странное поведение.По-видимому, данные могут быть получены независимо от того, какой ранг передан вызову MPI_Bcast
.
Часть используемого кода (функции вызываются сразу после друг друга, поэтому отправка широковещательной рассылки происходит до получения широковещательной рассылки).Отпечатки предназначены только для целей отладки, где я знаю, что данные тестирования имеют длину 2:
class Processor
{
public:
Processor(int rank, int communicatorSize);
private:
void broadcastOwnVectorToOtherRanks();
void receiveBroadcastsFromOtherRanks();
//...
int ownRank;
int communicatorSize;
std::vector<int> ownVectorPart;
std::vector<int> totalVector;
//...
};
void Processor::broadcastOwnVectorToOtherRanks()
{
//ownVectorPart is correctly filled before this function call
std::printf("Own data in vector %d %d\n", ownVectorPart[0], ownVectorPart[1]);
MPI_Bcast(ownVectorPart.data(), ownVectorPart.size(), MPI_INT, ownRank, MPI_COMM_WORLD);
}
void Processor::receiveBroadcastsFromOtherCommunicators()
{
for (int rank = 0; rank < communicatorSize; ++rank)
{
if (rank == ownRank)
{
totalVector.insert(totalVector.end(), ownVectorPart.begin(), ownVectorPart.end());
}
else
{
std::vector<int> buffer(ownVectorPart.size());
MPI_Bcast(buffer.data(), ownVectorPart.size(), MPI_INT, rank, MPI_COMM_WORLD);
std::printf("Received from process with rank %d: %d %d\n", rank, buffer[0], buffer[1]);
totalVector.insert(totalVector.end(), buffer.begin(), buffer.end());
}
}
}
Результат (отсортирован по рангу):
[0] Own data in vector 0 1
[0] Received from communicator 1: 6 7
[0] Received from communicator 2: 4 5
[0] Received from communicator 3: 2 3
[1] Own data in vector 2 3
[1] Received from communicator 0: 0 1
[1] Received from communicator 2: 4 5
[1] Received from communicator 3: 6 7
[2] Own data in vector 4 5
[2] Received from communicator 0: 0 1
[2] Received from communicator 1: 2 3
[2] Received from communicator 3: 6 7
[3] Own data in vector 6 7
[3] Received from communicator 0: 4 5
[3] Received from communicator 1: 2 3
[3] Received from communicator 2: 0 1
Как видите,в процессе с рангом 0 и 3 полученные данные отличаются от отправленных данных.Например, процесс с рангом 0
получил данные с рангом 3
, хотя он ожидает данные от процесса 1
.
Мне кажется, что ранг не учитывается при получении широковещательных данных и MPIприсваивает данные в том виде, в каком они получены, независимо от того, были ли они ожидаемыми или нет.
Почему MPI_Bcast
получает данные от процесса с рангом 3
, когда в качестве аргумента передается ранг 1
?Вызывает ли MPI_Bcast
несколько раз одновременно неопределенное поведение?Или в моем коде есть ошибка?