Руководство пользователя для MPICH, переносимой реализации MPI версия 1.2.1

William Gropp и Ewing Lusk
перевод Балуева А.Н. (мат-мех факультет СПбГУ)

Оглавление

Добавления

А. Автоматическая генерация профилирующих библиотек.

В начало страницы

Профилирующий оболочечный генератор (wrappergen) был задуман для дополнения профилирующего интерфейса MPI. Он позволяет пользователю написать любое количество `мета'-оболочек, которые могут быть применены к любому количеству MPI-функций. Оболочки wrappers могут находиться в самостоятельных файлах или вкладываться нужным образов, так что более чем один уровень профилирования может существовать для индивидуальных функций.

Генератор оболочек нуждается в трех источниках информации:

1. Список функций, для которых строятся оболочки.

2. Описания для функций, которые должны быть профилированы. Для ускорения и простоты синтаксического анализа, для этот используется специальный формат. См. файл `proto'.

3. Определения оболочек.

Список функций есть просто файл с разделенными пробелами именами функций.

Если он опущен, любые макросы forallfn или fnall будут действовать для каждой функции в файле описаний.

A.1. Написание определений оболочек.

В начало страницы

Сами определения оболочек состоят из C-кодов со специальными макросами. Каждая макро, окружено управляющими последовательностями ff и gg.

Следующие макросы распознаются генератором оболочек:

-fileno"""» здесь что-то пропущено

Целый индекс указывает, из какого оболочечного файла произошло макро. Это полезно для предотвращения коллизий с именами, когда файлы с описаниями содержат глобальные переменные. Предполагается, что все идентификаторы, объявленные вне функций, оканчиваются на .-fileno"""».

Например, static double overhead.time.-fileno"""»; может действовать до:

static double overhead.time.0; (конец примера).

-forallfn !function name escape? !function A? !function B? … «"""

… –endforallfn""""

Код между –forallfn"""» и –endforallfn"""» копируется один раз для каждой профилируемой функции, за исключением перечисленных в списке,

с заменой управляющей escape строки, указанной посредством !function name escape?, именем каждой функции.

Например:

-forallfn fn.name""""static int –fn.name"""».ncalls.-fileno"""»; –endforallfn""""

может действовать до:

static int MPI.Send.ncalls.1; static int MPI.Recv.ncalls.1; static int MPI.Bcast.ncalls.1;

(конец примера ) –foreachfn !function name escape? !function A? !function B? … «"""

… –endforeachfn""""

-foreachfn"""» есть то же самое, что и –forallfn""""

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

Например:

-forallfn fn.name mpi.send mpi.recv""""

static int –fn.name"""».ncalls.-fileno"""»; –endforallfn""""

может действовать до:

static int MPI.Send.ncalls.2; static int MPI.Recv.ncalls.2; (конец примера)

-fnall !function name escape? !function A? !function B? … «"""

… –callfn"""» … –endfnall""""

-fnall"""» определяет оболочку, которая должна использоваться для всех функций, кроме поименованных. Генератор оболочки wrappergen будет развернут в полное определение функции в традиционном формате C. Макро

-callfn"""» сообщает генератору оболочки, куда вставлять вызов функции, которая профилируется. Должно быть точно одно вхождение макро –callfn"""» в каждом определении оболочки. Макро, указанное посредством !function name escape?, должно быть замещено именем каждой функции. В пределах определения оболочки распознаются дополнительные макросы.

-vardecl !type? !arg? !arg? … «"""

vardecl употребляются для описания переменных внутри определения оболочки.

Если вложенный макрос запрашивает переменные описаниями с одинаковыми именами, то генератор оболочки создает уникальные имена, добавляя последовательные целые к концу объявленных имен (var, var1, var2, …), пока не получит уникальное имя. Не нужно «своим способом» описывать переменные в определении оболочки, поскольку имена переменных могут столкнуться с другими оболочками, и описания переменных могут встретиться в коде после операторов из других оболочек, что недопустимо в классическом С и в ANSI C.

-!varname?"""" Если переменная объявлена в vardecl, имя для обращения к этой переменной (которое может отличаться от унифицированной формы, которая появится в окончательном коде) становится временным макро, которое будет распространяться на унифицированную форму. Например,

-vardecl int i d"""» может распространиться на: int i, d3; (конец примера)

-!argname?""""

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

-!argnum?""""

На аргументы профилируемой функции можно ссылаться также по номеру, начиная с 0 и увеличивая его.

-returnVal""""

ReturnVal распространяется на переменные, которые используются для возврата значений профилируемой функции.

-callfn""""

callfn расширяется до вызова профилируемой функции. При вложенных определениях оболочек оно также представляет точку, в которой вставляется код для всяких внутренних вложенных функций. Порядок вложений определяется порядком, в котором оболочки воспринимаются генератором оболочек. Например, если два файла `prof1.w' и `prof2.w' оба содержат две оболочки для MPI Send, то профилирующий код, произведенный при использовании обоих файлов, будет иметь форму:

int MPI.Send( args…) arg declarations… – /*pre-callfn код из wrapper 1 из prof1.w */

/*pre-callfn коде из wrapper 2 из prof1.w */ /*pre-callfn код из wrapper 1 из prof2.w */

/*pre-callfn коде из wrapper 2 из prof2.w */ returnVal = MPI.Send( args… );

/*post-callfn код из from wrapper 2 из prof2.w */ /*post-callfn код из wrapper 1 из prof2.w */ /*post-callfn код из wrapper 2 из prof1.w */ /*post-callfn код из wrapper 1 из prof1.w */ return returnVal; «»

-fn !function name escape? !function A? !function B? … «"""

… –callfn"""» … –endfnall""""

fn идентичен fnall, за исключением того, что он генерирует только оболочки для функций, названных явно.

Например:

-fn this.fn MPI.Send"""" –vardecl int i"""» –callfn"""» printf( «Call to –this.fn"""»."n» ); printf( «-i"""» не был использован «n» ); printf( «первый аргумент для –this.fn"""» есть –0"""""n» );

-endfn""""

будет расширен до:

int MPI.Send( buf, count, datatype, dest, tag, comm ) void * buf; int count; MPI.Datatype datatype; int dest; int tag;

MPI.Comm comm; – int returnVal; int i; returnVal = PMPI.Send( buf, count, datatype, dest, tag, comm );

printf( «Call to MPI.Send."n» ); printf( «i не был использован «n» );

printf( «первый аргумент для MPI.Send есть buf"n» ); return returnVal; «»

Пример оболочечного файла есть в `sample.w' и соответствующий выходной файл есть в `sample.out'.


<<< Оглавление Страницы: Добавление A  B >>>