#c #mpi #openmpi
#c #mpi #openmpi
Вопрос:
Итак, я попробовал некоторые вещи в MPI, чтобы получить представление об этом, и я получил некоторые результаты, которые я не могу объяснить, просматривая документацию. Я использую открытый mpi.
#include <mpi.h>
#include <stdio.h>
#include <unistd.h>
#define PROBLEMSIZE 41
int main(int argc, char** argv) {
// Initialize the MPI environment
MPI_Init(amp;argc, amp;argv);
// Get the number of processes
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, amp;world_size);
// Get the rank of the process
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, amp;world_rank);
double send[PROBLEMSIZE];
MPI_Request request[PROBLEMSIZE];
int flag;
int array_of_indices[PROBLEMSIZE];
MPI_Status status[PROBLEMSIZE];
if(world_rank == 0)
{
for (int i = 0; i < PROBLEMSIZE; i )
{
request[i] = MPI_REQUEST_NULL;
send[i] = i;
}
for (int i = 0; i < PROBLEMSIZE; i )
{
MPI_Isend(amp;send[i],1,MPI_DOUBLE,1,i,MPI_COMM_WORLD,amp;request[i]);
}
MPI_Waitall(PROBLEMSIZE,request,status);
for (int i = 0; i < PROBLEMSIZE; i )
{
//printf("%i count %i", i, status[i].count);
//printf("%i cancel %i", i, status[i].cancel);
printf("%i MPI_SOURCE %in", i, status[i].MPI_SOURCE);
printf("%i MPI_TAG %in", i, status[i].MPI_TAG);
printf("%i MPI_ERROR %in n", i, status[i].MPI_ERROR);
}
printf("thread 0 done");
}
if (world_rank == 1)
{
sleep(10);
for (int i = 0; i < PROBLEMSIZE; i )
{
MPI_Irecv(amp;send[i],1,MPI_DOUBLE,0,i,MPI_COMM_WORLD, amp;request[i]);
}
int outcount;
do {
MPI_Testsome(PROBLEMSIZE,request, amp;outcount, array_of_indices, MPI_STATUSES_IGNORE);
printf("did some waiting, outcount is %in",outcount);
} while (outcount != 0);
for (int i = 0; i < PROBLEMSIZE; i )
{
printf("%f n",send[i]);
}
/*
sleep(20);
MPI_Testall(PROBLEMSIZE,request,MPI_STATUSES_IGNORE);
for (int i = 0; i < PROBLEMSIZE; i )
{
printf("%f n",send[i]);
}
*/
}
MPI_Finalize();
return 0;
}
/Редактировать
Чего я пытаюсь добиться, так это возможности отправлять произвольное количество данных с разными тегами из одного процесса в другой, где отправитель может блокировать и ждать, пока оно не будет получено, но получатель не должен блокировать, когда нечего получать.
Редактировать/
Итак, вот что сбивает меня с толку:
- MPI_Waitall в строке 36, похоже, на самом деле не блокируется, пока не произойдет обмен данными. Следовательно, последующая печать статуса приводит к полной подделке. (Источник = -2, Тег = -1, Ошибка = 0). Однако следующая строка
printf("thread 0 done");
, похоже, ждет, пока программа не будет завершена, что более чем немного сбивает меня с толку. - При попытке получить числа в строке 59, кажется, что только первые 16 совершают поездку, я попытался использовать MPI_Testall, MPI_Testsome и MPI_Waitsome для этого с тем же результатом. Я предположил, что это произошло из-за того, что буфер достиг какого-то предела, и попытался зациклить его несколько раз, пока он получал данные. Согласно документации
outcount
, должно содержаться количество полученных объектов, но всегда равно 0 при попытке сделать это с помощью MPI_Testsome и -32766 при попытке сделать это с помощью MPI_Waitsome. Оба эти явно подозрительные числа, но я не уверен, как и почему им удалось бы переполниться до -32766. - Использование MPI_Waitall для получения данных в потоке 1 дает желаемое поведение, ставя под сомнение мое подозрение, что это проблема с буфером. Однако эта реализация — это не то, что я ищу, так как я хотел бы, чтобы поток 1 мог что-то делать и периодически проверять поступление новых данных.
Ответ №1:
- Я не уверен
MPI_TAG
MPI_SOURCE
, что поля и релевантны, когдаMPI_Status
они связаны с запросом на отправку MPI_Test()
а друзья — это неблокирующие подпрограммы, которые возвращаются немедленно. Я не уверен, чего вы здесь добиваетесь, но, возможно, вы захотите использоватьMPI_Waitsome()
вместо этого.
Комментарии:
1. 1. Это справедливо, хотя и не объясняет, почему
MPI_Waitall
right before, похоже, не блокируется до тех пор, пока принимающий поток не проверит. Насколько я понимаю, это должно быть ожидаемое поведение, нет? 2. Это имеет смысл, почему MPI_Test тогда записал бы 0 в outcount, поскольку это, вероятно, не было сделано к моменту проверки? Как я уже упоминал в посте, хотя Waitsome записывает -32766 в outcount, что я вообще не могу объяснить. Я отредактировал исходное сообщение, добавив немного о том, чего я хочу достичь, поскольку я достиг предела символов комментария.2. Это ожидание возвращается, когда буфер отправки может быть использован повторно, это может произойти даже до отправки сообщения.
-32766
очень вероятноMPI_UNDEFINED
, см. Справочные страницы, чтобы узнать, как это интерпретировать.3. Спасибо, что проясняет большинство моих недоразумений.