| |
Конструктор распределенного массива поддерживает распределения данных, сходные с HPF[12]. Кроме этого, в отличие от HPF, порядок хранения может быть задан как для массивов Си, так и для ФОРТРАНА.
Совет пользователям: Вы можете создать HPF-подобный образ файла, используя этот конструктор типа описанным образом. Дополнительные типы файлов создаются групповым вызовом каждым процессом с идентичными аргументами (за исключением ранга, который должен быть установлен соответствующим образом). Эти типы файлов (с идентичными disp и etype) используются затем для определения отображения файла (через MPI_FILE_SET_VIEW). Используя это отображение, совместная операция доступа к данным (с идентичными смещениями) даст HPF-подобный шаблон распределения. []
MPI_TYPE_CREATE_DARRAY(size, rank, ndims, array_of_gsizes,
array_of_distribs, array_of_dargs,
array_of_psizes, order, oldtype, newtype)
IN | size | размер группы процессов (положительное целое) | |
IN | rank | ранг в группе процессов (неотрицательное целое) | |
IN | ndims | число измерений масива и размеры сетки процессов (положительное целое) | |
IN | array_of_gsizes | число элементов типа oldtype в каждом измерении глобального массива (массив положительных целых) | |
IN | array_of_distribs | распределение массива в каждом измерении (массив состояний) | |
IN | array_of_dargs | аргумент распределения в каждом измерении (массив положительных целых) | |
IN | array_of_psizes | размер сетки процессов в каждом измерении (массив положительных целых) | |
IN | order | порядок зранения массива (состояние) | |
IN | oldtype | старый тип данных (дескриптор) | |
OUT | newtype | новый тип данных (дескриптор) |
int MPI_Type_create_darray(int size, int rank, int ndims, int array_of_gsizes[], int array_of_distribs[], int array_of_dargs[], int array_of_psizes[], int order, MPI_Datatype oldtype, MPI_Datatype *newtype) MPI_TYPE_CREATE_DARRAY(SIZE, RANK, NDIMS, ARRAY_OF_GSIZES, ARRAY_OF_DISTRIBS, ARRAY_OF_DARGS, ARRAY_OF_PSIZES, ORDER, OLDTYPE, NEWTYPE, IERROR) INTEGER SIZE, RANK, NDIMS, ARRAY_OF_GSIZES(*), ARRAY_OF_DISTRIBS(*), ARRAY_OF_DARGS(*), ARRAY_OF_PSIZES(*), ORDER, OLDTYPE, NEWTYPE, IERROR MPI::Datatype MPI::Datatype::Create_darray(int size, int rank, int ndims, const int array_of_gsizes[], const int array_of_distribs[], const int array_of_dargs[], const int array_of_psizes[], int order) const
MPI_TYPE_CREATE_DARRAY может быть использована для создания типов данных, соответствующих распределению ndims-мерного массива элементов типа oldtype в ndims-мерную сетку логических процессов. Неиспользуемые измерения array_of_psizes должны быть установлены в 1. (См. пример Distributed Array Datatype Constructor .) Чтобы вызов MPI_TYPE_CREATE_DARRAY был корректным, должно выполняться условие . Порядок процессов в сетке процессов считается с главной строкой, как и в случае топологий виртуальных Cartesian процессов в MPI-1.
Совет пользователям: Для массивов и ФОРТРАНА и Си, порядок процессов считается построчно. Это соответствует порядку, используемому в случае виртуальных декартовых процессов в MPI-1. Для создания таких виртуальных топологий процессов или для нахождения координат процесса в сетке процессов и т.д., пользователи могут использовать соответствующие функции из MPI-1. []
Каждое измерение в массиве может распределяться одним из трех способов:
Константа MPI_DISTRIBUTE_DFLT_DARG определяет аргумент распределения по умолчанию. Аргумент не распределенного измерения игнорируется. Для любого измеренияi, в котором распределение равно MPI_DISTRIBUTE_BLOCK, ошибочно определять array_of_dargs[i] * array_of_psizes[i] < array_of_gsizes[i].
Например, вид HPF ARRAY(CYCLIC(15)) соответствует MPI_DISTRIBUTE_CYCLIC с аргументом 15, а вид HPF ARRAY(BLOCK)
соответствует MPI_DISTRIBUTE_BLOCK с агрументом распределения
MPI_DISTRIBUTE_DFLT_DARG.
Аргумент order используется как и в MPI_TYPE_CREATE_SUBARRAY для определения порядка размещения. Поэтому, массивы, описанные этим конструктором типа могут быть сохранены в порядке ФОРТРАНА (по колонкам) или Си (построчно). Допустимые значения для order - MPI_ORDER_FORTRAN и MPI_ORDER_C.
Эта функция создает новый тип данных MPI с картой типа, определенной в терминах функции ``cyclic()'' (см. ниже).
Без потери общности достаточно определить карту типа для случая MPI_DISTRIBUTE_CYCLIC, где не используется MPI_DISTRIBUTE_DFLT_DARG.
MPI_DISTRIBUTE_BLOCK и MPI_DISTRIBUTE_NONE могут быть
сокращены до случая
MPI_DISTRIBUTE_CYCLIC для измерения i следующим образом.
MPI_DISTRIBUTE_BLOCK с array_of_dargs[i] равным MPI_DISTRIBUTE_DFLT_DARG эквивалентен
MPI_DISTRIBUTE_CYCLIC с array_of_dargs[i] установленным в
(mpiargarray_of_gsizes[i] + mpiargarray_of_psizes[i] - 1) / mpiargarray_of_psizes[i].
Если array_of_dargs[i] - не MPI_DISTRIBUTE_DFLT_DARG, то MPI_DISTRIBUTE_BLOCK и
MPI_DISTRIBUTE_CYCLIC эквивалентны.
MPI_DISTRIBUTE_NONE эквивалентен MPI_DISTRIBUTE_CYCLIC с array_of_dargs[i] установленным в array_of_gsizes[i].
И, в конце концов, MPI_DISTRIBUTE_CYCLIC с array_of_dargs[i] равным MPI_DISTRIBUTE_DFLT_DARG эквивалентен MPI_DISTRIBUTE_CYCLIC с array_of_dargs[i] установленным в 1.
Для MPI_ORDER_FORTRAN, ndims-мерный распределенный массив (newtype) определяется следущим фрагментом кода:
oldtype[0] = oldtype; for ( i = 0; i < ndims; i++ ) { oldtype[i+1] = cyclic(array_of_dargs[i], array_of_gsizes[i], r[i], array_of_psizes[i], oldtype[i]); } newtype = oldtype[ndims];
Код для MPI_ORDER_C:
oldtype[0] = oldtype; for ( i = 0; i < ndims; i++ ) { oldtype[i + 1] = cyclic(array_of_dargs[ndims - i - 1], array_of_gsizes[ndims - i - 1], r[ndims - i - 1], array_of_psizes[ndims - i - 1], oldtype[i]); } newtype = oldtype[ndims];
где r[i] - позиция процесса (с рангом rank) в сетке процессов на измерении i. Значения r[i] даны следующим фрагментом кода:
t_rank = rank; t_size = 1; for (i = 0; i < ndims; i++) t_size *= array_of_psizes[i]; for (i = 0; i < ndims; i++) { t_size = t_size / array_of_psizes[i]; r[i] = t_rank / t_size; t_rank = t_rank % t_size; }
Пусть карта типа oldtype имеет форму
где - стандартный тип MPI, и пусть ex будет длиной oldtype.
С учетом вышеуказанного, функция cyclic() определяется так:
cyclic(darg,gsize,r,psize,oldtype)
= {(MPI_LB,0),
...
...
...
...
...
(MPI_UB,gsize*ex)}
где count определяется следущим фрагментом кода:
nblocks = (gsize + (darg - 1)) / darg; count = nblocks / psize; left_over = nblocks - count * psize; if (r < left_over) count = count + 1;
Здесь nblocks - число блоков, которые должны быть распределены между процессорами. И, в конце концов, определяется следующим фрагментом:
if ((num_in_last_cyclic = gsize % (psize * darg)) == 0) darg_last = darg; else darg_last = num_in_last_cyclic - darg * r; if (darg_last < darg) darg_last = darg; if (darg_last <= 0) darg_last = darg;
Пример Сгенерируем типы файлов в соответствии с распределением HPF:
<oldtype> FILEARRAY(100, 200, 300) !HPF$ PROCESSORS PROCESSES(2, 3) !HPF$ DISTRIBUTE FILEARRAY(CYCLIC(10), *, BLOCK) ONTO PROCESSES
Предполагая, что подключены шесть процессоров, этого можно достичь следующим кодом на ФОРТРАН:
ndims = 3 array_of_gsizes(1) = 100 array_of_distribs(1) = MPI_DISTRIBUTE_CYCLIC array_of_dargs(1) = 10 array_of_gsizes(2) = 200 array_of_distribs(2) = MPI_DISTRIBUTE_NONE array_of_dargs(2) = 0 array_of_gsizes(3) = 300 array_of_distribs(3) = MPI_DISTRIBUTE_BLOCK array_of_dargs(3) = MPI_DISTRIBUTE_DFLT_ARG array_of_psizes(1) = 2 array_of_psizes(2) = 1 array_of_psizes(3) = 3 call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) call MPI_TYPE_CREATE_DARRAY(size, rank, ndims, & array_of_gsizes, array_of_distribs, array_of_dargs, & array_of_psizes, MPI_ORDER_FORTRAN, oldtype, newtype,& ierr)
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |