fdvmDDr (1158419), страница 5
Текст из файла (страница 5)
Первый оператор вставляется вслед за оператором stmt1 , а второй – вслед за stmt2.
| void ShadowList ( | SgExpression | *el, | ||
| el | - список renewee-list | |||
| st | - указатель на директиву PARALLEL со спецификацией | |||
| gref | - указатель на выражение, являющееся ссылкой на группу | |||
Для каждого массива в списке el, генерируется и вставляется в процедуру следующий оператор:
* включение теневой грани в группу
dvm000(i) = inssh(gref,array,...)
| void RemoteVariableList ( | SgSymbol | *group | ||
| group | - указатель на символ группы | |||
| rml | - список ссылок на массивы | |||
| stmt | - указатель на директиву PARALLEL со спецификацией | |||
Функция генерирует и вставляет в процедуру операторы для чтения удаленных данных в буфер (REMOTE-ACCESS-block).
В случае синхронной спецификации REMOTE_ACCESS генерируются следующие операторы:
{
* создание буферного массива
it = crtrbl(array-header,buffer-header,…)
* запуск загрузки буфера
it = loadrb(buffer-header,0)
* ожидание завершения загрузки буфера
it = waitrb(buffer-header)
* корректировка коэффициента CNB адресации элементов буфера,
* где NB – размерность буфера
buffer-header(NB+2) = buffer-header(NB+1)-
* buffer-header(NB)*buffer-header(NB+3) … -
* buffer-header(3)*buffer-header(2*NB+2)
}... для каждой удаленной ссылки
В случае асинхронной спецификации REMOTE_ACCESS (с именем группы RMG) генерируются операторы:
IF (RMG(2) .EQ. 0) THEN
{
* создание буферного массива
it = crtrbl(array-header,buffer-header,…)
* корректировка коэффициента CNB адресации элементов буфера
buffer-header(NB+2) = buffer-header(NB+1)-
* buffer-header(NB)*buffer-header(NB+3) … -
* buffer-header(3)*buffer-header(2*NB+2)
* запуск загрузки буфера
it = loadrb(buffer-header,0)
* ожидание завершения загрузки буфера
it = waitrb(buffer-header)
* включение буфера в группу RMG
it = insrb(RMG(1),buffer-header)
}... для каждой удаленной ссылки
ELSE
IF (RMG(3) .EQ. 1) THEN
* ожидание завершения загрузки всех буферов группы RMG
it = waitbg(RMG(1))
RMG(3) = 0
ENDIF
ENDIF
5.2Трансляция операторов ввода-вывода (модуль io.cpp)
Модуль компилятора io.cpp включает функции для трансляции операторов ввода-вывода.
Операторы ввода-вывода, осуществляющие передачу данных, управление и другие вспомогательные операции с внешним файлом, выполняются на одном процессоре (процессоре ввода-вывода), специально выделяемом для этой цели системой поддержки выполнения FDVM программы. Операция ввода-вывода значения размноженной переменной производится над копией переменной, размещенной на процессоре ввода-вывода. Введенное значение рассылается остальным процессорам. Ввод-вывод распределенного массива реализуется с помощью буфера, размещенного на процессоре ввода-вывода. При вводе данные из внешнего файла передаются в буфер, а затем рассылаются тем процессорам, на которые распределен массив. Когда распределенный массив выводится, данные с процессоров, где локализованы элементы массива, сначала пересылаются в буфер, а из буфера - во внешний файл.
| int TestIOList ( | SgExpression | *iol, | ||
| iol | - список ввода-вывода | |||
| stmt | - указатель на оператор ввода-вывода | |||
Функция анализирует список ввода-вывода. Она возвращает 1, если в списке присутствуют ссылки на распределенные массивы, или 0, в противном случае.
Вызывает функции ImplicitLoopTest( ) , IOitemTest( ).
| int ImplicitLoopTest( | SgExpression | *eim, | ||
| eim | - указатель на неявный цикл | |||
| stmt | - указатель на оператор ввода-вывода | |||
Функция анализирует список элементов неявного цикла. Если в списке нет ссылок на распределенные массивы, функция возвращает 1, в противном случае – 0.
| int IOitemTest ( | SgExpression | *e, | ||
| e | - указатель на элемент списка ввода-вывода | |||
| stmt | - указатель на оператор ввода-вывода | |||
Функция возвращает 1, если элемент списка ввода-вывода не является ссылкой на распределенный массив, или 0, в противном случае.
| int IOcontrol ( | SgExpression | *e, | ||
| e | - список управляющей информации | |||
| ioc | - массив управляющих параметров ввода-вывода | |||
| type | - тэг признака оператора ввода-вывода (PRINT_STAT, WRITE_STAT, READ_STAT) | |||
Функция анализирует список управляющей информации оператора передачи данных и присваивает элементам массива ioc[] значения управляющих параметров (UNIT, FMT, ERR и т.п.). Если обнаруживаются синтаксические ошибки, функция возвращает 0, иначе – 1.
| int control_list1 ( | SgExpression | *e, | ||
| e | - список управляющей информации | |||
| ioc | - массив управляющих параметров ввода-вывода | |||
Функция анализирует список управляющей информации операторов BACKSPACE, REWIND и ENDFILE и присваивает элементам массива ioc[] значения управляющих параметров (UNIT, ERR и т.п.). Если обнаруживаются синтаксические ошибки, функция возвращает 0, иначе – 1.
| int control_list_open ( | SgExpression | *e, | ||
| e | - список управляющей информации | |||
| ioc | - массив управляющих параметров ввода-вывода | |||
Функция анализирует список управляющей информации операторов OPEN, CLOSE, INQUIRE и присваивает элементам массива ioc[] значения управляющих параметров (UNIT, ERR и т.п.). Если обнаруживаются синтаксические ошибки, функция возвращает 0, иначе – 1.
| void IO_ThroughBuffer( | SgSymbol | *ar, | ||
| e | - указатель на символ распределенного массива | |||
| stmt | - указатель на оператор ввода-вывода | |||
В случае ввода-вывода распределенного массива, в программе пользователя отводится память для буфера ввода-вывода.
Пусть A(N1,N2,...,Nk) – ссылка на распределенный массив размерности k, BUF(L) – вектор того же типа, что и массив A. Тогда компилятор заменит оператор ввода-вывода последовательностью операторов по следующей схеме:
s0 = L
si = [si-1 / Ni] i {1 : k}
n = max(i)
si 0, i{0 : k}
m = 1 (если n = k)
}
DO label In+2 = 0, Nn+2-1. . . n+2 k
DO label Ik = 0, Nk-1
}
DO label In+1 = 0, Nn+1-1, snIF (In+1 .LE. Nn+1) THEN
m = sn n+1 k
ELSE
m = Nn+1 - In+1
ENDIF
ввод:
IF(tstio( ) .ne. 0 ) READ (...) (BUF(j), j = 1, N1 * ...*Nn * m)
| n 1 |
копирование-секции-массива (BUF(1 : N1 * ...*Nn * m),
| n 1 |
A(1: N1,...,1:Nn , In+1 +1: In+1 +m , In+2 +1, ..., Ik +1) )
| n 1 | n+1 k | n+2 k |
вывод:
копирование-секции-массива (BUF(1 : N1 * ...*Nn* m),
| n 1 |
A(1: N1,...,1:Nn , In+1 +1: In+1 +m , In+2 +1, ..., Ik +1) )
| n 1 | n+1 k | n+2 k |
IF(tstio( ) .ne. 0 ) WRITE (...) (BUF(j), j = 1, N1 * ...*Nn * m)
| n 1 |
label CONTINUE
Операция копирования-секции-массива реализуется с помощью функции системы поддержки arrcpy( ).
5.3Реструктурирование дерева разбора (модуль stmt.cpp)
Модуль stmt.cpp составляют функции реструктурирования дерева разбора.
| void InsertNewStatementAfter( | SgStatement | *stat, | ||
| stat | - указатель на вставляемый оператор | |||
| current | - указатель на оператор, вслед за которым вставляется оператор stat | |||
| cp | - указатель на родительский оператор для stat | |||
Оператор stat вставляется в дерево разбора (программу) вслед за оператором current, так что его родителем по управлению является оператор cp.
| void InsertNewStatementBefore( | SgStatement | *stat, | ||
| stat | - указатель на вставляемый оператор | |||
| current | - указатель на оператор, перед которым вставляется оператор stat | |||
Оператор stat вставляется в дерево разбора (программу) перед оператором current.
void doAssignStmt ( SgExpression *re )
| re | - указатель на выражение для правой части оператора присваивания |
Создает оператор присваивания с правой частью re :
dvm000(i) = re
и вставляет его перед оператором, на который указывает глобальная переменная where.
SgExpression *LeftPart_AssignStmt ( SgExpression *re )
| re | - указатель на выражение для правой части оператора присваивания |
Создает оператор присваивания с правой частью re :
dvm000(i) = re















