Я работал над проектом MPI, в котором все подчиненные устройства отправляют данные обратно на мастер. По какой-то причине мастер получит данные только в том случае, если я выполню две последовательные отправки подряд. Это очень странно, и я думаю, что это вызывает некоторые другие странные проблемы, которые я получаю. Есть идеи, что вызвало бы это? Я думаю, что первая отправка отправляет какие-то ненужные данные или что-то в этом роде. Посылки — это точно такая же строка кода.
РЕДАКТИРОВАТЬ: код ниже …
if (numProcs > 0)
MPI_Barrier( MPI_COMM_WORLD ) ; //only wait if there are other processes to wait for
if (rank != 0)
{
MPI_Send(handArray, 10, MPI_DOUBLE, 0, TAG_HAND, MPI_COMM_WORLD);
MPI_Send(handArray, 10, MPI_DOUBLE, 0, TAG_HAND, MPI_COMM_WORLD);
}
//8. After the main loop the master process receives and sums together the hand counts array
// from each slave process.
else
{
int activeProcs = numProcs - 1;
getHandsFromSlaves( activeProcs, handArray );
Затем мастер приступает к печати некоторых данных …
Вот метод getHands FromSlaves. Обратите внимание, что я также пытался использовать для этого блокирующие вызовы с теми же проблемами.
void getHandsFromSlaves( int& activeCount, double handTotals[10] ){
static MPI_Request request;
static int msgBuff, recvFlag;
static double handBuff[10];
MPI_Status status;
while (activeCount > 0)
{
if( request )
{
// Already listening for a message
// Test to see if message has been received
MPI_Test( &request, &recvFlag, &status );
//cout << "TAG: " << status.MPI_TAG << " SOURCE: "<< status.MPI_SOURCE << " ERROR: " << status.MPI_ERROR << endl;
if( recvFlag )
{
// Message received
if( status.MPI_TAG == TAG_HAND )
{
cout << "Hand Received!" << endl;
for(int m = 0; m < 10; ++m)
{
handTotals[m] += handBuff[m];
}
activeCount--;
}
else
{
//error report... what happened?
cout << "TAG: " << status.MPI_TAG << " SOURCE: "<< status.MPI_SOURCE << " ERROR: " << status.MPI_ERROR << endl;
}
// Reset the request handle
request = 0;
}
}
if( !request && activeCount > 0 )
// Start listening again
MPI_Irecv(&handBuff, 10, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &request);
}
}
Ну, вы, вероятно, пытаетесь обработать слишком много сообщений, потому что ваш request
переменная не определена при вводе вашего getHandsFromSlaves()
рутина. Так как на входе, request
почти наверняка ненулевой, вы сразу попытаетесь MPI_Test
за сообщение что-то, даже если вы не опубликовали Irecv
,
На самом деле, здесь есть много действительно странных вещей в отрывке кода. Почему локальные переменные static
? Почему бы вам реализовать свой напряженный MPI_Test()
Вместо того, чтобы использовать MPI_Wait()
? Почему вы используете неблокирующие приемы вообще, если между приемами не делаете ничего полезного? И действительно, если вы все равно просто суммируете все массивы, почему вы вообще делаете отдельные двухточечные приемы вместо того, чтобы делать MPI_Reduce()
?
Следующий гораздо более короткий код, кажется, делает то, что вы пытаетесь сделать выше:
#include <stdio.h>
#include <mpi.h>int main (int argc, char **argv) {
int rank, numProcs;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
double handArray[10];
double handTotal[10];
for (int i=0; i<10; i++)
handArray[i] = rank + i;
if (rank == 0) // Since apparently rank 0 doesn't do anything
{
for (int i=0; i<10; i++)
handArray[i] = 0;
}
MPI_Reduce(handArray, handTotal, 10, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
if (rank == 0) {
printf("Hand Totals= \n");
for (int i=0; i<10; i++)
printf(" %lf ", handTotal[i]);
printf("\n");
}
MPI_Finalize();
}
Других решений пока нет …