Компилятор C-DVM
Руководство пользователя
* Май, 2000 *

- дата последнего обновления 17.10.00 -


Оглавление

1 Назначение компилятора
2 Запуск компилятора
3 Компиляция программы в режиме отладки
4 Диагностики компилятора

4.1 Фатальные ошибки
4.2 Диагностики сканнера и парсера
4.3 Ошибки файлового уровня и операторов
4.4 Описания
4.5 Объявление и использование DVM-объектов
4.6 DISTRIBUTE, ALIGN, TEMPLATE
4.7 malloc и доступ к распределенным данным
4.8 Цикл PARALLEL
4.9 SHADOW
4.10 REDUCTION
4.11 Процедуры
4.12 Трассировка данных
4.13 Разное


1 Назначение компилятора

Язык C-DVM это расширение ANSI-C специальными аннотациями для спецификации параллельного выполнения программы. Эти аннотации называются DVM-директивами.

Компилятор C-DVM (конвертор C-DVM) - это инструмент DVM-системы, который преобразует аннотированную CDVM программу в ANSI-C программу в SPMD стиле, которая содержит обращения к системе поддержки (Lib-DVM). Затем полученная программа (c INCLUDE-файлом cdvm_c.h) может быть оттранслирована любым C-компилятором и слинкована с библиотекой Lib-DVM.

Кроме чисто параллельного кода компилятор может создавать “расширенный” отладочный код, использующий возможности анализатора производительности параллельных программ (PPPA) и отладчика, а так же “последовательную” версию программы (без вызовов Lib-DVM) с такими отладочными расширениями, которая может использоваться для получения характеристик выполнения исходной (не распараллеленной) программы и для получения “эталонной” трассировки для отладки в режиме сравнения трассировки.

2 Запуск компилятора

Компилятор запускается следующей командной строкой:

dvm сdv [<options>] <infile>

где:

<infile> - имя файла (без расширения), который содержит текст исходной программы на языке C-DVM. Файл должен иметь расширение .cdv. Поиск входного файла производится только в текущей директории. Предполагается, что он является правильным с точки зрения синтаксиса C и транслируется стандартным C-компилятором (конвертор не делает стандартной проверки синтаксиса и семантики C);

<options> - одна или более опций из следующего списка:

-o <outfile>- имя выходного файла конвертированной программы. Если опция не указана, то по умолчанию, выходной файл получает имя <infile>.c. Выходной файл записывается в текущую директорию.Если конвертор обнаружил ошибки, то этот файл не создается. Сообщения об ошибках записываются в файл cdvm_msg.

-sгенерировать “последовательную” программу (для получения трассировки и характеристик эффективности); если этот параметр не указан, генерируется параллельная программа;

-pгенерировать параллельную программу;

Режимы трассировки:

-d1 – трассировать запись в DVM-массивы,
-d2 – трассировать все обращения к DVM-массивам,
-d3 – трассировать запись во все переменные,
-d4 – трассировать все обращения ко всем данным;

Замечание1. В любом указанном режиме трассируется выполнение витков циклов.

Режимы анализа производительности:

-e1замеры параллельных циклов и объемлющих последовательных,
-e2замеры только на пользовательских интервалах (INTERVAL),
-e3 = e1 + e2,
-e4 = e3 + все другие последовательные циклы;

Замечание2. Из последовательных циклов учитываются только те, которые заданы макросами DO и FOR. Стандартные циклы C (for, while, do) не замеряются.

Прочие:

-v вывод информационных сообщений на терминал,
-w включить все предупреждения,
-w- выключить все предупреждения,
-xN – размер системных таблиц (по умолчанию: -x16).

3 Компиляция программы в режиме отладки

Для программ на языке C-DVM предусмотрены два способа отладки:

Для каждого способа определено несколько уровней отладки.

Уровни функциональной отладки. Уровень функциональной отладки – это целое число от 0 до 4, оно определяет события в программе, о которых сообщается отладчику:

0 - нет событий,
1 - модификация распределенных массивов,
2 - модификация и использование распределенных массивов,
3 - модификация всех переменных,
4 - модификация и использование всех переменных.

Уровни отладки эффективности. Уровень отладки эффективности– это целое число от 0 до 4, которое определяет, какие участки программы рассматриваются в качестве интервалов выполнения программы. Для каждого такого интервала можно получить характеристики эффективности.

0 - нет интервалов,
1 - параллельные циклы и охватывающие их последовательные циклы,
2 - последовательности операторов, указанные в программе посредством директивы
 INTERVAL,
3 - объединение подмножеств 1 и 2,
4 - все циклы и интервалы, заданные с помощью директивы
INTERVAL.

Последовательность операторов можно объявить интервалом с помощью директив:

DVM( INTERVAL [<целочисленное-выражение>]) {
  
<последовательность-операторов>
}

Каждый интервал операторов должен удовлетворять условиям блока операторов:

Другими словами запрещены передачи управления извне внутрь интервала, и изнутри интервала - на оператор вне интервала.

Фрагменты программы. Программу можно разделить на отдельные отлаживаемые фрагменты. Каждый фрагмент определяется директивой

DVM( DEBUG <номер-фрагмента> [ <параметр> ]) {
  < последовательность-операторов>
}

<номер-фрагмента> ::= < целое-положительное-число>
<параметр> ::= -d<leveld>
  | -e<levele>
  | -d<leveld> -e<levele>

где:

параметр -d указывает максимально возможный уровень функциональной отладки,
параметр
-e указывает максимально возможный уровень отладки эффективности,
leveld – целое число от 0 до 4,
levele – целое число от 0 до 4.

Фрагмент операторов должен удовлетворять условиям блока операторов.

Допускается вложенность фрагментов. Пусть f1 обозначает множество операторов охватывающего фрагмента, l1 – заданный в директиве DEBUG уровень отладки для данного фрагмента, а f2 и l2 - множество операторов и уровень отладки вложенного фрагмента. Тогда для множества операторов f1  f2 максимально допустимым является уровень l1, а для множества f2 максимально допустимым является уровень l2.

Вся программа считается по умолчанию фрагментом с номером 0 и максимально допустимыми уровнями отладки -d4 -e4.

Уровни отладки в опциях компилятора.

Уровень отладки для всей программы определяется опциями

-d<leveld> - для функциональной отладки,
-e<levele> - для отладки эффективности.
По умолчанию действуют опции –d0 и –e0.

Уровень отладки для отдельных фрагментов определяется опциями:

-d<leveld> [:fr-list]
-e<levele> [:fr-list]

где:

fr ::= Lfr [ - Hfr ]
Lfr ::= <номер-фрагмента>
Hfr ::= <номер-фрагмента>

Требуется, чтобы Lfr < = Hfr.

fr-list это список, где каждый элемент списка представляет собой либо номер отдельного фрагмента, либо непрерывный диапазон номеров фрагментов. Пусть в директиве DEBUG определен для некоторого фрагмента уровень отладки равный m. Если для этого фрагмента в опциях компилятора задан уровень l, то фрагмент будет включен в отладку с уровнем min( m , l ).

Подробнее об отладке программы см. “Отладка DVM–программ. Руководство по использованию” и “Отладка эффективности DVM-программ. Руководство по использованию”.

4 Диагностики компилятора

4.1. Фатальные ошибки

При фатальных ошибках выполнение прекращается. К ним относятся:

4.2 Диагностики сканнера и парсера

Сканнер останавливается с сообщением при:

Парсер останавливается с сообщением:

Unexpected <token> - Нет допустимого терминального символа;
<construct> expected - Нет требуемой конструкции;
<construct> syntax - Ошибка в конструкции.

4.3 Ошибки файлового уровня и операторов

The 'main' should get the command line parameters
В командной строке передаются параметры запуска Lib-DVM. Поэтому требуется заголовок
int main (int argn, char ** args)

The 'main' should 'return <rc>;' for the Lib-DVM
Функция main должна возвращать значение. Lib-DVM передает это значение операционной системе.

Implicitly created objects must precede 'main'
“Неявно создаваемые объекты должны предшествовать ‘main’”.
Неявно создаваемые объекты должны быть описаны перед main. К таким объектам относятся распределяемые массивы, шаблоны, решетки процессоров с константными размерностями и т.п. Они автоматически создаются в самом начале main, поэтому должны быть все известны в этой точке.

'main' required for implicitly created objects
’main’ требуется в файле в неявно создаваемыми объектами.”
Распределяемые массивы, шаблоны, решетки процессоров с константными размерностями и т.п. автоматически создаются в самом начале
main, поэтому функция main должна присутствовать в файле в неявно создаваемыми объектами.

DVM-statement outside function
“DVM-оператор вне функции.”
DVM-оператор находится вне функции.

Misplaced declarative DVM-directive
“Описательная директива в неподходящем месте”
Директива-описание встретилась среди операторов или в операторе.

DVM-directive requires a non-empty statement
“DVM-директива требует непустого оператора”.
Эта директива - спецификация при операторе. Не должна отделяться от него ';'.

Should be followed by the ';'
“Должна сопровождаться ‘;’”
Директива сама является оператором и должна оканчиваться ';'.

TASK_REGION must be a sequence of ON-blocks or ON-loop
TASK_REGION должен быть последовательностью ON-блоков или ON-циклом”.
В TASK_REGION могут входить только операторы, содержащие ON-директивы.

Not allowed in a PARALLEL loop
“Недопустимо в параллельном цикле”
Коллективная операция не может выполняться на одном процессоре.

4.4 Описания

DVM-object should be defined as 'void *'
“DVM объекты должны иметь тип void *

DVM-arrays may be int, long, float, or double only
“DVM-массивы могут быть только типов int, long, float и double”.

Scalar can not be distributed
“Скалярные переменные не могут быть распределенными”
Скалярные переменные всегда являются неявно размноженными.

DVM-pointer should be a C-pointer
“DVM-указателем должен быть описан как указатель в C”.
DVM(* …) требует <type> * <id>.

'*' is valid only with DISTRIBUTE and ALIGN
“’*’ допустима только с директивами DISTRIBUTE и ALIGN
’*’ можно использовать только в директивах DISTRIBUTE и ALIGN.

Only 1D-arrays of ptrs to DVM-arrays supported
“Только одномерные массивы указателей на распределенные массивы допустимы”.
Ограничение
компилятора.

Unsupported declarator for distributed data
“Недопустимый декларатор для распределенных данных”.

Can not initialize DVM-objects
“Нельзя указывать инициализатор для DVM объектов и массивов”.

DVM declarator syntax error
“Синтаксическая ошибка в деклараторе”.
Прочие синтаксические ошибки в деклараторе.

4.5 Объявление и использование DVM-объектов

Undefined
“Не определен”
Неопределенный идентификатор используется в
DVM-директиве. Последовательная программа при этом могла компилироваться, если идентификатор используется только в DVM-директивах.

This is not a DVM-object
“Это не DVM-объект”
Объект, используемый в
DVM-директиве, не является DVM-объектом.

Rank error
“Несоответствие ранга”
Ранги объекта при описания и использовании разные и т.п.

This is not a REDUCTION_GROUP
Это не REDUCTION_GROUP”.
DVM-директива требует параметры определенного класса.

This is not a SHADOW_GROUP
“Это не SHADOW_GROUP”.
DVM-директива требует параметры определенного класса.

This is not a REMOTE_GROUP
Это не REMOTE_GROUP”.
DVM-директива требует параметры определенного класса.

This is not a TASK
“Это не TASK”.
DVM-директива требует параметры определенного класса.

An array of void* required.
“Требуется массив указателей void *

MAP-target must be a processors section
MAP требует секции процессоров”.

ON-target must be an element of task array
ON требует элемента массива задач”.

4.6 DISTRIBUTE, ALIGN, TEMPLATE

'[*]' is only allowed in DVM( * DISTRIBUTE...)
“’[*]’ допустимо только в DVM( * DISTRIBUTE…).”

Array should be defined as DVM(DISTRIBUTE...)
“Массив должен быть описан как DVM(DISTRIBUTE…)
DVM-массив должен быть описан как DVM(DISTRIBUTE…).

GENBLOCK requires non-distributed 1D integer array
GENBLOCK требует нераспределенного одномерного массива типа int.”

ONTO target must be a TASK or a PROCESSORS
ONTO требует DVM-объект типа TASK или PROCESSORS.”

ONTO target must be an element of task array
ONTO требует элемент массива задач.”

Align-expression syntax: [-][A*]var[+B|-B]
“Синтаксис выражения выравнивания: [-][A*]var[+B|-B]
Разрешено только выражение, линейное относительно var.

Already used align|do variable
“Уже использованная переменная выравнивания цикла”
Два выражения выравнивания с одной и той же переменной не допускаются.

The base of a static should be a (known) static
“Базовый массив для выравнивания статического сам должен быть (уже определенным) статическим”
Статические (с константными размерностями)
DVM-массивы автоматически создаются с помощью malloc в начале функции main в порядке их объявления. Базовый массив должен уже создан до выравнивания (ALIGN) по нему создаваемого массива.

The parameter should be a (non-static) TEMPLATE
“Параметр должен быть (не ‘статическим’) TEMPLATE
Неверный параметр директивы CREATE-TEMPLATE.

4.7 malloc и доступ к распределенным данным

DVM-malloc requires (dim1*...*sizeof(...))
malloc для распределенного массива требует параметра в виде (dim1*…*sizeof(…))”
При создании массива необходимо задание всех измерений массива.

Is it 'sizeof(<element type>)' ?
Это sizeof(<element>) ?”
Последний сомножитель записан не в такой форме; может быть, потерян?

Only DVM-arrays may be malloc'ed
“Только DVM-массивы могут создаваться с помощью malloc
При создании DVM-массива с помощью функции malloc задан DVM-указатель.

Static DVM-array can not be malloc'ed
“Статические массивы нельзя создавать с помощью malloc
И не нужно: они создаются автоматически в начале функции main.

Only DVM-pointers may be assigned
“Только DVM-указателям можно присваивать значения”
Только
DVM-указателям можно присваивать значения других указателей и DVM-массивов.

REDISTRIBUTE|REALIGN must follow this malloc
После этого malloc требуется REDISTRIBUTE или REALIGN
Чтобы правильно создать массив, после malloc к нему следует применить REDISTRIBUTE или REALIGN, т.к. в описании массива не было задано распределение.

Can not assign to REMOTE
“Нельзя присваивать данным, описанным в REMOTE_ACCESS
Удаленным данным нельзя присваивать значения.

Can not get REMOTE address
“Нельзя брать адрес от данных REMOTE_ACCESS
К удаленным данным нельзя применять оператор &.

Possible non-local assignement. Use DVM(OWN)
“Возможно нелокальное присваивание. Используйте директиву OWN
Левая часть оператора присваивания в последовательной ветви программы является элементом распределенного массива.

Only 1..4-D arrays may be distributed
“Размерность распределенных массивов не более 4”
Распределенные массивы могут иметь размерность от 1 до 4.

Too many distributed dimensions
“Слишком много распределенных размерностей”
Особый случай ошибки "
Rank error".

Not all distributed dimensions
“Указаны не все распределенные размерности”.
Особый случай ошибки "Rank error".

4.8 Цикл PARALLEL

Duplicated or incompatible sub-directive
“Повторяющиеся или несовместимые поддирективы”
Повторяющиеся или несовместимые поддирективы директивы
PARALLEL. Несовместимы SHADOW_RENEW, SHADOW_START и SHADOW_WAIT, а также все поддирективы с ON <task>.

Too many headers in the PARALLEL loop
“Слишком много заголовков в цикле PARALLEL
Отделите лишние заголовки фигурными скобками.

Not enough headers in the PARALLEL loop
“Не хватает заголовков в цикле PARALLEL
Разрешены только тесно вложенные параллельные циклы.

Not a PARALLEL loop variable
“Это не переменная параллельного цикла”
Переменная в распределенном
DO/FOR заголовке отсутствует в списке переменных заголовка PARALLEL параллельного цикла.

PARALLEL loop variables disordered
“Нарушен порядок переменных параллельного цикла”
Порядок переменных в заголовке
PARALLEL параллельного цикла и в заголовках цикла DO/FOR должен быть одинаковый.

Variable already used
“Переменная уже использована”.
Два выражения выравнивания по одной переменной в параллельном цикле не разрешены.

Loop variable required
“Переменная цикла обязательна”
В заголовке параллельного цикла
PARALLEL задано [<не идентификатор>] или [ ].

Only 'long' or 'int' scalar loop variables allowed
“Допустимы только скалярные переменные типа int или long
В качестве переменных цикла можно использовать только скалярные переменные типа int или long.

4.9 SHADOW

Declared (or default) maximum width exceeded
“Превышена максимальная ширина теневых граней”
Превышена максимальная ширина теневых граней, объявленная в описании массива или 1 по умолчанию.

1D-array's shadow has no CORNERs
“Для одномерного массива бесполезно CORNER
Предупреждение. Ключевое слово не имеет смысла в данном контексте.

4.10 REDUCTION

Нарушение синтаксиса и семантики параметров редукционных функций.

Undefined RVAR
Wrong type of RVAR
Undefined RLOC
Wrong type of RLOC
Unallowed RVAR-expression
Unallowed RLOC-expression

4.11 Процедуры

Parameter should be defined as DVM(*...)
“Параметры должны быть описаны с ‘*’”
DVM-указатели передаются по ссылке.

Only DISTRIBUTE and ALIGN are valid for parameter.
“Только директивы DISTRIBUTE и ALIGN допустимы для параметров”
В качестве параметров можно передавать только массивы.
TEMPLATE, SHADOW_GROUP, PROCESSORS и т.п. не могут передаваться как параметры.

4.12 Трассировка данных

Это предупреждения:

This initialization will not be traced
“Эта инициализация не будет трассироваться”
Инициализация не будет трассироваться из-за неподдерживаемого типа или уже сгенерированной
main.

Can not trace ++, --, +=, -=, ...
“Не трассируются операции ++, -- +=, -=, и т.п.”
Ограничения компилятора.

Can not trace multiple assignement
“Не трассируется кратное присваивание”

Can not trace this type
“Не трассируется доступ к данным этого типа”
Неподдерживаемый тип.

4.13 Разное

Can fread-fwrite DVM-arrays as a whole only
“Распределенный массив вводится/выводиться только целиком”

Do you mean multiple index?
Пишите A[a,b] как либо A[(a.b)], либо A[a][b] по смыслу.

Not yet implemented... or error
Еще не реализовано или ошибка