Главная страница

Программирование для многопроцессорных систем в стандарте MPI - Шпаковский Г.И., Серикова Н.В.. Программирование для многопроцессорных систем в стандарте MPI -. Организация вычислений в многопроцессорных системах


Скачать 1.61 Mb.
НазваниеОрганизация вычислений в многопроцессорных системах
АнкорПрограммирование для многопроцессорных систем в стандарте MPI - Шпаковский Г.И., Серикова Н.В..pdf
Дата15.03.2018
Размер1.61 Mb.
Формат файлаpdf
Имя файлаПрограммирование для многопроцессорных систем в стандарте MPI - .pdf
ТипКонтрольные вопросы
#16702
КатегорияИнформатика. Вычислительная техника
страница22 из 26
1   ...   18   19   20   21   22   23   24   25   26
Пример 4. Решение системы линейных уравнений
Следующий пример иллюстрирует параллельное решение систе- мы линейных уравнений с помощью SLES. Пользовательский интер- фейс для инициации программы, создания векторов и матриц и реше- ния линейной системы является тем же для однопроцессорного и мно- гопроцессорного примеров. Главное различие состоит в том, что каж- дый процесс формирует локальную часть матрицы и вектора в па- раллельном случае. static char help[] = "Solves a linear system in parallel with SLES.\n\
Input parameters include:\n\
-random_exact_sol : use a random exact solution vector\n\
-view_exact_sol : write exact solution vector to stdout\n\
-m : number of mesh points in x-direction\n\
-n : number of mesh points in y-direction\n\n";
#include "petscsles.h" int main(int argc,char **args)
{
Vec x,b,u; /* приближенное решение, RHS, точное решение */
Mat A; /* матрица линейной системы */
SLES sles; /* метод решения линейной системы */
PetscRandom rctx; /* генератор случайных чисел */ double norm; /* норма ошибки решения */ int i,j,I,J,Istart,Iend,ierr,m = 8,n = 7,its;
PetscTruth flg;
Scalar v,one = 1.0,neg_one = -1.0;
KSP ksp;
PetscInitialize(&argc,&args,(char *)0,help); ierr = PetscOptionsGetInt(PETSC_NULL,"-",&m,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-",&n,PETSC_NULL);CHKERRQ(ierr);
/* Организуем матрицу и правосторонний вектор, который определяет линейную систему, Ax = b. Создаем параллельную матрицу, описывая только ее глобальные размеры. Когда используется MatCreate(), формат матрицы может быть описан на этапе исполнения. */ ierr=MatCreate(PETSC_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, m*n,m*n,&A); CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr);
/* Матрица разделена крупными кусками строк по процессам. Определяем, какие строки матрицы размещены локально.*/ ierr = MatGetOwnershipRange(A,&Istart,&Iend);CHKERRQ(ierr);

266
/* Размещаем матричные элементы. Каждому процессу нужно разместить только те элементы, которые принадлежат ему локально (все нелокальные элементы бу- дут посланы в соответствующий процессор во время сборки матрицы). */ for (I=Istart; I{ v = -1.0; i = I/n; j = I – i*n; if (i>0)
{ J = I – n; ierr = MatSetValues(A,1,&I,1,&J,&v,INSERT_VALUES);
CHKERRQ(ierr);
} if (i { J = I + n; ierr = MatSetValues(A,1,&I,1,&J,&v,INSERT_VALUES);
CHKERRQ(ierr);
} if (j>0)
{ J = I – 1; ierr = MatSetValues(A,1,&I,1,&J,&v,INSERT_VALUES);
CHKERRQ(ierr);
} if (j { J = I + 1; ierr = MatSetValues(A,1,&I,1,&J,&v,INSERT_VALUES);
CHKERRQ(ierr);
} v = 4.0; ierr = MatSetValues(A,1,&I,1,&I,&v,INSERT_VALUES);
CHKERRQ(ierr);
} ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
/* Создаем параллельные векторы. Формируем вектор и затем дублируем, если необходимо.
Когда в этом примере используется VecCreate() и
VecSetFromOptions(), указывается только глобальный размер вектора; парал- лельное разбиение определяется на этапе исполнения. Когда решается линейная система, векторы и матрицы обязаны быть разбиты соответственно. PETSc авто- матически генерирует соответствующее разбиение матриц и векторов, когда
MatCreate() и VecCreate() используются с тем же самым коммуникатором. Поль- зователь может альтернативно описать размеры локальных векторов и матриц, когда необходимо более сложное разбиение (путем замещения аргумента
PETSC_DECIDE в VecCreate()). */ ierr = VecCreate(PETSC_COMM_WORLD,PETSC_DECIDE,m*n,&u);
CHKERRQ(ierr);

267
ierr = VecSetFromOptions(u);CHKERRQ(ierr); ierr = VecDuplicate(u,&b);CHKERRQ(ierr); ierr = VecDuplicate(b,&x);CHKERRQ(ierr);
/* Установим точное решение, затем вычислим правосторонний вектор. По умол- чанию используем точное решение вектора для случая, когда все элементы вектора равны единице. Альтернативно, используя опцию – random_sol, фор- мируем решение вектора со случайными компонентами. */ ierr = PetscOptionsHasName(PETSC_NULL,"-random_exact_sol",&flg);
CHKERRQ(ierr); if (flg)
{ ierr = PetscRandomCreate(PETSC_COMM_WORLD,RANDOM_DEFAULT,&rctx);
CHKERRQ(ierr); ierr = VecSetRandom(rctx,u);CHKERRQ(ierr); ierr = PetscRandomDestroy(rctx);CHKERRQ(ierr);
} else ierr = VecSet(&one,u);CHKERRQ(ierr); ierr = MatMult(A,u,b);CHKERRQ(ierr);
/* Выводим точное решение вектора, если необходимо */ ierr = PetscOptionsHasName(PETSC_NULL,"-view_exact_sol",&flg);
CHKERRQ(ierr); if (flg)
{ ierr = VecView(u,PETSC_VIEWER_STDOUT_WORLD);
CHKERRQ(ierr);
}
/* Создаем метод решения системы линейных уравнений */ ierr = SLESCreate(PETSC_COMM_WORLD,&sles);CHKERRQ(ierr);
/* Устанавливаем операторы. Здесь матрица, которая определяет линейную систему, служит как preconditioning матрица. */ ierr = SLESSetOperators(sles,A,A,DIFFERENT_NONZERO_PATTERN);
CHKERRQ(ierr);
/* Устанавливается метод решения */ ierr = SLESGetKSP(sles,&ksp);CHKERRQ(ierr); ierr = KSPSetTolerances(ksp,1.e-2/((m+1)*(n+1)),1.e-50,
PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); ierr = SLESSetFromOptions(sles);CHKERRQ(ierr);
/* Решается линейная система */ ierr = SLESSolve(sles,b,x,&its);CHKERRQ(ierr);
/* Проверяется решение norm *= sqrt(1.0/((m+1)*(n+1))); */ ierr = VecAXPY(&neg_one,u,x);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr);
/* Печатается информация о сходимости. PetscPrintf() создает одно предложение печати из всех процессов, которые разделяют коммуникатор. Альтернативой яв- ляется PetscFPrintf(), которая печатает в файл. */

268
ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of error %A iterations d\n", norm,its); CHKERRQ(ierr);
/* Освобождается рабочее пространство. Все PETSc объекты должны быть разру- шены, когда они больше не нужны. */ ierr = SLESDestroy(sles);CHKERRQ(ierr);ierr = VecDestroy(u);CHKERRQ(ierr); ierr = VecDestroy(x);CHKERRQ(ierr);ierr = VecDestroy(b);CHKERRQ(ierr); ierr = MatDestroy(A);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0;
}
КОНТРОЛЬНЫЕ ВОПРОСЫ К ГЛАВЕ 13
Контрольные вопросы к 13.1
1. Для чего предназначена библиотека ScaLAPACK?
2. Для чего предназначена библиотека PETSc?
3. Опишите уровень операций в библиотеки BLAS?
4. Для чего предназначена библиотека BLAS?
5. Для чего предназначена библиотека LAPACK?
6. Каково назначение библиотеки BLAСS?
7. Объясните назначение параметров функции vTRSD2D.
8. Какие четыре шага надо сделать, чтобы выполнить программу ScaLAPACK?
9. Опишите каждый из этих четырех шагов.
10. Объясните на примере программы умножения матриц особенности работы библиотеки ScaLAPACK.
Контрольные вопросы к 13.2
1. Какие задачи позволяет решать библиотека PETSc?
2. Нужно ли вызывать MPI_Init при написании PETSc программы?
3. В каком случае необходимо создание коммуникатора и как это сделать?
4. Какие типы векторов существуют в библиотеке? Как создать вектор того или иного типа?
5. В каком случае нужно создавать параллельные векторы?
6. Можно ли распределить компоненты параллельного вектора по процессам не равными частями?
7. Как определить номера строк в локальном процессе при создании параллель- ной матрицы?
8. Какие матричные операции библиотеки можно использовать для параллель- ного решения задачи умножения матрицы на матрицу?
9. Необходим ли MPICH для инсталляции PETSc?
10. Как выполнить PETSc-программу на 4 процессах, задавая различные размер- ности задачи?

269
ПРИЛОЖЕНИЯ
Приложение 1. КОНСТАНТЫ ДЛЯ ЯЗЫКОВ С И FORTRAN
Здесь приведены константы, определенные в файлах mpi.h (для C) и mpif.h
(для языка Fortran).
/* возвращаемые коды (как для C, так и для Fortran) */
MPI_SUCCESS
MPI_ERR_BUFFER
MPI_ERR_COUNT
MPI_ERR_TYPE
MPI_ERR_TAG
MPI_ERR_COMM
MPI_ERR_RANK
MPI_ERR_REQUEST
MPI_ERR_ROOT
MPI_ERR_GROUP
MPI_ERR_OP
MPI_ERR_TOPOLOGY
MPI_ERR_DIMS
MPI_ERR_ARG
MPI_ERR_UNKNOWN
MPI_ERR_TRUNCATE
MPI_ERR_OTHER
MPI_ERR_INTERN
MPI_ERR
_
PENDING
MPI_ERR_IN_STATUS
MPI_ERR_LASTCODE
/* константы (как для C, так и для Fortran) */
MPI_BOTTOM
MPI_PROC_NULL
MPI_ANY_SOURCE
MPI_ANY_TAG
MPI_UNDEFINED
MPI_BSEND_OVERHEAD
MPI_KEYVAL_INVALID
/* размер статуса и резервируемые индексные значения (Fortran) */
MPI_STATUS_SIZE
MPI_SOURCE
MPI_TAG
MPI_ERROR
/* описатели обработчика ошибок (C и Fortran) */
MPI_ERRORS_ARE_FATAL
MPI_ERRORS_RETURN

270
/* максимальные размеры строк */
MPI_MAX_PROCESSOR_NAME
MPI_MAX_ERROR_STRING
/* элементарные типы данных (C) */
MPI_CHAR
MPI_SHORT
MPI_INT
MPI_LONG
MPI_UNSIGNED_CHAR
MPI_UNSIGNED_SHORT
MPI_UNSIGNED
MPI_UNSIGNED_LONG
MPI_FLOAT
MPI_DOUBLE
MPI_LONG_DOUBLE
MPI_BYTE
MPI_PACKED
/* элементарные типы данных(Fortran) */
MPI_INTEGER
MPI_REAL
MPI_DOUBLE_PRECISION
MPI_COMPLEX
MPI_LOGICAL
MPI_CHARACTER
MPI_BYTE
MPI_PACKED
/* типы данных для функций редукции (C) */
MPI_FLOAT_INT
MPI_DOUBLE_INT
MPI_LONG_INT
MPI_2INT
MPI_SHORT_INT
MPI_LONG_DOUBLE_INT
/* типы данных для функций редукции (Fortran) */
MPI_2REAL
MPI_2DOUBLE_PRECISION
MPI_2INTEGER
/* дополнительные типы данных (Fortran) */
MPI_INTEGER1
MPI_INTEGER2
MPI_INTEGER4
MPI_REAL2
MPI_REAL4
MPI_REAL8 etc.

271
/* дополнительные типы данных (C) */
MPI_LONG_LONG_INT etc.
/*специальные типы данных для создания производных типов данных */
MPI_UB
MPI_LB
/* зарезервированные коммуникаторы (C и Fortran) */
MPI_COMM_WORLD
MPI_COMM_SELF
/* результаты сравнения коммуникаторов и групп */
MPI_IDENT
MPI_CONGRUENT
MPI_SIMILAR
MPI_UNEQUAL
/* ключи запроса среды (C и Fortran) */
MPI_TAG_UB
MPI_IO
MPI_HOST
MPI_WTIME_IS_GLOBAL
/* коллективные операции (C и Fortran) */
MPI_MAX
MPI_MIN
MPI_SUM
MPI_PROD
MPI_MAXLOC
MPI_MINLOC
MPI_BAND
MPI_BOR
MPI_BXOR
MPI_LAND
MPI_LOR
MPI_LXOR
/* нулевые дескрипторы */
MPI_GROUP_NULL
MPI_COMM_NULL
MPI_DATATYPE_NULL
MPI_REQUEST_NULL
MPI_OP_NULL
MPI_ERRHANDLER_NULL
/* пустая группа */
MPI_GROUP_EMPTY
/* топологии (C и Fortran) */
MPI_GRAPH
MPI_CART
/* предопределенные функции в C и Fortrun*/
MPI_NULL_COPY_FN

272
MPI_NULL_DELETE_FN
MPI_DUP_FN
Следующее есть типы С, также включенные в файл mpi.h.
/* скрытые типы */
MPI_Aint
MPI_Status
/* дескрипторы различных структур */
MPI_Group
MPI_Comm
MPI_Datatype
MPI_Request
MPI_Op
MPI_Errhandler
Приложение 2. ПЕРЕЧЕНЬ ФУНКЦИЙ MPI-1.1
1. MPI_ABORT ( comm, errorcode )
Прекращает выполнение операций
2. MPI_ADDRESS (location, address)
Получает адрес в ячейке памяти
3. MPI_ALLGATHER ( sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm)
Собирает данные от всех процессов и распределяет их всем процессам
4. MPI_ALLGATHERV ( sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm)
Собирает данные от всех процессов и поставляет их всем процессам
5. MPI_ALLREDUCE ( sendbuf, recvbuf, count, datatype, op, comm)
Выполняет глобальную операцию над данными от всех процессов и результат
посылает обратно всем процессам
6. MPI_ALLTOALL (sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm)
Посылает данные от всех процессов всем процессам
7. MPI_ALLTOALLV (sendbuf, sendcounts, sdispls, sendtype, recvbuf, recvcounts, rdispls, recvtype, comm)
Посылает данные от всех процессов всем процессам со смещением
8. MPI_BARRIER ( comm )
Блокирует дальнейшее исполнение, пока все процессы не достигнут этой
функции
9. MPI_BCAST( buffer, count, datatype, root, comm )
Широковещательная рассылка сообщения от одного процесса всем
10. MPI_BSEND (buf, count, datatype, dest, tag, comm)
Операция посылки сообщения с определенным пользователем буфером
11. MPI_BSEND_INIT (buf, count, datatype, dest, tag, comm, request)
Создает дескриптор для буферизованной посылки

273 12. MPI_BUFFER_ATTACH ( buffer, size)
Создает определяемый пользователем буфер для посылки
13. MPI_BUFFER_DETACH ( buffer_addr, size)
Удаляет существующий буфер
14. MPI_CANCEL (request)
Отменяет коммуникационный запрос
15. MPI_CART_COORDS (comm, rank, maxdims, coords)
Определяет координаты процесса в картезианской топологии в соответст-
вии с его номером
16. MPI_CART_CREATE (comm_old, ndims, dims, periods, reorder, comm_cart)
Создает новый коммуникатор по заданной топологической информации
17. MPI_CART_GET (comm, maxdims, dims, periods, coords)
Получает связанную с коммуникатором информацию о картезианской топо-
логии
18. MPI_CART_MAP (comm, ndims, dims, periods, newrank)
Отображает процесс в соответствии с топологической информацией
19. MPI_CART_RANK (comm, coords, rank)
Определяет номер процесса в коммуникаторе с картезианской топологией
20. MPI_CART_SHIFT (comm, direction, disp, rank_source, rank_dest)
Возвращает новые номера процессов отправителя и получателя после сдвига
в заданном направлении
21. MPI_CART_SUB (comm, remain_dims, newcomm)
Разделяет коммуникатор на подгруппы, которые формируют картезианские
решетки меньшей размерности
22. MPI_CARTDIM_GET (comm, ndims)
Получает информацию о связанной с коммуникатором картезианской топо-
логии
23. MPI_COMM_COMPARE (comm1, comm2, result)
Сравнивает два коммуникатора
24. MPI_COMM_CREATE (comm, group, newcomm)
Создает новый коммуникатор
25. MPI_COMM_DUP (comm, newcomm)
Создает новый коммуникатор путем дублирования существующего со всеми
его параметрами
26. MPI_COMM_FREE (comm)
Маркирует коммуникатор для удаления
27. MPI_COMM_GROUP (comm, group)
Осуществляет доступ к группе, связанной с данным коммуникатором
28. MPI_COMM_RANK (comm, rank)
Определяет номер процесса в коммуникаторе
29. MPI_COMM_SIZE (comm, size)
Определяет размер связанной с коммуникатором группы
30. MPI_COMM_SPLIT (comm, color, key, newcomm)
Создает новый коммуникатор на основе признаков и ключей
31. MPI_DIMS_CREATE (nnodes, ndims, dims)
Распределяет процессы по размерностям

274 32. MPI_FINALIZE ( )
Завершает выполнение программы MPI
33. MPI_ GATHER ( sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm)
Собирает в один процесс данные от группы процессов
34. MPI_GATHERV ( sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, root, comm)
Векторный вариант функции GATHER
35. MPI_GET_COUNT (status, datatype, count)
Получает номер старших элементов
36. MPI_GET_ELEMENTS ( status, datatype, count)
Возвращает номер базового элемента в типе данных
37. MPI_GET_PROCESSOR_NAME ( name, resultlen )
Получает номер процессора
38. MPI_GET_VERSION (version, subversion)
Возвращает версию MPI
39. MPI_GRAPH_CREATE (comm_old, nnodes, index, edges, reorder, comm_graph)
Создает новый коммуникатор согласно топологической информации
40. MPI_GRAPH_GET(comm, maxindex, maxedges, index, edges)
Получает информацию о связанной с коммуникатором графовой топологии.
41. MPI_GRAPH_MAP (comm, nnodes, index, edges, newrank)
Размещает процесс согласно информации о топологии графа
42. MPI_GRAPH_NEIGHBORS_COUNT(comm, rank, nneighbors)
Возвращает число соседей узла в графовой топологии
43. MPI_GRAPH_NEIGHBORS (comm, rank, maxneighbors, neighbors)
Возвращает соседей узла в графовой топологии
44. MPI_GRAPHDIMS_GET (comm, nnodes, nedges)
Получает информацию о связанной с коммуникатором топологии
45. MPI_GROUP_COMPARE (group1, group2, result)
Сравнивает две группы
46. MPI_GROUP_DIFFERENCE (group1, group2, newgroup)
Создает группу по разности двух групп
47. MPI_GROUP_EXCL (group, n, ranks, newgroup)
Создает группу путем переупорядочивания существующей группы и отбора
только тех элементов, которые не указаны в списке
48. MPI_GROUP_FREE (group)
Освобождает группу
49. MPI_GROUP_INCL (group, n, ranks, newgroup)
Создает группу путем переупорядочивания существующей группы и отбора
только тех элементов, которые указаны в списке
50. MPI_GROUP_INTERSECTION (group1, group2, newgroup)
Создает группу на основе пересечения двух групп
51. MPI_GROUP_RANGE_EXCL (group, n, ranges, newgroup)
Создает группу путем исключения ряда процессов из существующей группы
52. MPI_GROUP_RANGE_INCL (group, n, ranges, newgroup)
Создает новую группу из ряда номеров существующей группы

275 53. MPI_GROUP_RANK (group, rank)
Возвращает номер процесса в данной группе
54. MPI_GROUP_SIZE (group, size)
Возвращает размер группы
55. MPI_GROUP_TRANSLATE_RANKS (group1, n, ranks1, group2, ranks2)
Переводит номер процесса в одной группе в номер в другой группе
56. MPI_GROUP_UNION(group1, group2, newgroup)
Создает новую группу путем объединения двух групп
57.
1   ...   18   19   20   21   22   23   24   25   26


написать администратору сайта