The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Каталог документации / Раздел "Программирование, языки" / Оглавление документа
next up previous contents
Next: Новые стандартные типы Up: Новые функции манипуляции типами Previous: Конструктор типа данных ``субмассив''   Contents

Конструктор типа данных ``распределенный массив''

Конструктор распределенного массива поддерживает распределения данных, сходные с 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 был корректным, должно выполняться условие $\prod_{i=0}^{ndims-1}array\_of\_psizes[i] = size$. Порядок процессов в сетке процессов считается с главной строкой, как и в случае топологий виртуальных 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 имеет форму

$\{(type_0,disp_0),(type_1,disp_1),...,(type_{n-1},disp{n-1})\}$

где $type_i$ - стандартный тип MPI, и пусть ex будет длиной oldtype.

С учетом вышеуказанного, функция cyclic() определяется так:


cyclic(darg,gsize,r,psize,oldtype)

= {(MPI_LB,0),
$(type_0,disp_0+r\times darg\times ex),...,$
$(type_{n-1},disp_{n-1}+r\times darg\times ex),$
$(type_0,disp_0+(r\times darg+1)\times ex),...,$
$(type_{n-1},disp_{n-1}+(r\times darg+1)\times ex),$
...
$(type_0,disp_0+((r+1)\times darg-1)\times ex),...,$
$(type_{n-1},disp_{n-1}+((r+1)\times darg-1)\times ex),$
...
$(type_0,disp_0+r\times darg\times ex+psize\times darg\times ex),...,$
$(type_{n-1},disp_{n-1}+r\times darg\times ex+psize\times darg\times ex),$
$(type_0,disp_0+(r\times darg+1)\times ex+psize\times darg\times ex),...,$
$(type_{n-1},disp_{n-1}+(r\times darg+1)\times ex+psize\times darg\times ex),$
...
$(type_0,disp_0+((r+1)\times darg-1)\times ex+psize\times darg\times ex),...,$
$(type_{n-1},disp_{n-1}+((r+1)\times darg-1)\times ex+psize\times darg\times ex),$
...
$(type_0,disp_0+r\times darg\times ex+psize\times darg\times ex\times(count-1)),...,$
$(type_{n-1},disp_{n-1}+r\times darg\times ex+psize\times darg\times ex\times(count-1)),$
$(type_0,disp_0+(r\times darg+1)\times ex+psize\times darg\times ex\times(count-1)),...,$
$(type_{n-1},disp_{n-1}+(r\times darg+1)\times ex+psize\times darg\times ex\times(count-1)),$
...
$(type_0,disp_0+(r\times darg-1+darg_{last}-1)\times ex+psize\times darg\times ex\times(count-1)),...,$
$(type_{n-1},disp_{n-1}+(r\times darg+darg_{last}-1)\times ex+psize\times darg\times ex\times(count-1)),$
(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 - число блоков, которые должны быть распределены между процессорами. И, в конце концов, $darg_{last}$ определяется следующим фрагментом:

        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)


next up previous contents
Next: Новые стандартные типы Up: Новые функции манипуляции типами Previous: Конструктор типа данных ``субмассив''   Contents
Alex Otwagin 2002-12-10



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру