Рубрики Обзоры

Научные вычисления: архитектуры, форматы, инструментарий

Опубликовал ITC.UA

Как бы автору того не хотелось, начинать статью по такой тематике вероятнее всего стоит с эпохальной фразы "Люди добрые, извините, что я к вам обращаюсь…". Действительно, наша суровая реальность оставила теме научных вычислений весьма скромное место в картине "национального компьютинга" — где-то глубоко в тени насущных вопросов офисной автоматизации и бесконечной ист(о/е)рии борьбы с пиратством.


Часть 1

Слишком большая дистанция между общим характером нашего журнала и спецификой темы вынудила автора прибегнуть пусть к спорному, но единственно приемлемому в подобной ситуации приему — полному отказу от каких-либо претензий на объективность, полноту обзора и учебную точность изложения. Взамен всего этого читателю предлагается одна из многих точек зрения как на пригодные к освоению в реальные сроки и с реальными затратами инструментальные средства "научного" назначения, так и на ряд идей, не то чтобы доминирующих в мире научного ПО, но привлекательных "прозрачностью" и простотой. Сразу следует оговориться — все программы, которым будет уделено внимание или просто упомянутые, совершенно легально бесплатны, доступны с исходными текстами и весьма некритичны к платформе. Кроме того, универсальный характер и богатые возможности этих программ расширяют область их применимости далеко за границы классических академических задач. И наконец, последний в перечне критериев, формирующих сугубо субъективный механизм отбора "обозреваемого" ПО и идей, maturity — состояние "зрелости", достигнутое после продолжительного бурного периода роста.

Ситуация

Многочисленные представители обширного класса ПО научного назначения исторически являются и одними из самых ранних программ с открытыми исходными текстами (ОИТ). Еще в эпоху мэйнфреймов сборники научных программ распространялись фактически исключительно в исходных текстах, которые постоянно совершенствовались, дорабатывались и возвращались в академическую среду тысячами "пользователей" (в те времена это понятие было неотделимо от понятия "программист"). Бесспорный факт существования "доисторического" ОИТ-сообщества и бесспорная же сегодняшняя мода на идеи ОИТ, казалось бы, должны были оказать незаменимую помощь в попытке разобраться с современной ситуацией в мире свободного ОИТ ПО научного назначения… На деле, увы, все оказывается строго наоборот. Поток информации о достоинствах/недостатках модели ОИТ сводится более к выражению эмоций ярых апологетов или противников и практически никогда не подтверждается тщательным анализом истории.

Конечно, оптимальным содержанием для этого раздела статьи как раз и был бы график,
отражающий динамику развития ОИТ-проектов научных программ… но это предмет уже
не статьи, а слишком сложного исследования. Поэтому ограничимся коротким перечнем
фактов, оставляя их возможные интерпретации читателю: портал ПО научного назначения
sal.kachinatech.com,
некогда очень популярный и даже знаменитый, не обновлялся с января 2001 г.; портал
разработчиков ОИТ ПО sourceforge.net из примерно 40 тыс. в той или иной степени
актуальных проектов насчитывает около 2,5 тыс. представителей категории Scientific/Engineering
(ПО научного/инженерного класса). Сегодняшние активные проекты, если судить по
данным sourcefoge.net, не
отличаются масштабностью и активностью развития, а наиболее серьезные из них являются
или "реинкарнациями" классического академического ПО (например, знаменитый
алгебраический пакет символьных вычислений Maxima), или "освобождениями"
некогда коммерческих программных систем (IBM Data Explorer).

В целом, сложившуюся ситуацию можно охарактеризовать так: ученые всегда ждали дешевых мощных компьютеров, и вот время "настольных гигафлопсов" наступило… но что-то изменилось — вместо ожидаемого всплеска активности разработчиков ПО научного назначения (который тем более можно было прогнозировать, учитывая глубинные корни идеи ОИТ именно в академической среде) наблюдается, мягко говоря, спад интереса. Эту тенденцию заметил и известный специалист знаменитых Bell Labs Роб Пайк. В одном из своих эссе он говорит: "…Сегодняшние доктора наук используют Unix, X Window, Emacs и TeX… как и 15 лет назад".


Архитектуры

Упоминание о популярности модели ОИТ в научном ПО прозвучало не случайно.
Надо быть очень недальновидным, чтобы не рассмотреть взаимосвязи между моделью
процесса разработки программного обеспечения и доминирующими архитектурами программ.
Свободное распространение ПО на деле играет роль и естественного отбора, при котором
именно "некрасивые" проекты отмирают быстро и безболезненно. Выживают
же не "сильнейшие" в коммерческом смысле (удачно подкрепленные рекламными
кампаниями, эффективной рыночной борьбой с конкурентами и умением привлечь инвестора),
а "красивые" в понимании красоты "по Ефремову" — одновременно
целесообразные и обладающие некоей изюминкой.

Научное ПО демонстрирует почти идеальное соответствие с такой пусть грубой, но вполне правомочной моделью. Ранние разработки были основаны на слоистой (layered) архитектуре, представляющей собой, образно говоря, "надстройки библиотек над библиотеками". Период "слоистого" развития оставил богатейшее наследство — компактный перечень прекрасно выполненных, с отточенными программными интерфейсами библиотек, позволяющих в 90% случаев при решении научных задач не изобретать очередной велосипед. Впрочем, компактным этот перечень стал не сразу, а после того, как количество библиотек достигло какой-то критической отметки, за которой их основным пользователям — "непрофессиональным" программистам — стало практически невозможным сочетать свою основную научную деятельность с изучением растущего с неимоверной скоростью обилия спецификаций…

Спасение от первого проявления эффекта бурного роста было тоже временным — ориентированная на языки архитектура (language-oriented) завоевала быстрое признание в среде разработчиков научного ПО почти сразу после появления доступных инструментальных средств, автоматизирующих генерацию кода целых подсистем трансляторов и интерпретаторов. Возможность эффективно создавать адаптированные к прикладной области специализированные языки использована на 100%, утилиты lex и yacc (генераторы программ лексического и семантического разбора) стали классическими инструментами, знание которых было обязательным даже для "непрофессиональных" программистов. Достижения этого периода развития и сегодня поражают именно красотой реализации и "живучестью" проектов — многочисленные удачные языки управления визуализацией, моделирования и описания данных по сей день составляют основу самых крупных программных комплексов научного назначения.

За периодом language-oriented наступило время "собирать камни" — самостоятельные, удачные, выжившие в ходе эволюции программы, в нечто целое, подчиненное решению поставленной задачи. А так как потребности в ПО каждого отдельно взятого исследователя или высококвалифицированного инженера предугадать (а тем более, — удовлетворить) трудно, то эволюционный процесс нашел достаточно очевидный выход — минимизация затрат на изучение самостоятельной возможности "сборки" приложений с новой функциональностью из уже имеющихся.

Инструментальная поддержка такой привлекательной идеи заключалась в использовании "надъязыка", на техническом сленге именуемого "скриптовым", допускающим применение на языковом уровне сторонних программ фактически как элементов языка. "Скрипт-облатка" писался быстро, потому как сам скриптовый язык доводился до совершенства простоты, а потерями производительности за счет интерпретации можно пренебречь из-за эффективной реализации ресурсоемких фрагментов сторонними программами. Плоды этого периода — не только по сей день правящие миром научного ПО скриптовые языки Scheme и Tcl/Tk, но и звучащие в новых разработках "отголоски" доказавшей свою состоятельность архитектуры "emdedded-extended language based" (основанная на встраиваемом/расширяемом языке). Они "слышны", например, в скриптовом языке Lua — квинтэссенции изящества и архитектурной идеи и реализации (Lua создан именно в академической науке).

Творцы сегодняшнего научного ПО сражаются с новым аспектом сложности, образно именуемым "middleware nightmare" ("кошмаром middleware"). В ход пущены все архитектурные приемы: в больших проектах объектные брокеры прячутся под слоями "упрощающих" библиотек, максимально используются возможности объектно-ориентированного проектирования и программирования (знаменитая инфраструктура поддержки разработки систем визуализации и анализа больших массивов научных данных ROOT насчитывает сгруппированные в 14 категорий 310 классов). И все-таки об определенной закономерности в развитии архитектуры современного научного ПО говорить можно. Де-факто и де-юре стандартные объектные брокеры здесь не в большом почете из-за очень высокой сложности освоения техники программирования, а их функциональность заменяется несоизмеримо более простыми программными шинами (что оправдано и спецификой распределенного научного ПО, но об этом — позже), в данном случае "правят бал" особые форматы данных, и наконец, — основанная на встраиваемых/расширяемых языках архитектура не сдает своих позиций.


"Клей" по-научному

В опубликованной ранее статье ("Компьютерное Обозрение", #
46, 2001
), посвященной программным шинам (ПШ), мы с высоты "птичьего
полета" взглянули на саму идею и потенциальные возможности применения ПШ.
Теперь наступило время знакомства с конкретной реализацией ПШ. Тем более, что
предмет нашего разговора непосредственно касается научного ПО — с ПШ Glish ассоциированы
такие громкие в научном мире названия, как проект "Суперколлайдер",
лаборатория Lawrence Berkeley и Национальная радиоастрономическая обсерватория
США.

Итак, Glish — программная шина, предназначенная для построения распределенных систем обработки научной информации. С архитектурной точки зрения это не "чистая" layered (слоистая) реализация ПШ в виде библиотеки, используемой приложениями. Glish — необычайно удачный гибрид языковой архитектуры и ПШ. Основная идея Glish — создание распределенной системы обработки данных (новой функциональности) на основе имеющихся программ без необходимости их модификации. В отличие от большинства "взрослых" middleware-систем Glish требует минимума как от разработчика программы-компонента, способной занять свое место в будущей системе (точнее, — вообще не предъявляет никаких требований к этому классу программистов, они просто могут забыть о существовании ПШ), так и от "программиста-интегратора", "собирающего" с помощью скриптового языка Glish отдельные программы в нечто целое.

Основное понятие Glish — "событие" (event) — сообщение о том, что что-то произошло и ассоциированные с этим сообщением данные. Например, событие может описываться парой "данные_готовы, data_f.dat", указывающей, соответственно, что некие данные готовы к дальнейшей обработке и располагаются в файле data_f.dat. Glish поддерживает вполне приемлемую для создания интерактивных распределенных систем обработки интенсивность обмена сообщениями — порядка 300—500 в секунду, при этом, естественно, подразумевается, что объединяемые с помощью этой ПШ программы являются или высокоуровневыми ресурсоемкими пакетами, или элементарными, но необходимыми в большой системе механизмами (задающими временные интервалы таймерами и т. д.).

Почувствовать "на вкус" язык и возможности Glish проще всего на фрагментарном примере:

1 tsk1 := client("Calc_FFT", host="andrew")
2 tsk2 := client("Disp_FFT", host="sergei")
3 whenever tsk1->fft_done do
4 send tsk2->fft_done($value)
5 whenewer tsk2->user_controls
6send tsk1-> user_controls($value)

Вызов функции языка Glish с именем "client" принимает два параметра: имя программы и имя машины (хоста), на которой программа будет выполняться. Действие client — запуск указанной в параметрах программы на определенном компьютере. Соответственно, первые две строки нашей "распределенной системы" вызывают запуск двух программ: Calc_FFT (предположим, она "занимается" расчетами быстрого преобразования Фурье, БПФ) — на машине с именем "andrew" и Disp_FFT (программа визуализации спектра, "оснащенная" графическим пользовательским интерфейсом, с помощью которого можно задавать параметры системы обработки) — на машине с именем "sergei". Уникальные в пределах одной сети идентификаторы этих задач записываются в переменные Glish с именами tsk1 и tsk2.

Ключевое слово whenever, весьма экстравагантно переводящееся для ключевых слов языков программирования (дословно — "когда бы ни?"), начинает одну из главных конструкций Glish — описание механизма обмена сообщениями. "По-человечески" третью и четвертую строку нашего Glish-"кода" можно прочитать так:

"когда бы ни отправила программа Calc_FFT (именно ее идентифицирует содержимое переменной tsk1) сообщение о событии готовности результатов расчетов БПФ (fft_done), немедленно переслать сообщение программе Disp_FFT (ее идентификатор содержится в переменной tsk2), передав ассоциированные с ним данные (специальное выражение Glish $value)".

Пятая и шестая строки прочитываются аналогично и вызывают передачу настроек от программы визуализации/управления к программе расчета БПФ.

Для управления потоками сообщений о событиях используется специальная выделенная подсистема (сервер), именуемая в терминах Glish "секвенсором" (sequencer, автор счел "музыкальный" вариант перевода наиболее уместным). Секвенсор Glish является одновременно и сильной и слабой стороной этой ПШ — в случае необходимости обмена сообщениями о событиях с большими объемами ассоциированных данных секвенсор превращается в "бутылочное горлышко". Но и эта проблема в Glish решается очень просто: ПШ допускает непосредственные соединения между программами (P2P), для создания которых достаточно воспользоваться ключевыми словами link … to … (соединить … с …). В нашем примере для организации соединения P2P между Calc_FFT и Disp_FFT необходимо в скрипте указать фразу:

link tsk1->fft_done to tsk2-> fft_done($value)

P2P-соединения могут быть разорваны командой unlink, могут создаваться динамически, в зависимости от размеров ассоциированных с сообщением данных.

Кроме "святая святых" Glish — механизма событий, этот язык во всем соответствует требованиям к современным скриптовым языкам: динамическая типизация, масса встроенных типов данных, включающие комплексные числа двойной точности, векторы данных всех базовых типов, записи (структуры), изящно реализованный механизм атрибутов данных.

О нем стоит сказать два слова, точнее — привести короткий пример. Описание и инициализация вектора целых чисел на Glish выглядит так:

matrx := [1,2,3,4,5,6,7,8,9]

Предположим, что нам нужен не вектор, а матрица 3 3, но пока мы располагаем только знаниями о поддержке описаний векторов. Как быть? Учитывая, что в случае скриптового языка-"облатки" вся эта информация нужна исключительно для служебных целей (формирование и передача параметров между различными программами), в Glish реализован так называемый механизм "произвольных атрибутов" — дополнительной информации, "присоединенной" к значению данных с помощью оператора "::"

matrx::size := [3,3]

Мы "присоединили" к данным, хранящимся в настоящий момент в переменной matrx, дополнительный атрибут с именем size. Имена атрибутов и их количество выбираются программистом фактически произвольно — система не предъявляет к ним каких-либо существенных требований. При "перемещении" данных из переменной в переменную атрибуты, естественно, не утрачиваются (благодаря динамической типизации и реализации переменных как контейнеров, способных хранить данные любого типа). Проверка всего перечня атрибутов, ассоциированных с данными, осуществляется с помощью того же оператора "::" (в унарной правосторонней записи). Для нашего примера она может выглядеть так:

atributes := matrx::

После выполнения этой команды переменная atributes будет содержать запись из всех пар имен атрибутов и их значений.

Еще одна интересная особенность этой конструкции языка — возможность создания
атрибутов… для атрибутов (в терминах Glish — каскадирование атрибутов), что
позволяет эффективно моделировать скромными типами данных "вектор" и
"запись" исключительно сложные иерархические структуры, свойственные
научным приложениям.

Кроме перечисленных уже типов данных, в Glish реализованы и многомерные массивы с операциями выделения срезов (на основе описанных "фокусов" с атрибутами, потому и без специальных арифметических операций), и ссылки — безопасные аналоги указателей. Впрочем, вычисления с большими массивами — неподходящая задача для решения ее с помощью интерпретируемого языка (на самом деле это высказывание не всегда истинно, в чем мы убедимся, рассматривая в дальнейшем языки быстрого прототипирования научных приложений), но в случае необходимости Glish поддерживает эффективную реализацию поэлементного итератора для векторов.

Во всем остальном язык Glish синтаксически максимально приближен к самому распространенному языку программирования C (с подобной особенностью мы еще не раз столкнемся в последующих статьях цикла), что существенно облегчает его изучение.

Мощный механизм поддержки так называемых "асинхронных клиентов" позволяет с помощью Glish создавать "облатки" к программам, работающим исключительно со стандартными потоками ввода/вывода, разработчики которых, возможно, и не подозревали о существовании программных шин. Например, следующие две строки на Glish превращают обыкновенную Unix-утилиту ls (выводящую в стандартный поток вывода содержимое текущего каталога файловой системы) в полноценный элемент распределенной вычислительной системы:

cl_ls := "ls '$1'"
ls_cl := shell(cl_ls, async=T)

Такая "клиент-серверная модификация" ls может "принимать" сообщения о событиях, посланные ей Glish с помощью такой записи:

ls_cl->stdin('параметр')

и автоматически генерировать сообщения о событии "на стандартном выходе программы появились данные", которое в Glish записывается в уже знакомой форме:

whenever ls_cl->stdout do...

Теперь наступила пора самого интересного — подтверждения предположений, сделанных в начале статьи. Мы говорили об оправданном стремлении разработчиков научного ПО к сокращению сложности и объясняли это стремление пригодностью технологии к использованию "непрофессиональными" программистами — специалистами, для которых программирование является одним из способов достижения собственных целей, а не основной профессией. Реализация Glish — очень удачный пример хотя бы потому, что, несмотря на огромные возможности всей ПШ, она основывается на скромной C++ программе всего из… 2 тыс. строк! Типовые "скрипты-облатки" для готовых программ требуют написания нескольких десятков—сотен строк на языке Glish, в низкоуровневых клиентских программах (использующих библиотечные вызовы Glish) специфический для этой ПШ код занимает буквально несколько десятков строк.

Контент сайту призначений для осіб віком від 21 року. Переглядаючи матеріали, ви підтверджуєте свою відповідність віковим обмеженням.

Cуб'єкт у сфері онлайн-медіа; ідентифікатор медіа - R40-06029.