next up previous contents
Next: Языковые привязки Up: Поддержка языка ФОРТРАН Previous: Расширенная поддержка ФОРТРАНa.   Contents

Дополнительная поддержка для встроенных числовых типов данных ФОРТРАНa.

Функции в этой главе - часть расширенной поддержки ФОРТРАНa, описанной в главе 8.2.4.

MPI-1 предоставляет несколько типов данных, соответствующих встроенным типам данных, поддерживаемым Си и ФОРТРАН. Они включают MPI_INTEGER, MPI_REAL, MPI_INT, MPI_DOUBLE, и т.д, а также необязательные типы MPI_REAL4, MPI_REAL8, и т.д. При этом существует однозначное соответствие между описанием языка и типом MPI.

ФОРТРАН (начиная с ФОРТРАН90) предоставляет так называемые KIND-параметризованные типы. Эти типы объявлены с использованием встроенного типа (INTEGER, REAL, COMPLEX, LOGICAL или CHARACTER) с необязательным целым KIND параметром, который выбирает из одного или более вариантов. Конкретное значение различных значений KIND зависит от реализации и не определяется языком. ФОРТРАН предоставляет функии выбора KIND selected_real_kind для типов REAL и COMPLEX, и selected_int_kind для типов INTEGER, которые позволяют пользователю объявлять переменные с минимальной точностью или количеством разрядов. Эти функции предоставляют переносимый способ объявления KIND-параметризованных переменных REAL, COMPLEX и INTEGER в ФОРТРАН. Эта схема обратно совместима с ФОРТРАН77. Переменные REAL и INTEGER в ФОРТРАН имеют KIND по умолчанию, если он не определен. Переменные DOUBLE PRECISION имеют встроенный тип REAL с нестандартным KIND. Эти два объявления эквивалентны: double precision x real(KIND(0.0d0)) x

MPI предоставляет два различных метода использования встроенных числовых типов. Первый метод может быть использован когда переменные объявлены в переносимом виде - используя KIND по умолчанию или используя параметры KIND, полученные функциями selected_int_kind или selected_real_kind. С этим методом, MPI автоматически выбирает необходимый тип данных (например, 4 или 8 байт) и предоставляет преобразование представления в гетерогенных средах. Второй метод дает пользователю полное управление над коммуникациями, раскрывая машинные представления.

Параметризованные типы данных с определенной точностью и диапазоном экспоненты.

MPI-1 предоставляет типы данных, соответствующие стандартным типам данных ФОРТРАН77 - MPI_INTEGER, MPI_COMPLEX, MPI_REAL, MPI_DOUBLE_PRECISION и MPI_DOUBLE_COMPLEX. MPI автоматически выбирает правильный размер данных и предоставляет преобразование представления в гетерогенных средах. Механизм, описанный в этой главе, расширяет модель MPI-1 для поддержки переносимых параметризованных типов данных.

Модель для поддержки переносимых параметризованных типов такова: переменные REAL объявлены (возможно, неявно), с использованием selected_real_kind(p, r) для определения параметра KIND, p - десятичная разрядная точность, а r - диапазон экспоненты. MPI неявно поддерживает двумерный массив определенных типов данных MPI D(p, r). D(p, r) определен для каждого значения (p, r), поддерживаемого компилятором, включая пары, в которых одно из значений не определено. Попытка доступа к элементу массива с индексом (p, r) не поддерживаемым компилятором ошибочны. MPI неявно поддерживает такой же массив типов данных COMPLEX. Такой же массив для целых чисел относится к selected_int_kind и индексируется по требуемому количеству разрядов r. Заметьте, что типы данных, содержащиеся в этих массивах не те же, что типы MPI вроде MPI_REAL, и т.д., а новый набор.

Совет разработчикам: Вышеуказанное описание дано только в описательных целях. Разработчики не обязаны создавать подобные внутренние массивы.[]

Совет пользователям: selected_real_kind() отражает большое число пар (p,r) в намного меньшее число параметров KIND, поддерживаемых компилятором. Параметры KIND не определены языком и не переносимы. С точки зрения языка, встроенные типы с одним и тем же базовым типом и параметром KIND одинаковы. Для того, чтобы позволить работу в гетерогенных средах, понятия MPI более строги. Соответствующие типы данных MPI совпадают тогда и только тогда, когда они имеют то же значение (p,r) ( REAL и COMPLEX) или значение r (INTEGER). Поэтому MPI имеет большее количество типов, чем количество фундаментальных типов в языках.

MPI_TYPE_CREATE_F90_REAL(p, r, newtype)  
IN p точность в десятичных разрядах (целое число)  
IN r десятичный диапазон экспоненты (целое число)  
OUT newtype требуемый тип данных MPI (дескриптор)  
int MPI_Type_create_f90_real(int p, int r, MPI_Datatype *newtype) MPI_TYPE_CREATE_F90_REAL(P, R, NEWTYPE, IERROR) INTEGER P, R, NEWTYPE, IERROR static MPI::Datatype MPI::Datatype::Create_f90_real(int p, int r)

Эта функция возвращает тип MPI, который соответствует переменной REAL типа
KIND selected_real_kind(p, r). В описанной выше модели она возвращает дескриптор элемента D(p, r). p или r могут быть убраны из вызовов selected_real_kind(p, r) (но не оба). Аналогично, p или r могут быть установлены в MPI_UNDEFINED. В коммуникации тип MPI A, возвращенный MPI_TYPE_CREATE_F90_REAL, соответствует типу B тогда и только тогда, когда B был возвращен функцией MPI_TYPE_CREATE_F90_REAL вызванной с теми же параметрами p и r или если B - дубликат такого типа данных. Ограничения по использованию возращенного типа данных с представлением данных ``external32'' даны далее.

Значения p и r, не поддерживаемые компилятором, вызывают ошибку.

MPI_TYPE_CREATE_F90_COMPLEX(p, r, newtype)  
IN p точность в десятичных разрядах (целое число)  
IN r десятичный диапазон экспоненты (целое число)  
OUT newtype требуемый тип данных MPI (дескриптор)  
int MPI_Type_create_f90_complex(int p, int r, MPI_Datatype *newtype) MPI_TYPE_CREATE_F90_COMPLEX(P, R, NEWTYPE, IERROR) INTEGER P, R, NEWTYPE, IERROR static MPI::Datatype MPI::Datatype::Create_f90_complex(int p, int r)

Эта функция возвращает тип MPI, который соответствует переменной COMPLEX типа
KIND selected_real_kind(p, r). p или r могут быть убраны из вызовов selected_real_kind(p, r) (но не оба). Аналогично, p или r могут быть установлены в MPI_UNDEFINED. Правила соответствия для созданных типов данных аналогичны правилам для MPI_TYPE_CREATE_F90_REAL. Ограничения по использованию возвращенного типа данных с представлением данных ``external32'' даны далее.

Значения p и r, не поддерживаемые компилятором, вызывают ошибку.

MPI_TYPE_CREATE_F90_INTEGER(r, newtype)  
IN r десятичный диапазон экспоненты - т.е. количество десятичных разрядов (целое число)  
OUT newtype требуемый тип данных MPI (дескриптор)  
int MPI_Type_create_f90_integer(int r, MPI_Datatype *newtype) MPI_TYPE_CREATE_F90_INTEGER(R, NEWTYPE, IERROR) INTEGER R, NEWTYPE, IERROR static MPI::Datatype MPI::Datatype::Create_f90_integer(int r)

Эта функция возвращает тип данных MPI, который соответствует переменной INTEGER типа KIND selected_int_kind(r). Правила соответствия для созданных типов данных аналогичны правилам для MPI_TYPE_CREATE_F90_REAL. Ограничения по использованию возращенного типа данных с представлением данных ``external32'' даны далее.

Значения p и r, не поддерживаемые компилятором, вызывают ошибку.

Пример 8.11 Иллюстрирует как создать типы данных MPI, соответствующие двум типам ФОРТРАНa, описанным при помощи selected_int_kind и selected_real_kind integer longtype, quadtype integer, parameter :: long = selected_int_kind(15) integer(long) ii(10) real(selected_real_kind(30)) x(10) call MPI_TYPE_CREATE_F90_INTEGER(15, longtype, ierror) call MPI_TYPE_CREATE_F90_REAL(30, MPI_UNDEFINED, quadtype, ierror) ... call MPI_SEND(ii, 10, longtype, ...) call MPI_SEND(x, 10, quadtype, ...)

Совет пользователям: Типы данных, полученные от функций выше - предопределенные типы данных. Они не могут быть освобождены; они не обязаны создаваться; они могут быть использованы с предопределенными операциями понижения точности. Есть две ситуации, в которых они ведут себя синтаксически, но не семантически отличаясь от предопределенных типов данных MPI:

  1. MPI_TYPE_GET_ENVELOPE возвращает особые комбинации, позволяющие программам получить значения p и r.
  2. Так как эти типы данных не имеют имен, они не могут быть использованы как инициализаторы во время компиляции и каким-либо образом использованы до вызова функций MPI_TYPE_CREATE_F90_.
Если переменная была объявлена с использованием значения KIND не по умолчанию, которое не было получено вызовом selected_real_kind() или selected_int_kind(), единственный способ получить соответствующий тип MPI - это использовать механизм, основанный на размере, описанный ниже. []

Объяснение: Интерфейс MPI_TYPE_CREATE_F90_REAL/COMPLEX/INTEGER требует на входе оригинальные значения диапазона и точности, чтобы определить полезные и независимые от компилятора (глава 7.5.2) или определенные пользователем (глава 7.5.3) представления данных, и в целях получения возможности производить автоматические и эффективные преобразования данных в гетерогенной среде.[]

Типы данных и представление ``external32''. Теперь мы определим, как типы данных, описанные в этой главе, ведут себя, если они использованы с внешним представлением данных
``external32'', описанным в главе 7.5.2.

Представление ``external32'' определяет форматы данных для целых значений и значений с плавающей точкой. Целые числа представлены по модулю два в формате ``big-endian''. Числа с плавающей точкой представлены в одном из форматов IEEE. IEEE определяет форматы ``Single'', ``Double'' и ``Double Extended'', требующие соответственно 4, 8 и 16 байт памяти. Для формата IEEE ``Double Extended'' MPI определяет ширину формата 16 байт с 15 битами экспоненты, диапазоном +10383, 112 бит мантиссы и кодировку, аналогичную формату ``Double''.

Представления external32 типов, возвращенных MPI_TYPE_CREATE_F90_REAL/COMPLEX/INTEGER даны в соответствии со следующими правилами:
Для MPI_TYPE_CREATE_F90_REAL: if (p > 33) or (r > 4931) then представление external32 не определено else if (p > 15) or (r > 307) then external32_size = 16 else if (p > 6) or (r > 37) then external32_size = 8 else external32_size = 4

Для MPI_TYPE_CREATE_F90_COMPLEX: размер вдвое больше чем MPI_TYPE_CREATE_F90_REAL.
Для MPI_TYPE_CREATE_F90_INTEGER: if (r > 38) then представление external32 не определено else if (r > 18) then external32_size = 16 else if (r > 9) then external32_size = 8 else if (r > 4) then external32_size = 4 else if (r > 2) then external32_size = 2 else external32_size = 1

Если представление типа данных ``external32'' не определено, его использования прямо или косвенно (как часть другого типа или с помощью дубля) в операциях, требующих ``external32'' тоже не определено. Эти операции включают в себя MPI_PACK_EXTERNAL, MPI_UNPACK_EXTERNAL и множество функций MPI_FILE, где используется ``external32''. Диапазоны, для которых представление ``external32'' не определено, зарезервированы для дальнейшей стандартизации.

Поддержка типов данных с определенным размером. MPI-1 предоставляет поименованные типы данных, соответствующие опциональным типам ФОРТРАН77, содержащим явную длину - MPI_REAL4, MPI_INTEGER8, и др. Эта глава описывает механизм, обобщающий эту модель для поддержки всех встроенных числовых типов данных ФОРТРАНa.

Мы предполагаем, что каждый класс типов (integer, real, complex) и каждый размер слова имеет уникальное машинное представление. Для каждой пары (класс типа, n) поддерживаемой компилятором, MPI должен предоставить поименованный тип данных соответствующего размера. Имя этого типа должно быть в форме MPI_<тип>n для Си и ФОРТРАНa и в форме MPI::<тип>n для С++, где <тип> - REAL, INTEGER или COMPLEX, а n - длина машинного представления в байтах. Этот тип локально соответствует всем переменным типа (тип класса, n). Список имен для таких типов включает:

MPI_REAL4 MPI_INTEGER1
MPI_REAL8 MPI_INTEGER2
MPI_REAL16 MPI_INTEGER4
MPI_COMPLEX8 MPI_INTEGER8
MPI_COMPLEX16 MPI_INTEGER16
MPI_COMPLEX32

В MPI-1 эти типы опциональны и соответствуют нестандартным определениям, поддерживаемым многими компиляторами ФОРТРАНa. В MPI-2 для каждого представления, поддерживаемого компилятором, необходим один тип. Для обратной совместимости с интерпретацией этих типов в MPI-1, мы предполагаем что нестандартные объявления REAL*n, INTEGER*n, всегда создают переменную, чье представление имеет размер n. Все эти типы предопределены.

Дополнительные размеры с нестандартным размером, например MPI_LOGICAL1 (соответствующий LOGICAL*1) могут быть определены в реализациях, но не требуются стандартом MPI.

Следующие функции позволяют пользователю получить требуемый тип данных встроенного типа языка ФОРТРАН.

MPI_SIZEOF(x, size)  
IN x переменная ФОРТРАН встроенного числового типа (выбор)  
OUT size размер машинного представления (целое число)  
MPI_SIZEOF(X, SIZE, IERROR) <type> X INTEGER SIZE, IERROR

Эта функция возвращает размер машинного представления переменной в байтах. Это функция ФОРТРАН и имеет привязку только для ФОРТРАН.

Совет пользователям: Эта функция похожа на оператор sizeof для Си и С++, но немного отличается. Если ей будет передан массив, она вернет размер базового элемента, а не всего массива. []

Объяснение: Эта функция недоступна в других языках за ненадобностью.[]

MPI_TYPE_MATCH_SIZE(typeclass, size, type)  
IN typeclass общий тип (целое число)  
IN size размер представления в байтах (целое число)  
OUT type тип данных правильного размера (дескриптор)  
int MPI_Type_match_size(int typeclass, int size, MPI_Datatype *type) MPI_TYPE_MATCH_SIZE(TYPECLASS, SIZE, TYPE, IERROR) INTEGER TYPECLASS, SIZE, TYPE, IERROR static MPI::Datatype MPI::Datatype::Match_size(int typeclass, int size)

typeclass - MPI_TYPECLASS_REAL, MPI_TYPECLASS_INTEGER или MPI_TYPECLASS_COMPLEX, в соответствии с желаемым типом. Функция возвращает тип данных MPI, соответствующий локальной переменной типа (тип класса, размер).

Эта функция возвращает ссылку (дескриптор) на один из типов данных, не являющийся копией. Этот тип не может быть освобожден. Функция MPI_TYPE_MATCH_SIZE может быть использована для для получения типа с определенным размером, соответствующего встроенному числовому типу ФОРТРАНa путем вызова MPI_SIZEOF для нахождения размера переменной, с последующим вызовом MPI_TYPE_MATCH_SIZE для поиска подходящего типа. В Си и С++ вместо MPI_SIZEOF можно использовать функцию sizeof(). Кроме того, для переменных с KIND по умолчанию, размер можно вычислить вызовом MPI_TYPE_GET_EXTENT, если известен typeclass. Использование размера, не поддерживаемого компилятором вызывает ошибку.

Объяснение: Это - функция ``для удобства''. Без нее поиск необходимого именованного типа может быть утомительным. (см. комментарии для разработчиков).[]

Совет разработчикам: Эта функция может быть реализована как серия тестов: int MPI_Type_match_size(int typeclass, int size, MPI_Datatype *rtype) { switch(typeclass) { case MPI_TYPECLASS_REAL: switch(size) { case 4: *rtype = MPI_REAL4; return MPI_SUCCESS; case 8: *rtype = MPI_REAL8; return MPI_SUCCESS; default: error(...); } case MPI_TYPECLASS_INTEGER: switch(size) { case 4: *rtype = MPI_INTEGER4; return MPI_SUCCESS; case 8: *rtype = MPI_INTEGER8; return MPI_SUCCESS; default: error(...); } ... etc ... } }

Связь с использованием разных типов. Обычные правила соответствия типов справедливы и для типов с определенным размером: значение, посланное с типом MPI_<тип>n может быть получено другим процессом с таким же типом. Большинство современных компьютеров использует дополнение двойки для целых и формат IEEE для плавающей точки. Поэтому, связь с использованием таких типов не выльется в потерю точности или ошибки округления.

Совет пользователям: При работе в гетерогенных окружениях нужна осторожность. Пример: real(selected_real_kind(5)) x(100) call MPI_SIZEOF(x, size, ierror) call MPI_TYPE_MATCH_SIZE(MPI_TYPECLASS_REAL, size, xtype, ierror) if (myrank .eq. 0) then ... initialize x ... call MPI_SEND(x, xtype, 100, 1, ...) else if (myrank .eq. 1) then call MPI_RECV(x, xtype, 100, 0, ...) endif Это может не работать в гетерогенной среде, если размер size различается в процессах 1 и 0. В гомогенной среде проблемы быть не должно. Для связи в гетерогенной среде есть, как минимум, четыре варианта, если не используется нестандартные объявления заданного размера - как REAL*8. Первое - определить переменные типа по умолчанию и использовать для них типы MPI - например, переменная типа REAL и использовать MPI_REAL. Второй - использовать selected_real_kind или selected_int_kind и с функциями из предыдущей главы. Третье - определить переменную, которая будет одинакова во всех архитектурах (например, selected_real_kind(12) почти во всех компиляторах будет размером 8 байт). Четвертый - аккуратно проверить размер машинного представления до связи. Это может потребовать явного преобразования в переменную, размер которой походит для связи, и согласование размера между приемником и передатчиком.

Также заметьте, что использование ``external32'' для ввода-вывода требует пристального внимания к размерам представлений. Пример: real(selected_real_kind(5)) x(100) call MPI_SIZEOF(x, size, ierror) call MPI_TYPE_MATCH_SIZE(MPI_TYPECLASS_REAL, size, xtype, ierror) if (myrank .eq. 0) then call MPI_FILE_OPEN(MPI_COMM_SELF, 'foo', & MPI_MODE_CREATE+MPI_MODE_WRONLY, & MPI_INFO_NULL, fh, ierror) call MPI_FILE_SET_VIEW(fh, 0, xtype, xtype, 'external32', & MPI_INFO_NULL, ierror) call MPI_FILE_WRITE(fh, x, 100, xtype, status, ierror) call MPI_FILE_CLOSE(fh, ierror) endif call MPI_BARRIER(MPI_COMM_WORLD, ierror) if (myrank .eq. 1) then call MPI_FILE_OPEN(MPI_COMM_SELF, 'foo', MPI_MODE_RDONLY, & MPI_INFO_NULL, fh, ierror) call MPI_FILE_SET_VIEW(fh, 0, xtype, xtype, 'external32', & MPI_INFO_NULL, ierror) call MPI_FILE_WRITE(fh, x, 100, xtype, status, ierror) call MPI_FILE_CLOSE(fh, ierror) endif

Если процессы 0 и 1 работают на разных машинах, код может работать не так, как ожидается, если size на этих машинах имеет разное значение.[] --

--


next up previous contents
Next: Языковые привязки Up: Поддержка языка ФОРТРАН Previous: Расширенная поддержка ФОРТРАНa.   Contents
Alex Otwagin 2002-12-10