cdvmDDr (1158400), страница 6
Текст из файла (страница 6)
Реализация.
Функция ISWFaccess(N) проверяет ссылку на распределенные данные и выдает сообщение, если
-
ранги не совпадают;
-
результат malloc присваивается DVM-указателю или статическому DVM-массиву;
-
в функции fread или fwrite указан не массив целиком;
-
это присваивание ссылке REMOTE_ACCESS.
Она использует функции:
-
LBK() для индексированных переменных;
-
wfLXI() для одиночных идентификаторов;
-
wfLXfun() для макрокоманд с идентификатором распределенного массива.
Если это корректная ссылка на элемент распределенного массива, эта же функция строит ссылку в форме, требуемой RTL. Функция mk_datype(N,type) порождает первый параметр макрокоманды DAElmx -- тип как идентификатор. Функция mk_daind(N,type,lbk) преобразует ссылку на распределенный массив в список остальных параметров макрокоманды.
3.6.4Собственные вычисления
Контекст и синтаксис.
lhs=rhs; // assignement
Выход компилятора.
if(DVM_ISLOCAL(lhs)) {
lhs = rhs ; }
DVM_ENDLOCAL();
Замечание. Оператор собственных вычислений это присваивание распределенному массиву в нераспределенной ветки программы. Оно должно "охраняться" проверкой локальности элемента.
Реализация.
Требуемые поддеревья строит функция mk_local(N), когда это необходимо (т.е. если ссылка в левой части присваивания может оказаться нелокальной). Если это так, то выдается (слабое) предупреждение. (Чтобы его получить, нужно задать опцию -w.) Функция mk_ind_list(N) используется для создания списка индексных выражений.
3.6.5Инициализация и завершение параллельного выполнения
Контекст и синтаксис.
int main( int argc, char ** arg)
{
declarations...
first-statement
...
[ exit(rc); ]
...
return rc;
}
Выход компилятора.
int main( int argn, char ** args)
{
declarations...
DVM_INIT(0,argn,args); // initialization of RTL
[ implicit static array creation ]
[ tracing of initialized variables ]
[ other implicit actions ]
first-statement
...
[ DVM_EXIT(rc); ] // exit through RTL
...
DVM_RETURN(rc); // exit through RTL
}
Замечание. Для генерации корректной программы функция main должна принимать параметры командной строки (которые затем будут переданы RTL) и должна завершаться оператором return или exit.
Реализация.
Функция isMain(N) определяет, не является ли текущее определение определением функции main. Функция Arg(N) извлекает параметры и выдает сообщение, если если они не указаны.
Требуемые поддеревья строит функция wfRETURN(), а также функция ISWF непосредственно перед вызовом функции genIMglob().
3.6.6Функции ввода-вывода
Компиляция функций ввода-вывода сводится к переименованию функции iofun на ее RTL аналог dvm_iofun. Единственным исключением являются функции fread() и fwrite(), когда они применяются к распределенному массиву. В это случае массив читается или пишется целиком. Остальные параметры игнорируются.
Реализация.
Замена идентификаторов выполняется на шаге преобразования той же функцией pSUBST. Она использует список пар идентификаторов. Этот список строится в списковой памяти на шаге инициализации функцией RenInit(). Функция RenPair(a,b) записывает одну пару в список.
Список переименования содержит следующие идентификаторы:
идентификатор СИ -- идентификатор C-DVM
exit DVM_EXIT
FILE DVMFILE
clearerr dvm_clearerr
fclose dvm_fclose
feof dvm_feof
ferror dvm_ferror
fflush dvm_fflush
fgetc dvm_fgetc
fgetpos dvm_fgetpos
fgets dvm_fgets
fopen dvm_fopen
fprintf dvm_void_fprintf
fputc dvm_fputc
fputs dvm_fputs
fread dvm_fread
freopen dvm_freopen
fscanf dvm_fscanf
fseek dvm_fseek
fsetpos dvm_fsetpos
ftell dvm_ftell
fwrite dvm_fwrite
getc dvm_getc
getchar dvm_getchar
gets dvm_gets
printf dvm_void_printf
putc dvm_putc
putchar dvm_putchar
puts dvm_puts
rewind dvm_rewind
scanf dvm_scanf
setbuf dvm_setbuf
setvbuf dvm_setvbuf
tmpfile dvm_tmpfile
ungetc dvm_ungetc
vfprintf dvm_void_vfprintf
void_vprintf dvm_void_vprintf
vprintf dvm_vprintf
fgetchar dvm_fgetchar
fputchar dvm_fputchar
vfscanf dvm_vfscanf
vscanf dvm_vscanf
STDIN DVMSTDIN
STDOUT DVMSTDOUT
STDERR DVMSTDERR
STDAUX DVMSTDAUX
STDPRN DVMSTDPRN
remove dvm_remove
rename dvm_rename
tmpnam dvm_tmpnam
access dvm_access
unlink dvm_unlink
stat dvm_stat
3.7Отладочные расширения
3.7.1Анализатор производительности. Циклы
Контекст и синтаксис.
[ DVM(PARALLEL... ) ]
DO(var,first,last,step) // or
FOR(var,times)
loop-body
Выход компилятора.
BPLOOP(n) // for parallel loop or
BSLOOP(n) // for sequential loop
code for loop
ELOOP(n)
Замечание. Параметр n это порядковый номер цикла для идентификации парных команд. Множество циклов, для которых генерируются эти макрокоманды, зависит от параметров командной строки (-e1 ... -e4).
Реализация.
Требуемые поддеревья строит функция Ploop() в зависимости от параметров командной строки.
3.7.2Анализатор производительности. Интервалы
Контекст и синтаксис.
DVM(INTERVAL [ int-expr ] )
{ C-statements }
Выход компилятора.
DVM_BINTER(n,v)
{ code for statements }
DVM_EINTER(n)
Замечание. Параметр n это порядковый номер цикла для идентификации парных команд. Если int-expr отсутствует, то параметр v будет иметь некоторое стандартное значение.
Реализация.
Требуемые поддеревья строит функция interval(N) в зависимости от параметров командной строки.
3.7.3Отладчик. Трассировка данных
Контекст и синтаксис. Любая ссылка на обычную или распределенную переменную var в операторах СИ или инициализация переменной.
Выход компилятора.
DVM_STVA(type,rt,var,base,rhs) // lh-side of assignement
DVM_LDV(type,rt,var,base) // for read access
DVM_STV(type,rt,var,base) // to register initialization
Замечание. Множество ссылок, для которых генерируются эти макрокоманды, зависит от параметров командной строки (-d1 ... -d4).
Реализация.
Это последнее действие функции ISWFaccess, которая вызывает функцию cDTscal или cDTarr, чтобы перестроить уже построенное дерево RTL ссылки. Еще одно преобразование будет выполнено функцией stv2stva для оператора присваивания; а именно, макрокоманда будет преобразована в DVM_STVA.
3.7.4Отладчик. Трассировка вычислений
Контекст и синтаксис. Любой цикл или конструкция TASK_REGION.
Выход компилятора.
parallel loop creation
DVM_PLOOP(n,r,ls,hs,ss) // or DVM_SLOOP(n)
loop-headers
DVM_ITER(r,vars)
code for loop body
DVM_ENDLOOP(n)
для цикла или
DVM_BTASK(n) // in TASK_REGION header
...
DVM_ETASK(n)
ON-block or ON-loop body
...
DVM_NTASK(ind) // end of TASK_REGION construct
для конструкции TASK_REGION.
Реализация.
Требуемые поддеревья строит функция Ploop() для параллельного цикла и функция wfTASKREGION для блока TASK_REGION в зависимости от параметров командной строки.
3.7.5Пoследовательный код
Генерация последовательной программы задается параметром -s командной строки. Все DVM-директивы игнорируются за исключением следующих:
-
параллельные циклы и задачи;
-
редукционные группы должны создаваться для правильной работы отладчика;
-
директивы распределения данных учитываются, чтобы отличить обычные данные от распределенных для выборочной трассировки.
Заметим, что препроцессорные операторы #define должны оставаться на месте в отличие от параллельного кода, в котором они должны переноситься в начало файла.
Реализация.
Опция командной строки -s сохраняется в переменной OPTs, которая управляет генерацией всех конструкций. При наличии этой опции почти все макрокоманды (с указанными выше исключениями) генерируются как пустые операторы, а все описания остаются неизменными.















