MPI (по Бахтину) (1186089), страница 3
Текст из файла (страница 3)
В outcountвозвращается количество выполненных запросов из массиваrequests, а в первых outcount элементах массива indicesвозвращаются индексы этих операций. В первых outcountэлементах массива statuses возвращается статусзавершенных операций. Если выполненный запрос былсформирован неблокирующей операцией обмена, онаннулируется. Если в списке нет активных запросов,выполнение подпрограммы завершается сразу, а параметруoutcount присваивается значение MPI_UNDEFINED.Неблокирующая проверка выполнения обменов:int MPI_Testsome(int incount, MPI_Requestrequests[], int *outcount, int indices[],MPI_Status statuses[])Параметры такие же, как и у подпрограммыMPI_Waitsome. Эффективность подпрограммыMPI_Testsome выше, чем у MPI_Testany, посколькупервая возвращает информацию обо всех операциях, адля второй требуется новый вызов для каждойвыполненной операции.MPI_Comm_rank(MPI_COMM_WORLD, &myrank); /*find rank */if (myrank == 0) {int x;MPI_Isend(&x,1,MPI_INT, 1, msgtag,MPI_COMM_WORLD,&req1);compute();MPI_Wait(&req1, &status);} else if (myrank == 1) {int x;MPI_Recv(&x,1,MPI_INT,0,msgtag,MPI_COMM_WORLD, &status);}Блокирующая проверка:int MPI_Probe(int source, int tag, MPI_Comm comm,MPI_Status* status)Неблокирующая проверка:int MPI_Iprobe(int source, int tag, MPI_Comm comm,int *flag, MPI_Status *status)Входные параметры этой подпрограммы те же, что и уподпрограммы MPI_Probe.Выходные параметры: flag - флаг; status - статус.Если сообщение уже поступило и может быть принято,возвращается значение флага «истина».if (rank == 0) {MPI_Send(buf, size, MPI_INT, 1, 0, MPI_COMM_WORLD); // Send to process 1printf("0 sent %d numbers to 1\n", size);} else if (rank == 1) {MPI_Status status;MPI_Probe(0, 0, MPI_COMM_WORLD, &status); // Probe for an incoming msg.// When probe returns, the status object has the size and other// attributes of the incoming message.
Get the size of the message.MPI_Get_count(&status, MPI_INT, &size)// Allocate a buffer just big enough to hold the incoming numbersint* number_buf = (int*)malloc(sizeof(int) * size);// Now receive the message with the allocated bufferMPI_Recv(number_buf, size, MPI_INT, 0, 0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);printf("1 dynamically received %d numbers from 0.\n",number_amount);free(number_buf);}Передача сообщений между группойпроцессовВызываются ВСЕМИ процессами вкоммуникатореПримеры:◦ Broadcast, scatter, gather (рассылка данных)◦ Global sum, global maximum, и.т.д.(редукционные операции)◦ Барьерная синхронизациКоллективные операции не являются помехойоперациям типа точка-точка и наоборотВсе процессы коммуникатора должны вызыватьколлективную операциюСинхронизация не гарантируется (за исключениембарьера)Нет неблокирующих коллективных операцийНет тэговПринимающий буфер должен точно соответствоватьразмеру отсылаемого буфераOne-to-all передача: один и тот же буферотсылается от процесса root всемостальным процессам в коммуникатореint MPI_Bcast (void *buffer, int, count,MPI_Datatype datatype,int root, MPI_Commcomm)Все процессы должны указать один тот жеroot и communicatorOne-to-all communication: различные данные изодного процесса рассылаются всем процессамкоммуникатора (в порядке их номеров)int MPI_Scatter(void* sendbuf, int sendcount,MPI_Datatype sendtype, void* recvbuf,int recvcount,MPI_Datatype recvtype,int root, MPI_Comm comm)sendcount - число элементов, посланных каждомупроцессу, не общее число отосланных элементов;send параметры имеют смысл только для процессаrootAll-to-one передачи: различные данные собираютсяпроцессом rootСбор данных выполняется в порядке номеровпроцессов.Длина блоков предполагается одинаковой, т.е.
данные,посланные процессом i из своего буфера sendbuf,помещаются в i-ю порцию буфера recvbuf процессаroot.Длина массива, в который собираются данные, должнабыть достаточной для их размещения.int MPI_Gather(void* sendbuf, int sendcount,MPI_Datatype sendtype, void* recvbuf, intrecvcount,MPI_Datatype recvtype, int root, MPI_Comm comm)Операции выполняются над данными,распределенными по процессам коммуникатораПримеры:◦ Глобальная сумма или произведение◦ Глобальный максимум (минимум)◦ Глобальная операция, определеннаяпользователемint MPI_Reduce(void* sendbuf, void* recvbuf, intcount, MPI_Datatype datatype, MPI_Op op, int root,MPI_Comm comm)count число операций "op", выполняемых надпоследовательными элементами буфераsendbuf (также размер recvbuf)op является ассоциативной операцией, котораявыполняется над парой операндов типа datatype ивозвращает результат того же типа:MPI_MAX, MPI_MIN, MPI_SUM, MPI_PROD, MPI_LAND,MPI_BAND, MPI_LOR, MPI_BOR, MPI_LXOR, MPI_BXOR,MPI_MAXLOC, MPI_MINLOCMPI_ALLREDUCE - нет root процесса (все получают рез-т)int MPI_Alltoall (void* sendbuf,int sendcount, /* in */MPI_Datatype sendtype, /* in */void* recvbuf, /* out */int recvcount, /* in */MPI_Datatype recvtype, /* in */MPI_Comm comm);Описание: Рассылка сообщений от каждого процесса каждому j-ый блок данных из процесса i принимается j-ымпроцессом и размещается в i-ом блоке буфера recvbuf.