Параллельные вычисления в ИММ УрО РАН
 
 
                      Файл PROGDEVL.TXT
                  ИПМ им. М. В. Келдыша РАН.
           Отдел ИВСиЛС, сектор эксплуатации МВС.
                                                  А. О. Лацис.

            СИСТЕМА-1000 - ОС СУПЕР-ЭВМ МВС-1000.
             ИНСТРУКЦИЯ ПРИКЛАДНОМУ ПРОГРАММИСТУ
           ПО РАБОТЕ НА МВС-1000 В СРЕДЕ Router+.

     Здесь и далее первое,  определяющее вхождение термина или
важного понятия выделяется в тексте заглавными буквами.
     Предполагается, что читатель настоящего документа знаком
с  документами: "Система-1000 - ОС супер-ЭВМ МВС-1000. Наибо-
лее общие понятия. Аннотированный список документов", "Систе-
ма-1000 - ОС супер-ЭВМ МВС-1000. Инструкция  пользователю  по
работе на МВС-1000".
     Данный документ  посвящен описанию системы обмена сообще-
ниями для программ,  разрабатываемых и выполняемых  на  основе
транспортной сети Router+.

СОДЕРЖАНИЕ.
Введение.
1. Структура программного обеспечения.
2. Настройка программы на логическую топологию.
3. Управление ресурсами сети во время счета.
4. Формат обращения к системным функциям.
  4.1. Обязательная инициализация.
  4.2. Основные возможности.
  4.3. Дополнительные возможности.
  4.4. Измерение времени.
5. Графический вывод.
  5.1. Основные понятия для программиста.
  5.2. Предоставляемые режимы и реализации.

Введение.
     Вообще говоря,  разработка программы для  транспьютеропо-
добных  систем включает в себя,  помимо написания программ для
отдельных процессов,  также описание в том или ином виде ЛОГИ-
ЧЕСКОЙ КОНФИГУРАЦИИ,  то есть картины связи между процессами в
задаче,  ФИЗИЧЕСКОЙ КОНФИГУРАЦИИ,  то есть картины связи между
процессорами в системе,  и отображения логической конфигурации
на физическую.  В принципе, теоретически, обе конфигурации мо-
гут  меняться во время счета,  и тогда задача конфигурирования
становится совсем нетривиальной.
     В  МВС-1000  физическая  конфигурация  во время счета не
меняется.  При  разработке  программ  в  рамках  возможностей
транспортной  сети  Router+  логическая  конфигурация  всегда
одинакова и от физической конфигурации не зависит  (подробнее
см. ниже). Наконец, вся работа по отображению предоставляемых
пользователю    логических    конфигураций    на   физические
выполняется коммуникационным  ядром  ОС  при  запуске  задачи
автоматически.  Это  полностью  освобождает  пользователя  от
задачи конфигурирования - требуется только выбрать количество
процессоров  и  распределить  между  ними   работу,   написав
программу  для каждого. Ниже рассматривается используемая при
этом логика взаимодействия.
     Замечание.  Система  Router+  очень  похожа  на  систему
Router,   реализованную   для   МВС-100.    За    исключением
незначительных  деталей,  Router+  есть   просто   расширение
Router.  Старые  программы  для  МВС-100  должны  работать на
МВС-1000 практически без изменений.

1. Структура программного обеспечения.
     Логически МВС-1000 используется как сеть  вычислительных
процессоров, связанных линками.
     Это  означает, что на коммуникационном процессоре модуля
не может выполняться программа, написанная пользователем. Там
выполняются  только  компоненты  ОС,  и  само  наличие   этих
процессоров  от  прикладной  программы скрыто. Поэтому впредь
вместо  "вычислительный   модуль"   будем   говорить   просто
"процессор",  имея  в  виду модуль, в котором процессор Alpha
выполняет прикладную программу, а коммуникационный  процессор
-  чисто  системные  функции.  Будем  также  говорить о связи
линками между процессорами, не оговариваясь всякий  раз,  как
обстоит дело на физическом уровне.
     Таким образом,  модель вычислений  в  ОС-1000 практически
совпадает с транспьютерной.  Перечислим здесь основные понятия
последней, не вдаваясь в их подробное определение, но вводя по
ходу  дела  ограничения и уточнения, свойственные ОС-1000 в ее
нынешнем виде.
     На сети процессоров выполняется ЗАДАЧА, состоящая из ПРО-
ЦЕССОВ, которые обмениваются СООБЩЕНИЯМИ по КАНАЛАМ. В отличие
от чисто транспьютерных систем, в ОС-1000 на каждом процессоре
выполняется только один процесс. Реализован он в виде ПРОГРАМ-
МЫ,  которая  с точки зрения системы программирования является
отдельным загрузочным модулем:  пользователь пишет ее текст на
языке программирования, транслирует и компонует. В тексте явно
выписываются обмены сообщениями с другими программами.
     Настоящая версия ОС не позволяет порождать процессы дина-
мически: на  каждом  процессоре при запуске задачи выполняется
один и только один процесс.
     В дополнение к возможности обмена сообщениями по каналам,
каждый процесс прикладной задачи в  полном  объеме  пользуется
стандартным вводом/выводом:  файлами, потоками stdin, stdout и
stderr.
     Поскольку каждый процессор выполняет один процесс, реали-
зованный как одна программа, мы будем впредь использовать сло-
ва "процессор",  "процесс" и "программа" как синонимы. В част-
ности,  будем говорить о номере (в смысле п.1) процесса  и/или
программы,  об обмене сообщениями между процессорами или прог-
раммами.
     Упомянутое  выше  требование  единственности  процесса в
рамках программы пользователя,  вообще  говоря,  может  и  не
иметь  места.  Правильнее  утверждать,  что  с  точки  зрения
обращения  к  описываемым  ниже  функциям  Router+  программа
пользователя должна вести себя, как один процесс.
     Введем несколько  важных определений,  связанных с техни-
ческой реализацией упомянутой выше модели вычислений.
     Программа   в  среде  ОС-1000  имеет  доступ  к  системе
ввода-вывода, включающей:
     - некоторое  подмножество системных запросов ввода/вывода
Unix,
     - средства обмена сообщениями по каналам.
     Для программы,  выполняющейся на Alpha, доступ к  системе
ввода/вывода прозрачен, как если бы линки, терминалы и магнит-
ные диски были напрямую доступны из Alpha.
     Процессоры в рамках одной задачи занумерованы  подряд  от
нуля. Эти номера и используются для адресации сообщений.
     Физическая топология процессорной  сети  также  прозрачна
для задачи пользователя:  каждый процессор связан с каждым па-
рой противонаправленных ВИРТУАЛЬНЫХ КАНАЛОВ. Обмениваясь сооб-
щениями по каналам, программа указывает НОМЕР КАНАЛА, совпада-
ющий с номером процессора,  к которому (от которого)  проложен
этот канал.  Если процессор номер 2 посылает сообщение процес-
сору номер 8, он должен послать его в свой восьмой канал. Про-
цессор номер 8, в свою очередь, должен прочитать его из своего
второго канала.

2. Настройка программы на логическую топологию.
     В виртуально  полносвязной  сети  настройка на логическую
топологию заключается в том,  что программа во время счета уз-
нает свой  номер  процессора  и общее число процессоров (прог-
рамм). Дополнительно системный администратор может (и  должен)
устанавливать некоторые соглашения о системе нумерации,  чтобы
пользователь мог  оптимизировать  наиболее  массовые   обмены,
распределяя программы  по процессорам наилучшим образом.  Так,
рекомендуется нумеровать физически смежные процессоры последо-
вательными  номерами.  В  ОС-1000,  из-за  того,  что   набор
процессоров  для  запуска  программы формируется из отдельных
свободных  процессоров,  а  не  секций  с  известной  заранее
топологией,     такого     рода    оптимизация    затруднена.
Соответствующие средства, когда они будут разработаны,  будут
описаны в отдельном документе.
     В ОС-1000 информация о номере процессора не  может  быть
передана  через  получаемую  программой командную строку, как
это делалось в Router для МВС-100, поскольку программа  поль-
зователя выполняется на модуле в рамках ОС vxWorks, в которой
вообще нет понятия передаваемой программе командной строки.
     Для  того,  чтобы  инициализировать  функции  Router+  и
одновременно  узнать  собственный  номер  в наборе модулей, а
также общее число модулей  в  наборе,  следует  обратиться  к
функции rf_create:
     
     extern int rf_create( void )
     ....
     n = rf_create();
     if ( !n )
      {
       fprintf( stderr, "rf_create error\n" );
       return...
      }
                
     rf_create  возвращает  закодированную в целом числе пару
номеров: собственный номер и общее число процессоров. Система
кодирования такова, что значение "0" получиться не может. Оно
возвращается при ошибке. Помимо возвращения в  закодированном
виде в качестве значения функции rf_create, собственный номер
и общее число процессоров запоминаются внутри системы и могут
быть извлечены в явном виде обращениями к следующим функциям:
     
     extern int sysProcNumGet( void ), sysProcTotalGet( void );
     ....
     my_number  = sysProcNumGet();
     n_of_nodes = sysProcTotalGet();
     
     В программе на Фортране можно использовать  целочисленные
подпрограммы-функции без параметров,  включенные в стандартную
библиотеку:

        n = node_number()
c n теперь равно номеру процессора
        nn = n_of_nodes()
c nn теперь равно числу процессоров в конфигурации.
     Вызывать перед этим rf_create в  программе  на  Фортране
нет необходимости.

3. Управление ресурсами сети во время счета.
     Имевшиеся  в  реализации  Router  для  МВС-100  средства
обеспечения  очередности  доступа   процессоров   к   системе
ввода/вывода    (grab_server,    ungrab_server)   в   Router+
отсутствуют, поскольку  ОС-1000  не  налагает  таких  строгих
ограничений   на  число  одновременно  открытых  файлов,  как
ОС-100, а также  обеспечивает  каждому  процессору  отдельные
stdin, stdout и stderr.

4. Формат обращения к системным функциям.
     
4.1. Обязательная инициализация.
     В среде vxWorks,  в  которой  выполняются  программы  на
МВС-1000, от программиста требуются некоторые усилия по обес-
печению  нормального старта программы. Ниже приводится сводка
правил по инициализации runtime-среды при использовании  раз-
ных языков программирования.
     Язык C:
     Главная  функция,  с которой начинается выполнение прог-
раммы, может называться как угодно, в том числе и "main",  но
командной  строки  (argc, argv) она не получит. Для выяснения
своих координат среди партнеров (свой номер, общее число про-
цессоров)    используйте    rf_create(),     sysProcNumGet(),
sysProcTotalGet(), как описано выше в настоящем документе.
     Фортран-77 и Фортран-90:
     Главная программа или подпрограмма, с которой начинается
выполнение программы, может называться как угодно. При указа-
нии  этого  имени  системе  запуска следует добавлять к имени
сзади символ "_" (подчерк). Так, если у Вас написано:
     PROGRAM MAIN
то при формировании описания программы для  запуска  (см.  об
этом  в Руководстве пользователя, файл working.txt) имя глав-
ной функции надо указать как "main_".
     Первым выполняемым оператором в Вашей  программе  должен
быть следующий:
     call for_rtl_init
     В противном случае, ничего работать не будет.
     Для  выяснения  своего номера и общего числа процессоров
поступайте, как описано выше.
     В отличие от программы на языке "C", программа на  Форт-
ране  способна получать командную строку, извлекаемую при по-
мощи стандартных подпрограмм iargc(), getarg().
     По умолчанию, строка состоит из единственного  аргумента
"node".  Вы можете задать любую свою, поместив ее в текстовый
файл под именем "commandline" в раздел,  который  назначается
текущим при старте задачи.
     Скорее  всего, Вас не устроят настройки по умолчанию ре-
акций системы на арифметические аварии. Для изменения реакции
системы на underflow и прочие неприятнсти  используйте  сист-
темную подпрограмму for_set_fpe() (см. соответствующую коман-
ду "man").
     Язык HPF:
     Имя главной подпрограммы - как в Фортране.
     Использовать явно функции Router+ КАТЕГОРИЧЕСКИ запреща-
ется  -  программа  на HPF использует их автоматически внутри
себя. Соответственно, и узнавать свой номер и число процессо-
ров не требуется  (если  требуется,  используйте  конструкции
языка HPF).
     "call for_rtl_init" - не требуется.
     Командная строка передается, как в Фортране.
     Использование for_set_fpe() - как в Фортране.
     
4.2. Основные возможности.
     Прототипы описываемых здесь функций находятся в:

          #include 

     Сами  функции  включены в vxWorks. Возможно обращение из
программ на C  и  Фортране.
     Имеется всего 6 функций обмена сообщениями между процес-
сорами:
     -  запустить посылку указанного массива в указанный про-
цессор,
     - запустить прием в указанный массив из указанного  про-
цессора,
     - ждать конца посылки,
     - ждать конца приема,
     - проверить кончилась ли посылка,
     - проверить, кончился ли прием.
     Отличие  Router+  от  Router для МВС-100  заключается  в
ослаблении  ограничений  на  запуск  одновременно  нескольких
обменов сообщениями между одними и теми же двумя процессорами.
     В Router, процессор одновременно мог  запустить  сколько
угодно  посылок  и  приемов  от разных процессоров, но только
один  обмен  в  каждом  из  направлений  с  одним  и  тем  же
процессором.  Если  процессор  A  запустил прием сообщения от
процессора B, он не мог запустить еще один прием от него  же,
пока  первый  обмен  не  завершится.  То  же было верно и для
передачи.
     В  Router+   разрешается   запускать   ограниченное   (в
настоящей  реализации  -  до  16)  число  обменов между двумя
процессорами в  одном  и  том  же  направлении  одновременно.
Обмены  ставятся  в  очередь  и  выполняются в том порядке, в
каком они были запущены.
     Это расширение возможностей потребовало  изменить  смысл
параметра  в  функциях  "ждать  конца" и "проверить, кончился
ли". В Router  в  качестве  параметра,  говорящего,  о  каком
именно  обмене идет речь, указывался номер процессора, обмен
с  которым   был   запущен.   В   Router+,   для   сохранения
совместимости,  разрешается  указывать  в  качестве  значения
параметра в функциях синхронизации номер процессора, при этом
будет иметься в виду ПОСЛЕДНИЙ обмен, запущенный с  указанным
процессором   в   указанном   направлении  (поскольку  обмены
выполняются строго в порядке запуска,  завершение  последнего
обмена  автоматически означает и завершение всех предыдущих).
При необходимости подождать завершения не  последнего  обмена
следует применять специальные средства, описанные ниже.
     Длина сообщения указывается как при приеме,  так  и  при
передаче,  и  должна быть согласована на обоих концах. Нельзя
передать некоторое сообщение одним обращением к функции "пос-
лать" и принять его двумя обращениями  к  функции  "принять",
указав каждый раз половину длины.
     В   отличие   от   Router,   в  Router+  уточнен  способ
нейтрализации ошибок при расхождении  длин  на  передающем  и
приемном  концах. Теперь эта ситуация не приводит к зависанию
или  "порче  памяти".  Обмен   всегда   завершается,   причем
сообщения  не  дробятся  и  не склеиваются, а одно переданное
всегда  принимается  как  одно.  Если  передано  меньше,  чем
принимается,  будет  принято  все  переданное.  Если передано
больше, обмен также завершится  без  разрушений  в  памяти  и
нарушений  в  логике  взаимодействия,  но примется, возможно,
меньше  данных,  чем  было  затребовано  при  приеме,  причем
неизвестно, на сколько именно меньше (возможно, что и ничего).
     В Router+ снята имевшаяся в  Router  асимметрия  в заве-
ршении операции запуска обмена. Теперь любая операция запуска
(как  приема,  так  и  передачи)  завершается  без выполнения
каких-либо условий (в Router для завершения запуска  передачи
требовалось,    чтобы   на   приемном   конце   был   запущен
соответствующий прием). Как и в Router, завершение самого об-
мена  (а не запуска его) требует как минимум, чтобы был запу-
щен соответствующий обмен на  стороне  партнера.  Система  по
прежнему не запоминает сообщений внутри себя, и, если запуще-
на  передача, а приема на противоположном конце нет, передача
никогда не завершится.
     Формат обращения:

        extern int r_write( int /*proc*/,
                          void* /*buffer*/, int /*length*/ );
     - запустить посылку. Первый аргумент - номер процесса, в
который послать, второй - адрес передаваемого массива, третий
- его длина.
     Возвращаемое значение:
      0 - обмен запущен,
     -1 - несуществующий номер процесса,
     -2 - слишком много предыдущих посылок в указанный процесс
не завершено.

        extern int r_read( int /*proc*/,
                         void* /*buffer*/, int /*length*/ );
     - запустить прием. Смысл аргументов  тот  же,  что  и  в
r_write.
     Возвращаемое значение:
      0 - обмен запущен,
     -1 - несуществующий номер процесса,
     -2 - слишком много предыдущих приемов из указанного про-
цесса не завершено.

        extern int w_write( int /*proc*/ );
     -  ждать конца посылки. Аргумент - номер процесса, конца
последней посылки которому ждать, или  специальное  значение,
если ждать не последней посылки (см. ниже).
     Возвращаемое значение:
      0 - несуществующий номер процесса,
      1 - конец посылки.
     Попытка повторно подождать заведомо завершенного обмена
немедленно завершается с кодом 1.

        extern int w_read( int /*proc*/ );
     -  ждать конца приема.  Аргумент - номер процесса, конца
последнего   приема   от   которого  ждать,  или  специальное
значение, если ждать не последнего приема (см. ниже).
     Возвращаемое значение:
      0 - несуществующий номер процесса,
      1 - конец приема.
     Попытка повторно подождать заведомо завершенного обмена
немедленно завершается с кодом 1.

        extern int t_write( int /*proc*/ );
     - проверить, кончилась ли  посылка.  Аргумент  -  как  в
w_write.
     Возвращаемое значение:
      0 - несуществующий номер процесса, или посылка не завер-
шена,
      1 - конец посылки.

        extern int t_read( int /*proc*/ );
     - проверить, кончился ли прием. Аргумент - как в w_read.
     Возвращаемое значение:
      0 - несуществующий номер процесса, или прием не завершен,
      1 - конец приема.

     Для каждой из описанных выше функций имеется  Фортранный
эквивалент,  с тем же именем, но с одним дополнительным пара-
метром СПЕРЕДИ - целочисленным кодом ответа:

     CALL W_WRITE( IRET, N )
     ...
                                               
     ВАЖНОЕ  ЗАМЕЧАНИЕ.  В  отличие от МВС-100, в Router+ для
МВС-1000 имеется очень важное ограничение, нарушение которого
может привести к весьма  печальным  последствиям.  Требуется,
чтобы как адреса участвующих в обмене массивов, так и их дли-
ны  были  кратны четырем (то есть длине int и float). В боль-
шинстве вычислительных программ это  ограничение  выполняется
автоматически.  Наиболее вероятных источников нарушения этого
условия два:
     - передача массивов типа char, структур с полями  такого
типа, и/или их фрагментов,
     - использование для синхронизации (когда важно не содер-
жимое сообщения, а сам факт его прохождения) длины сообщения,
равной 1. К сожалению, на МВС-1000 оба эти приема недопустимы.
     Замечание для пользователей Router МВС-100.
     Из сказанного выше очевидно, как переносить старые прог-
раммы и что дополнительно можно делать в новых.
     Для переноса старых программ:
     1). Замените извлечение информации о собственном  номере
и  числе  процессоров из командной строки на фрагмент, приве-
денный выше, в п. 2,
     2). Исключите обращения  к  grab_server,  ungrab_server,
или замените эти функции "пустышками",
     3). Замените обращения к функциям измерения времени на
описанные ниже, в п. 4.4 (дело в том, что некоторые "стандар-
тные" функции измерения времени бесполезны, поскольку всегда
возвращают "0"),
     4). Проверьте выполнение условий Важного Замечания, при-
веденного выше в настоящем пункте.
     После этого программа должна работать.
     Как пользоваться расширениями:
     1). Возможность передать несколько сообщений  подряд,  а
подождать  конца только последнего обмена, можно использовать
для исключения сборки фрагментов сообщения в один большой бу-
фер перед посылкой, если  число  передаваемых  таким  образом
фрагментов известно заранее и не превышает 16,
     2). Уточнение семантики обменов при расхождении длин  на
приемном и передающем концах позволяет использовать как штат-
ную ситуацию, когда принимается сообщение неизвестной, но за-
ведомо ограниченной длины, а фактическая длина, например, пе-
редается  в  "голове"  сообщения или иным способом может быть
выяснена из его содержимого.
     
4.3. Дополнительные возможности.
     Дополнительные возможности сводятся к возможности подож-
дать завершения не последнего из запущенных обменов и к  воз-
можности установить обработчик завершения обмена.
     Для того, чтобы подождать завершения  произвольного  (не
последнего, вообще говоря, из запущенных в данном направлении
с данным процессором) обмена, необходимо получить при запуске
обмена уникальное число - дескриптор обмена, а затем передать
его  в  качестве  параметра  в  одну из функций синхронизации
вместо номера процессора. Дескрипторы кодируются таким  обра-
зом,  что информация о номере процессора, обмен с которым за-
пущен, содержится в нем, но, в то же время, дескриптор не мо-
жет быть в точности равен номеру какого-либо процессора,  так
что функция синхронизации всегда может разобраться, что имен-
но  от нее требуется. Дескриптор запущенного (r_read/r_write)
обмена можно прочитать сразу после обращения к функции запус-
ка в следующей внешней переменной:
     
     extern int started_handle;
     
     Дескрипторы посылок и приемов в/из один и тот же процес-
сор могут совпадать. Для дополнительной их "подкраски",  если
возникает  такая  необходимость, можно использовать тот факт,
что старший байт дескриптора всегда равен нулю.
     В Router+ также предоставляется  возможность  установить
функцию  обработки  завершения обменов. Данная возможность не
предназначена для использования прикладным программистом  не-
посредственно,  поскольку является, вообще говоря, "опасной",
и в настоящем документе не описывается.

4.4. Измерение времени.
     Функция
     
     extern int _cputime( void );
     
возвращает текущее локальное время в миллисекундах.
     
5. Графический вывод.

5.1. Основные понятия для программиста.
     Доступные прикладной программе внешние переменные и функ-
ции описаны в bgraphic.h. Общая схема работы приводится ниже.
     Перед началом работы следует инициализировать графический
экран. В  принятой  сейчас  реализации на основе системы X это
означает создание окна, в котором будет происходить рисование.
     Это делается обращением к функции

     extern int bgr_init( int mode, int *s_x, int *s_y );

     Здесь mode - номер требуемого графического режима (в сво-
ей нумерации,  принятой в данной библиотеке,  см. ниже), s_x и
s_y - возвращаемые размеры экрана в пикселах.  Функция возвра-
щает значение - код ответа: BGR_OK соответствует успешному за-
вершению, о прочих значениях см. ниже.
     Во всех режимах предполагается дисплей  класса  "псевдоц-
вет" с форматом видеопамяти "1 байт на пиксел". Для управления
палитрой используется функция:

     extern void bgr_setpal( int c, int cr, int cg, int cb );

     Здесь c - значение пиксела,  cr, cg, cb - компоненты цве-
та. Диапазон значений компонент цвета ни к чему не приводится:
значения непосредственно поступают в видеоадаптер.
     Для записи  в  видеопамять строки растра,  сформированной
прикладной программой, используется функция:

     extern void bgr_write( int xto, int yto, int xsize,
                            char *start );

     Здесь (xto, yto) - точка начала строки, xsize - длина за-
писываемой строки, start - указатель на строку.
     Также предоставляется возможность закрасить заданным цве-
том прямоугольник со сторонами, параллельными сторонам экрана:

     extern void bgr_rect( int c, int xmin, int ymin,
                           int xmax, int ymax );

и написать горизонтальную строку текста заданным цветом в за-
данной позиции:
     extern void bgr_text( int c, int xto, int yto,
                           char *string );

     Видеопамять при работе  библотеки  предполагается  дважды
буферизованной  (работа  непосредственно в экран возможна,  но
выглядит довольно некрасиво).  Это значит, что построения про-
изводятся в невидимом буфере, который в некоторый момент копи-
руется на экран,  и все накопленное с момента прошлого копиро-
вания изображение становится видимым.  Такое копирование дела-
ется явно, обращением к функции:

     extern void bgr_flbuf( int xmin, int ymin,
                            int xmax, int ymax );

     Аргументы этой функции задают так называемый динамический
прямоугольник со  сторонами,  параллельными  сторонам  экрана.
Сразу после обращения к bgr_flbuf невидимая видеопамять, в ко-
торой программа формирует изображение, в пределах динамическо-
го  прямоугольника  заполняется  нулями,  а за его пределами -
сохраняется.  Такая схема помогает повысить эффективность  для
некоторых способов двойной буферизации.
     Однопроцессные возможности библиотеки этим исчерпываются.
     Многопроцессные возможности, предоставлявшиеся в ОС-100,
в ОС-1000 не реализованы.

5.2. Предоставляемые режимы и реализации.
     Реализация на базе X-графики - единственная, предоставля-
емая в настоящее время.
     Режимов несколько, чем больше номер, тем большего размера
открывается окно (режим 0 - 320 на 200). Глубина видеопамяти -
всегда требуется 8 бит на пиксел (иначе не произойдет  инициа-
лизация), балльность пушек - 256.