next up previous contents
Next: Соответствие представлений данных Up: Возможность взаимодействия с файлом Previous: Внешнее представление данных: external32   Contents

Определяемые пользователем представления данных

Есть две ситуации, которые не могут быть разрешены по требованиям представлений.

  1. Пользователь желает писать файл в представлении, неизвестном для реализации.
  2. Пользователь желает читать файл в представлении, неизвестном для реализации.
Определяемые пользователем представления данных позволяют этому пользователю вставлять конвертор ``третьей стороны'' в поток ввода- вывода - для выполнения преобразования представления.

Таблица 7.2 Типы данных, определенные для external32

Тип Длина    
MPI_PACKED 1    
MPI_BYTE 1    
MPI_CHAR 1    
MPI_UNSIGNED_CHAR 1    
MPI_SIGNED_CHAR 1    
MPI_WCHAR 2    
MPI_SHORT 2    
MPI_UNSIGNED_SHORT 2    
MPI_INT 4    
MPI_UNSIGNED 4    
MPI_LONG 4    
MPI_UNSIGNED_LONG 4    
MPI_FLOAT 4    
MPI_DOUBLE 8    
MPI_LONG_DOUBLE 16    
       
MPI_CHARACTER 1    
MPI_LOGICAL 4    
MPI_INTEGER 4    
MPI_REAL 4    
MPI_DOUBLE_PRECISION 8    
MPI_COMPLEX 2*4    
MPI_DOUBLE_COMPLEX 2*8    

Опциональный тип Длина    
MPI_INTEGER1 1    
MPI_INTEGER2 2    
MPI_INTEGER4 4    
MPI_INTEGER8 8    
MPI_LONG_LONG 8    
MPI_UNSIGNED_LONG_LONG 8    
       
MPI_REAL4 4    
MPI_REAL8 8    
MPI_REAL16 16    

MPI_REGISTER_DATAREP(datarep, read_conversion_fn, write_conversion_fn, dtype_file_extent_fn, extra_state)

IN datarep Идентификатор представления данных (строка)  
IN read_conversion_fn Функция, вызываемая для преобразования из текущего представления файла в исходное (функция)  
IN write_conversion_fn Функция, вызываемая для преобразования из текущего представления файла в исходное (функция)  
IN write_conversion_fn Функция, вызываемая для преобразования из исходного представления файла в текущее (функция)  
IN dtype_file_extent_fn Функция, вызываемая для определения экстента типа данных согласно представленному в файле (функция)  
IN extra_state Дополнительное состояние  

int MPI_Register_datarep(char *datarep, MPI_Datarep_conversion_function *read_conversion_fn, MPI_Datarep_conversion_function *write_conversion_fn, MPI_Datarep_extent_function *dtype_file_extent_fn, void *extra_state)

MPI_REGISTER_DATAREP(DATAREP, READ_CONVERSION_FN, WRITE_CONVERSION_FN, DTYPE_FILE_EXTENT_FN, EXTRA_STATE, IERROR) CHARACTER*(*) DATAREP EXTERNAL READ_CONVERSION_FN, WRITE_CONVERSION_FN, DTYPE_FILE_EXTENT_FN INTEGER(KIND=MPI_ADDRESS_KIND) EXTRA_STATE INTEGER IERROR

void MPI::Register_datarep(const char* datarep, MPI::Datarep_conversion_function* read_conversion_fn, MPI::Datarep_conversion_function* write_conversion_fn, MPI::Datarep_extent_function* dtype_file_extent_fn, void* extra_state)

Вызов связывает read_conversion_fn, write_conversion_fn и dtype_file_extent_fn с идентификатором представления данных datarep. После этого datarep может использоваться как аргумент MPI_FILE_SET_VIEW, заставляя последующие операции доступа к данным вызывать функции для преобразования всех элементов данных, к которым происходит обращение, из текущего представления в исходное, либо наоборот. MPI_REGISTER_DATAREP - локальная операция и она только регистрирует представление данных для вызывающего процесса MPI. Если datarep уже определен, сигнализируется ошибка из класса ошибок MPI_ERR_DUP_DATAREP, используя заданный по умолчанию обработчик ошибок файла (см. раздел 7.7). Длина строки представления данных ограничена значением MPI_MAX_DATAREP_STRING (MPI::MAX_DATAREP_STRING для С++). MPI_MAX_DATAREP_STRING должно быть достаточно большим - чтобы представить 64 символа (см. раздел 2.2.8). Не предоставляется никаких подпрограмм для удаления представления данных и освобождения привлеченных ресурсов; не ожидается, что прикладная программа будет генерировать представление данных, привлекая значительные ресурсы.

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

typedef int MPI_Datarep_extent_function(MPI_Datatype datatype, MPI_Aint *file_extent, void *extra_state);

SUBROUTINE DATAREP_EXTENT_FUNCTION(DATATYPE, EXTENT, EXTRA_STATE, IERROR) INTEGER DATATYPE, IERROR INTEGER(KIND=MPI_ADDRESS_KIND) EXTENT, EXTRA_STATE

typedef MPI::Datarep_extent_function(const MPI::Datatype& datatype, MPI::Aint& file_extent, void* extra_state);

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

Функции преобразования datarep.

typedef int MPI_Datarep_conversion_function(void *userbuf, MPI_Datatype datatype, int count, void *filebuf, MPI_Offset position, void *extra_state);

SUBROUTINE DATAREP .CONVERSION_FUNCTION (USERBUF, DATATYPE, COUNT, FILEBUF, POSITION, EXTRA-STATE, IERROR) <TYPE> USERBUF(*), FILEBUF(*) INTEGER COUNT, DATATYPE, IERROR INTEGER(KIND=MPI_OFFSET_KIND) POSITION INTEGER(KIND=MPI_ADDRESS_KIND) EXTRA_STATE

typedef MPI::Datarep_conversion_function(void* userbuf, MPI::Datatype& datatype, int count, void* filebuf, MPI::Offset position, void* extra_state);

Функция read_conversion_fn должна преобразовывать представление данных файла в исходное представление. Перед вызовом этой подпрограммы MPI распределяет и заполняет filebufcount) последовательностью элементов данных. Тип каждого элемента данных совпадает с типом элемента соответствующего предопределенного типа данных, указанного сигнатурой datatype. Функция принимает в extra_state аргумент, который был передан вызову MPI_REGISTER_DATAREP. Функция должна копировать все count элементов данных из filebuf в userbuf согласно распределению, описанному в datatype, преобразовывая каждый элемент данных файла в исходное представление. datatype будет эквивалентен типу данных, который пользователь передал в функцию чтения или записи. Если длина datatype меньше, чем длина count для элементов данных, функция преобразования должна обработать datatype как последовательно располагающийся вне userbuf. Функция преобразования должна начать сохранять преобразованные данные в userbuf с ``места'', указанного с помощью position в последовательном datatype.

Совет пользователям: Хотя функции преобразования подобны MPI_PACK и MPI_UNPACK, нужно обратить внимание на различия в использовании аргументов count и position. В функциях преобразования: count - счетчик элементов данных (то есть, счетчик элементов typemap datatype), а position - индекс этого typemap. В MPI_PACK, incount ссылается на номер неделимого datatypes, а position - номер байта.[]

Совет разработчикам: Операция преобразования при чтении может быть реализована следующим образом:

  1. Получить файловый экстент всех элементов данных.
  2. Распределить (выделить) filebuf достаточного размера для ``удержания'' всех count элементов данных.
  3. Прочитать данные из файла в filebuf.
  4. Вызвать read_conversion_fn, чтобы преобразовать данные и поместить их в userbuf.
  5. Перераспределить (освободить) filebuf.

Если MPI не в состоянии распределить буфер достаточного размера для ``удержания'' всех данных при преобразовании во время операции чтения, то он может вызвать функцию, преобразования, многократно использующую одинаковые datatype и userbuf, и последовательно читающую ``куски'' данных, подверженных преобразованиям, в filebuf. При первом вызове (и для случая, когда все данные, которые должны быть преобразованы, помещаются в filebuf), MPI вызовет функцию с position, установленной в ноль. Данные, преобразованные в течение этого вызова, будут сохранены в userbuf соответственно с первым count элементов данных datatype. Затем, при последующих вызовах функции преобразования, MPI будет инкрементировать значение position до значения count элементов, преобразование которых началось предыдущим вызовом.

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

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

Функция write_conversion_fn должна преобразовывать представление данных файла из исходного. Перед вызовом этой подпрограммы MPI распределяет filebuf, достаточного размера для ``удержания'' всех count последовательных элементов данных. Тип каждого элемента данных совпадает с типом элемента соответствующего предопределенного типа данных, указанного сигнатурой datatype. Функция должна копировать count элементов данных из userbuf согласно распределению, описанному в datatype, и последовательно размещать их в filebuf, преобразовывая каждый элемент данных из исходного представления в файловое. Если длина datatype меньше, чем длина count для элементов данных, функция преобразования должна обработать datatype как последовательно располагающийся вне userbuf.

Функция преобразования должна начать копирование с ``места'' в userbuf, указанного с помощью position в последовательном datatype. datatype будет эквивалентен типу данных, который пользователь передал в функцию чтения или записи. Функция принимает в extra_state аргумент, который был передан вызову MPI_REGISTER_DATAREP.

Предопределенная константа MPI_CONVERSION_FN_NULL (MPI::MPI CONVERSION_FN_NULL для С++) может использоваться как write_conversion_fn или read_conversion_fn. В таком случае, MPI не будет пытаться вызвать write_conversion_fn или read_conversion_fn, соответственно, но осуществит требуемый доступ к данным, используя исходное их представление.

Реализация MPI должна гарантировать, что все доступные данные преобразованы, любо используя filebuf, достаточного размера для ``удержания'' всех элементов данных, либо иначе, делая повторяющиеся вызовы функции преобразования с одинаковым аргументом datatype соответствующими значениями position.

Реализация вызовет только возвратные подпрограммы, описанные в этой секции
(read_conversion_fn, write_conversion_fn и dtype_file_extent_fn), когда одна из подпрограмм чтения или записи из раздела 7.4 или MPI_FILE_GET_TYPE_EXTENT вызывается пользователем.
dtype_file_extent_fn будет принимать только предопределенные типы данных, используемые пользователем. Функции преобразования будут принимать только те типы данных, что эквивалентны переданным пользователем в одну из подпрограмм, упомянутых выше.

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

Функции преобразования должны возвратить код ошибки. Если возвращенный код ошибки имеет значение отличное от MPI_SUCCESS, реализация сигнализирует ошибку в классе MPI_ERR_CONVERSION.


next up previous contents
Next: Соответствие представлений данных Up: Возможность взаимодействия с файлом Previous: Внешнее представление данных: external32   Contents
Alex Otwagin 2002-12-10