next up previous contents
Next: Пример c атрибутами Up: Кэширование Previous: Кэширование   Contents

Функциональные возможности

Атрибуты присоединяются к коммуникаторам. Они локальны по отношению к процессу и специфичны по отношению к коммуникатору, к которому подключены. Атрибуты не передаются MPI от одного коммуникатора к другому кроме случая, когда коммуникатор дублируется с помощью MPI_COMM_DUP (и даже тогда приложение должно дать специальное разрешение через функции обратного вызова для копирования атрибута).

Совет пользователям: Атрибуты в языке Си имеют тип void *. Как правило, такой атрибут будет указателем на структуру, которая содержит дальнейшую информацию, или дескриптором для объекта MPI. В языке ФОРТРАН атрибуты имеют тип integer. Такой атрибут может быть дескриптором для объекта MPI или просто целочисленным атрибутом.[]

Совет разработчикам: Атрибуты являются скалярными величинами, равными или большими по размеру, чем указатель в языке Си. Атрибуты могут всегда хранить дескриптор MPI.[]

Интерфейс кэширования, определенный здесь, предполагает, что атрибуты хранятся в MPI скрытыми внутри коммуникатора. Функции доступа включают следующее:

Совет разработчикам: Кэширование и функции обратного вызова вызываются только синхронно, в ответ на явные запросы приложения. Это избавляет от проблем, которые возникают из-за повторных пересечений между пространствоми системы и пользователя. (Правило синхронного вызова - общее свойство MPI.)

Выбор значений ключей находится под контролем MPI. Это позволяет MPI оптимизировать реализацию наборов атрибутов и позволяет избежать конфликта между независимыми модулями, которые выполняют кэширование информации на одинаковых коммуникаторах.

Полные возможности кэширования можно реализовать и с минимальным интерфейсом, состоящим только из средств обратного вызова. Но такой минимальный интерфейс требует для обработки произвольных коммуникаторов некоторой формы табличного поиска. Напротив, более законченный интерфейс, определенный здесь, разрешает быстрый доступ к атрибутам с помощью указателей в коммуникаторах (чтобы найти таблицу атрибута) и разумно выбранных значений ключей (чтобы восстановить индивидуальные атрибуты).[]

MPI предоставляет следующие средства, связанные с кэшированием. Все они локальны для процессов.

Синтаксис функции MPI_KEYVAL_CREATE представлен ниже.

MPI_KEYVAL_CREATE(copy_fn, delete_fn, keyval, extra_state)

IN copy_fn функция обратного вызова для копирования keyval
IN delete_fn функция обратного вызова для удаления keyval
OUT keyval значение ключа для будущего доступа (целое)
IN extra_state дополнительное состояние для функций обратного вызова

int MPI_Keyval_create(MPI_Copy_function *copy_fn, MPI_Delete_function *delete_fn,
int *keyval, void *extra_state)

MPI_KEYVAL_CREATE(COPY_FN, DELETE_FN, KEYVAL, EXTRA_STATE, IERROR)
EXTERNAL COPY_FN, DELETE_FN
INTEGER KEYVAL, EXTRA_STATE, IERROR

Функция MPI_KEYVAL_CREATE генерирует новый ключ атрибута. Ключи локально уникальны в процессе и скрыты от пользователя, хотя они явно хранятся как целые числа. Однажды созданное значение ключа может использоваться для связывания атрибутов и обращения к ним на любом локально определенном коммуникаторе.

Функция copy_fn вызывается, когда коммуникатор дублируется функцией MPI_COMM_DUP. Функция сopy_fn должна иметь тип MPI_Copy_function, который определяется следующим образом:

typedef int MPI_Copy_function(MPI_Comm oldcomm, int keyval, void *extra_state, void *attribute_val_in, void *attribute_val_out, int *flag)

Объявление в языке ФОРТРАН для такой функции следующее:

SUBROUTINE COPY_FUNCTION(OLDCOMM, KEYVAL, EXTRA_STATE, ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT, FLAG, IERR) INTEGER OLDCOMM, KEYVAL, EXTRA_STATE, ATTRIBUTE_VAL_IN, ATTRIBUTE_VAL_OUT, IERR LOGICAL FLAG

Функция обратного вызова на копирование вызывается для каждого значения ключа в oldcomm в произвольном порядке. Каждый запрос на копирование делается с ключевым значением и соответствующим ему атрибутом. Если вызов возвращает flag = 0, то атрибут в дублированном коммуникаторе удален. В противном случае (flag = 1) новое значение атрибута принимает значение, возвращенное в attribute_val_out. Функция возвращает MPI_SUCCESS при успехе и код ошибки при отказе (когда MPI_COMM_DUP не может быть выполнен).

Функция сopy_fn может быть определена как MPI_NULL_COPY_FN или MPI_DUP_FN из Си или ФОРТРАН; MPI_NULL_COPY_FN есть функция, которая не делает ничего другого, кроме возвращения flag = 0 и MPI_SUCCESS. MPI_DUP_FN есть простая функция копирования, которая устанавливает flag = 1, возвращает значение attribute_val_in в attribute_val_out и возвращает
MPI_SUCCESS.

Совет пользователям: Несмотря на то, что формальные параметры attribute_val_in и attribute_val_out имеют тип void *, их использование отличается. Функция копирования в языке Си передает с помощью MPI в attribute_val_in значение атрибута и в attribute_val_out - адрес атрибута, чтобы позволить функции возвращать (новое) значение атрибута. Использование типа void * для обеих функций необходимо, чтобы избежать беспорядочных приведений типа.

Правильная функция копирования есть функция, которая полностью дублирует информацию, делая полную копию структур данных, соответствующих атрибуту; другая функция копирования может только делать другую ссылку на эту структуру данных, используя механизм счета ссылок.[]

Совет разработчикам: Для копирования и удаления функций, связанных со значениями ключей, созданных в Си, должен использоваться интерфейс языка Си; интерфейс языка ФОРТРАН должен использоваться для ключевых значений, созданных в языке ФОРТРАН.[]

Аналогичной copy_fn является функция обратного вызова для удаления. Функция delete_fn вызывается, когда коммуникатор удаляется функцией MPI_COMM_FREE. Функция delete_fn должна иметь тип MPI_Delete_function, который определяется следующим образом:

typedef int MPI_Delete_function(MPI_Comm comm, int keyval, void *attribute_val, void *extra_state);

Декларация для такой функции в языке ФОРТРАН следующая:

SUBROUTINE DELETE_FUNCTION(COMM, KEYVAL, ATTRIBUTE_VAL, EXTRA_STATE, IERR) INTEGER COMM, KEYVAL, ATTRIBUTE_VAL, EXTRA_STATE, IERR

Эта функция вызывается функциями MPI_COMM_FREE, MPI_ATTR_DELETE и MPI_ATTR_PUT, чтобы, когда это необходимо, удалить атрибут. Функция возвращает MPI_SUCCESS при успехе и код ошибки при неудаче (когда MPI_COMM_FREE не может быть выполнена.).

Функция delete_fn может быть определена как MPI_NULL_DELETE_FN в Си и ФОРТРАН; это тип функции, которая не делает ничего другого, кроме возвращения MPI_SUCCESS.

Функция MPI_KEYVAL_CREATE никогда не возвращает специальное ключевое значение
MPI_KEYVAL_INVALID, поэтому она может использоваться для статической инициализации значений ключей.

Синтаксис функции MPI_KEYVAL_FREE представлен ниже.

MPI_KEYVAL_FREE(keyval)

INOUT keyval освобождает целочисленное значение ключа (целое)

int MPI_Keyval_free(int *keyval)

MPI_KEYVAL_FREE(KEYVAL, IERROR)
INTEGER KEYVAL, IERROR

Функция MPI_KEYVAL_FREE освобождает существующий ключ атрибута. Эта функция устанавливает значение keyval в MPI_KEYVAL_INVALID. Заметим, что освобождение ключа атрибута, который находится в использовании, не является ошибкой, потому что фактически свободным он не cтановится, пока все ссылки (в других коммуникаторах на этом процессе) на этот ключ не будут освобождены. Эти ссылки должны быть явно удалены программой или через запросы к MPI_ATTR_DELETE, которые освобождают один экземпляр атрибута, или запросами к MPI_COMM_FREE, которые освобождают все экземпляры атрибута, связанные с удаленным коммуникатором.

Синтаксис функции MPI_ATTR_PUT представлен ниже.

MPI_ATTR_PUT(comm, keyval, attribute_val)

IN comm коммуникатор, к которому будет присоединен атрибут (дескриптор)
IN keyval ключевое значение, возвращаемое MPI_KEYVAL_CREATE (целое)
IN attribute_val значение атрибута

int MPI_Attr_put(MPI_Comm comm, int keyval, void *attribute_val)

MPI_ATTR_PUT(COMM, KEYVAL, ATTRIBUTE_VAL, IERROR)
INTEGER COMM, KEYVAL, ATTRIBUTE_VAL, IERROR

Функция MPI_ATTR_PUT сохраняет предусмотренное значение атрибута attribute_val для последующего восстановления функцией MPI_ATTR_GET. Если значение уже представлено, то результат будет таким, как если бы MPI_ATTR_DELETE сначала вызывалась, чтобы удалить предыдущее значение (и функция delete_fn была выполнена), и затем было сохранено новое значение. Запрос неверен, если отсутствует ключ со значением keyval; в частности MPI_KEYVAL_INVALID - неверное значение ключа. Запрос не выполнится, если функция delete_fn возвратила код ошибки вместо MPI_SUCCESS.

Синтаксис функции MPI_ATTR_GET представлен ниже.

MPI_ATTR_GET(comm, keyval, attribute_val, flag)

IN comm коммуникатор, к которому будет присоединен атрибут (дескриптор)
IN keyval значение ключа (целое)
OUT attribute_val значение атрибута, пока не станет flag = false
OUT flag true, если значение атрибута было извлечено; false, если ни один атрибут не связан с ключом

int MPI_Attr_get(MPI_Comm comm, int keyval, void *attribute_val, int *flag)

MPI_ATTR_GET(COMM, KEYVAL, ATTRIBUTE_VAL, FLAG, IERROR)
INTEGER COMM, KEYVAL, ATTRIBUTE_VAL, IERROR
LOGICAL FLAG

Функция MPI_ATTR_GET восстанавливает значение атрибута по ключу. Запрос ошибочен, если отсутствует ключ со значением keyval. С другой стороны, запрос правилен, если значение ключа существует, но ни один атрибут не присоединен к comm для этого ключа; в этом случае, запрос возвращает flag = false. В частности MPI_KEYVAL_INVALID - неверное значение ключа.

Совет пользователям: Запрос к MPI_ATTR_PUT передает в attribute_val значение атрибута; запрос к MPI_ATTR_GET передает в attribute_val адрес ячейки, куда должно быть возвращено значение атрибута. Таким образом, если само значение атрибута является указателем типа void*, фактический attribute_val параметр для MPI_ATTR_PUT будет иметь тип void*, и фактический attribute_val параметр для MPI_ATTR_PUT будет иметь тип void **.[]

Объяснение: Использование формального параметра attribute_val или типа void* (а не void**) позволяет избежать неупорядоченного приведения типа, которое было бы необходимо, если бы тип значения атрибута отличался от void*.[]

Синтаксис функции MPI_ATTR_DELETE представлен ниже.

MPI_ATTR_DELETE(comm, keyval)

IN comm коммуникатор, к которому будет присоединен атрибут (дескриптор)
IN keyval значение ключа удаленного атрибута (целое)

int MPI_Attr_delete(MPI_Comm comm, int keyval)

MPI_ATTR_DELETE(COMM, KEYVAL, IERROR)
INTEGER COMM, KEYVAL, IERROR

Функция MPI_ATTR_DELETE удаляет атрибут из кэша с помощью ключа. Эта функция вызывает функцию удаления атрибута delete_fn, определенную во время создания keyval. Вызов не будет выполнен, если функция delete_fn возвращает код ошибки, а не MPI_SUCCESS.

Всякий раз, когда коммуникатор копируется функцией MPI_COMM_DUP, вызываются (в произвольном порядке) все установленные на этот момент функции обратного вызова для копирования атрибутов. Всякий раз, когда коммуникатор удаляется функцией MPI_COMM_FREE, вызываются все установленные функции обратного вызова для удаления атрибутов.


next up previous contents
Next: Пример c атрибутами Up: Кэширование Previous: Кэширование   Contents
Alex Otwagin 2002-12-10