1 / 37

MPI. Терминология и обозначения

MPI. Терминология и обозначения. MPI - message passing interface Процессы объединяются в группы . С каждой группой ассоциирован свой коммуникатор . Два основных атрибута процесса : коммуникатор (группа) и номер процесса в коммуникаторе (группе) .

rico
Download Presentation

MPI. Терминология и обозначения

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. MPI. Терминология и обозначения MPI - message passing interface Процессы объединяются в группы. С каждой группой ассоциирован свой коммуникатор. Два основных атрибута процесса: коммуникатор (группа) и номер процесса в коммуникаторе (группе). Номер процесса - целое неотрицательное число, являющееся уникальным атрибутом каждого процесса от 0 до N-1 (N – число процессоров в группе. Все процессы содержатся в группе с предопределенным идентификатором MPI_COMM_WORLD.

  2. Сообщение- набор данных некоторого типа. Атрибуты сообщения: номер процесса-отправителя, номер процесса-получателя, идентификатор сообщения и др. Идентификатор сообщения (msgtag) - атрибут сообщения, являющийся целым неотрицательным числом, лежащим в диапазоне от 0 до 32767.

  3. Общие процедуры MPI int MPI_Init( int* argc, char*** argv) - инициализация параллельной части приложения. int MPI_Finalize( void ) - завершение параллельной части приложения.

  4. int MPI_Comm_size( MPI_Comm comm, int* size) - определение общего числа параллельных процессов в группе comm. IN comm - идентификатор группы OUT size - размер группы

  5. int MPI_Comm_rank( MPI_comm comm, int* rank) - определение номера процесса в группе comm. Значение, возвращаемое по адресу &rank. IN comm- идентификатор группы OUT rank - номер вызывающего процесса в группе comm

  6. Пример 1. «Привет» #include <stdlib.h> #include "mpi.h" main(int argc, char **argv) { int me, size; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &me); MPI_Comm_size(MPI_COMM_WORLD, &size); printf("Hi, I’m process %d of %d \n", me, size); MPI_Finalize(); }

  7. double MPI_Wtime(void) - функция возвращает астрономическое время в секундах (вещественное число), прошедшее с некоторого момента в прошлом.

  8. int MPI_Get_processor_name(char *name, int *len) • определяет имя процессора, на котором выполняется данная команда. • Также определяет длину имени процессора. Буффер name должен быть как минимум размером в MPI_MAX_PROCESSOR_NAME символов.

  9. int MPI_Send (void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) - функция блокирующей посылки IN buf начальный адрес буфера посылки сообщения (альтернатива) IN count число элементов в буфере посылки (неотрицательное целое) IN datatype тип данных каждого элемента в буфере передачи (дескриптор) IN dest номер процесса-получателя (целое) IN tag тэг сообщения (целое) IN comm коммуникатор (группа)

  10. Типы данных в MPI MPI datatype C datatype MPI_CHAR signed char MPI_INT signed int MPI_LONG signed long int MPI_UNSIGNED_CHAR unsigned char MPI_UNSIGNED_SHORT unsigned short int MPI_UNSIGNED unsigned int MPI_UNSIGNED_LONG unsigned long int MPI_FLOAT float MPI_DOUBLE double MPI_LONG_DOUBLE long double

  11. int MPI_Get_count (MPI_Status *status,MPI_Datatype datatype, int *count) - операция возвращает число полученных элементов IN status статус операции приема (статус ) IN datatype тип данных каждого элемента приемного буфера (дескриптор) OUT count количество полученных единиц (целое)

  12. Модификации функции MPI_SEND: • MPI_BSEND(buf, count, datatype, dest, tag, comm)—передача сообщения с буферизацией. • MPI_SSEND (buf, count, datatype, dest, tag, comm)—передача сообщения с синхронизацией. • MPI_RSEND (buf, count, datatype, dest, tag, comm)—передача сообщения по готовности.

  13. РАСПРЕДЕЛЕНИЕ И ИСПОЛЬЗОВАНИЕ БУФЕРОВ int MPI_Buffer_attach (void* buffer, int size) - описать буфера, используемого для буферизации сообщений, посылаемых в режиме буферизации. IN buffer начальный адрес буфера (альтернатива) IN size размер буфера в байтах (целое) int MPI_Buffer_detach(void* buffer_addr, int * size) - отключенние буфера OUT buffer_addr начальный адрес буфера (альтернатива) OUT size размер буфера в байтах (целое)

  14. int MPI_Recv (void* buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status) - функция блокирующего приема OUT buf начальный адрес буфера процесса-получателя (альтернатива) IN count число элементов в принимаемом сообщении (целое) IN datatype тип данных каждого элемента сообщения (дескриптор) IN source номер процесса-отправителя (целое) IN tag тэг сообщения (целое) IN comm коммуникатор (дескриптор) OUT status параметры принятого сообщения (статус)

  15. Параметры принятого сообщения всегда можно определить по соответствующим элементам структуры STATUS: STATUS.MPI_SOURCE— номер процесса-отправителя. STATUS.MPI_TAG — идентификаторсообщения. STATUS.MPI_ERROR — код ошибки.

  16. Вместо аргументов SOURCEи TAGможно использовать константы: • MPI_ANY_SOURCE— признак того, что подходит сообщение от любого процесса • MPI_ANY_TAG— признак того, что подходит сообщение с любым идентификатором.

  17. Пример 2.1. «Все одному» #include "mpi.h" main (int argc, char **argv) { char message[20]; int myrank, size, i; MPI_Status status; MPI_Init (&argc, &argv); MPI_Comm_rank (MPI_COMM_WORLD, &myrank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (myrank==0) /* code for process zero */ { strcpy (message, "Hello, there"); for (i=1;i<size;i++) MPI_Send(message, strlen(message)+1, MPI_CHAR, i, 99, MPI_COMM_WORLD); } else /* code for process one */ { MPI_Recv (message, 20, MPI_CHAR, 0, 99, MPI_COMM_WORLD, &status); printf ("proc %d received :%s:\n",myrank, message); } MPI_Finalize(); }

  18. Тупиковые ситуации (deadlock): процесс 0: RECV(1) SEND(1) процесс 1: RECV(0) SEND(0) процесс 0: SEND(1) RECV(1) процесс 1: SEND(0) RECV(0)

  19. Разрешение тупиковых ситуаций: 1. процесс 0: SEND(1) RECV(1) процесс 1: RECV(0) SEND(0) 2. Использование неблокирующих операций (MPI_ISEND, MPI_IRECV) 3. Использование функции совмещенного обмена (MPI_SENDRECV)

  20. #include "mpi.h" main(int argc, char **argv) { int me, size, n; int SOME_TAG=0; MPI_Status status; MPI_Init (&argc, &argv); MPI_Comm_rank (MPI_COMM_WORLD, &me); MPI_Comm_size (MPI_COMM_WORLD, &size); if ((me % 2)==0) { /* send unless highest-numbered process */ if ((me+1) < size) { MPI_Send (&me, 1, MPI_INT,me+1,SOME_TAG,MPI_COMM_WORLD); MPI_Recv(&n,1,MPI_INT,me+1,SOME_TAG,MPI_COMM_WORLD,&status); printf("me %d received %d\n",me,n); } } else { MPI_Recv(&n,1,MPI_INT,me-1,SOME_TAG,MPI_COMM_WORLD,&status); MPI_Send (&me, 1, MPI_INT,me-1,SOME_TAG,MPI_COMM_WORLD); printf("me %d received %d\n",me,n); } MPI_Finalize(); } Пример 2.2: Парный обмен

  21. int MPI_Isend (void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request) - функция неблокирующей посылки IN buf начальный адрес буфера посылки (альтернатива) IN count число элементов в буфере посылки (целое) IN datatype тип каждого элемента в буфере посылки (дескриптор) IN dest номер процесса-получателя (целое) IN tag тэг сообщения (целое) IN comm коммуникатор (дескриптор) OUT request запрос обмена (дескриптор)

  22. int MPI_Irecv (void* buf, int count, MPI_Datatype datatype, int source, int tag,MPI_Comm comm, MPI_Request *request) - функция неблокирующего приема IN buf начальный адрес буфера посылки (альтернатива) IN count число элементов в буфере посылки (целое) IN datatype тип каждого элемента в буфере посылки (дескриптор) IN sourceномер процесса-получателя (целое) IN tag тэг сообщения (целое) IN comm коммуникатор (дескриптор) OUT request запрос обмена (дескриптор)

  23. Модификации функции MPI_ISEND: • MPI_IBSEND(buf, count, datatype, dest, tag, comm, request)—передача сообщения с буферизацией. • MPI_ISSEND (buf, count, datatype, dest, tag, comm, request)—передача сообщения с синхронизацией. • MPI_IRSEND (buf, count, datatype, dest, tag, comm, request)—передача сообщения по готовности.

  24. Завершение обмена int MPI_Wait (MPI_Request *request, MPI_Status *status) - заканчивается, когда завершена операция, указанная в запросе. INOUT request запрос (дескриптор) OUT status объект состояния (статус) int MPI_Test (MPI_Request *request, int *flag, MPI_Status *status)- возвращает flag = true, если операция, указанная в запросе, завершена. INOUT request коммуникационный запрос (дескриптор) OUT flag true, если операция завершена (логический тип) OUT status статусный объект (статус)

  25. Множественные завершения int MPI_Waitall (int count, MPI_Request *array_of_requests, MPI_Status *array_of_statuses)- блокирует работу, пока все операции обмена, связанные с активными дескрипторами в списке, не завершатся, и возвращает статус всех операций. IN count длина списков (целое) INOUT array_of_requests массив запросов (массив дескрипторов) OUT array_of_statuses массив статусных объектов (массив статусов) int MPI_Testall(int count, MPI_Request *array_of_requests, int *flag, MPI_Status *array_of_statuses) - возвращает flag=true, если обмены, связанные с активными дескрипторами в массиве, завершены. IN count длина списка (целое) INOUT array_of_requests массив запросов (массив дескрипторов) OUT flag (логический тип) OUT array_of_statuses массив статусных объектов(массив статусов)

  26. Int MPI_Waitany (int count, MPI_Request *array_of_requests, int *index, MPI_Status *status)- блокирует работу до тех пор, пока не завершится одна из операций из массива активных запросов. Если более чем одна операция задействована и может закончиться, выполняется произвольный выбор. IN count длина списка (целое) INOUT array_of_requests массив запросов (массив дескрипторов) OUT index индекс дескриптора для завершенной операции (целое) OUT status статусный объект (статус) int MPI_Testany (int count, MPI_Request *array_of_requests, int *index, int *flag, MPI_Status *status) - тестирует завершение либо одной либо никакой из операций, связанных с активными дескрипторами. IN count длина списка (целое) INOUT array_of_requests массив запросов (массив дескрипторов) OUT index индекс дескриптора для завершенной операции (целое) OUT flag true, если одна из операций завершена (логический тип) OUT status статусный объект (статус)

  27. int MPI_Waitsome (int incount, MPI_Request *array_of_requests, int *outcount, int *array_of_indices, MPI_Status *array_of_statuses) - ожидает, пока, по крайней мере, одна операция, связанная с активным дескриптором в списке, не завершится. IN incount длина массива запросов (целое) INOUT array_of_requests массив запросов (массив дескрипторов) OUT outcount число завершенных запросов (целое) OUT array_of_indices массив индексов операций, которые завершены (массив целых) OUT array_of_statuses массив статусных операций для завершенных операций (массив статусов) int MPI_Testsome (int incount, MPI_Request *array_of_requests, int *outcount, int *array_of_indices, MPI_Status *array_of_statuses) - ведет себя подобно MPI_WAITSOMEза исключением того, что заканчивается немедленно. IN incount длина массива запросов (целое) IN OUT array_of_requests массив запросов (массив дескрипторов) OUT outcount число завершенных запросов (целое) OUT array_of_indices массив индексов завершенных операций (массив целых) OUT array_of_statuses массив статусных объектов завершенных операций (массив статусов)

  28. MPI_SUCCESS- удачное завершение обменов MPI_ERR_IN_STATUS - неудачное завершение обменов, устанавливается специфический код ошибки в поля ошибки каждого статуса. MPI_ERR_PENDING– обмен не завершен, но и не в состоянии отказа MPI_REQUEST_NULL – значение дескриптора (по завершении обмена он удаляется), если запрос был размещен вызовом неблокирующего обмена outcount = MPI_UNDEFINED - если не имеется активных дескрипторов в списке

  29. Пример 3: Обмен по кольцу без блокировки #include "mpi.h" #include <stdio.h> main(int argc, char **argv){ int numtasks, rank, next, prev, buf[2], tag1=1, tag2=2; MPI_Request reqs[4]; MPI_Status stats[4]; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD, &numtasks); MPI_Comm_rank(MPI_COMM_WORLD, &rank); prev = rank - 1; next = rank + 1; if (rank == 0) prev = numtasks - 1; if (rank == (numtasks - 1)) next = 0; MPI_Irecv(&buf[0], 1, MPI_INT, prev, tag1, MPI_COMM_WORLD,&reqs[0]); MPI_Irecv(&buf[1], 1, MPI_INT, next, tag2, MPI_COMM_WORLD,&reqs[1]); MPI_Isend(&rank, 1, MPI_INT, prev, tag2, MPI_COMM_WORLD,&reqs[2]); MPI_Isend(&rank, 1, MPI_INT, next, tag1, MPI_COMM_WORLD,&reqs[3]); MPI_Waitall(4, reqs, stats); printf("me %d recv %d %d\n",rank,buf[0],buf[1]); MPI_Finalize(); }

  30. ПРОБА И ОТМЕНА int MPI_Iprobe(int source, int tag, MPI_Comm comm, int *flag, MPI_Status *status) - возвращает flag = true, если имеется сообщение, которое может быть получено и которое соответствует образцу, описанному аргументами source, tag, и comm. IN source номер процесса-отправителя или MPI_ANY_SOURCE (целое) IN tag значение тэга или MPI_ANY_TAG (целое) IN comm коммуникатор (дескриптор) OUT flag (логическое значение) OUT status статус (статус) int MPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status *status) –блокирующий аналогMPI_Iprobe IN source номер источника или MPI_ANY_SOURCE (целое) IN tag значение тэга или MPI_ANY_TAG (целое) IN comm коммуникатор (дескриптор) OUT status статус (статус)

  31. int MPI_Cancel(MPI_Request *request) - маркирует для отмены ждущие неблокирующие операции обмена (передача или прием). IN request коммуникационный запрос (дескриптор) После маркировки необходимо завершить эту операцию обмена, используя вызов MPI_WAIT или MPI_TEST (или любые производные операции). int MPI_Test_cancelled(MPI_Status *status, int *flag) - возвращает flag = true, если обмен, связанный со статусным объектом, был отменен успешно. IN status статус (Status) OUT flag (логический тип )

  32. int MPI_Sendrecv(void*sendbuf, int sendcount, MPI_Datatype sendtype, int dest,int sendtag, void *recvbuf, int recvcount, MPI_Datatype recvtype, int source,MPI_Datatype recvtag, MPI_Comm comm, MPI_Status *status) – функция совмещенного приема передачи (с блокировкой) IN sendbuf начальный адрес буфера отправителя (альтернатива) IN sendcount число элементов в буфере отправителя (целое) IN sendtype тип элементов в буфере отправителя (дескриптор) IN dest номер процесса-получателя (целое) IN sendtag тэг процесса-отправителя (целое) OUT recvbuf начальный адрес приемного буфера (альтернатива) IN recvcount число элементов в приемном буфере (целое) IN recvtype тип элементов в приемном буфере (дескриптор) IN source номер процесса-отправителя (целое) IN recvtag тэг процесса-получателя (целое) IN comm коммуникатор (дескриптор) OUT status статус (статус)

  33. int MPI_Sendrecv_replace(void* buf,int count, MPI_Datatype datatype, int dest, int sendtag, int source, int recvtag, MPI_Comm comm, MPI_Status *status) - функция приема передачи с совмещенным буфером (с блокировкой) INOUT buf начальный адрес буфера отправителя и получателя (альтернатива) IN count число элементов в буфере отправителя и получателя (целое) IN datatype тип элементов в буфере отправителя и получателя (дескриптор) IN dest номер процесса-получателя (целое) IN sendtag тэг процесса-отправителя (целое) IN source номер процесса-отправителя (целое) IN recvtag тэг процесса-получателя (целое) IN comm коммуникатор (дескриптор) OUT status статус (статус)

  34. Объединение запросов на взаимодействие int MPI_Send_init( void *buf, int count, MPI_Datatype datatype, int dest, int msgtag, MPI_Comm comm, MPI_Request *request)- формирование запроса на выполнение пересылки данных INbuf - адрес начала буфера посылки сообщения INcount - число передаваемых элементов в сообщении INdatatype - тип передаваемых элементов INdest - номер процесса-получателя INmsgtag - идентификатор сообщения INcomm - идентификатор группы OUT request - идентификатор асинхронной передачи int MPI_Recv_init( void *buf, int count, MPI_Datatype datatype, int source, int msgtag, MPI_Comm comm, MPI_Request *request)- формирование запроса на выполнение приема данных

  35. MPI_Startall( int count, MPI_Request *requests) • запуск всех отложенных взаимодействий, ассоциированных с элементами массива запросовrequests. • IN count - число запросов на взаимодействие • OUT requests - массив идентификаторов приема/передачи • MPI_Start(MPI_Request *requests)

  36. Пример 4. Вычисление числа  где #include "mpi.h" #include <math.h> main ( int argc, char **argv ) { int n=0, myid, numprocs, i; double mypi, pi, h, sum, x, t1, t2, PI25DT = 3.141592653589793238462643; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &numprocs); MPI_Comm_rank(MPI_COMM_WORLD,&myid); if (myid == 0) t1 = MPI_Wtime(); if (argc>1) n=atoi(argv[1]); else { printf("number of points is needed\n"); return; }

  37. h = 1.0/ (double) n; sum = 0.0; for (i = myid +1; i <= n; i+= numprocs) { x = h * ( (double)i - 0.5); sum += (4.0 / (1.0 + x*x)); } mypi = h * sum; // Cуммирования mypi со всех процессоров в переменную pi MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); if (myid == 0) { t2 = MPI_Wtime(); printf ("pi is approximately %.16f. Error is %.16f\n",pi, fabs(pi - PI25DT)); printf ("'time is %f seconds \n", t2-t1); } MPI_Finalize(); }

More Related