Разработка и применение программного обеспечения в физических исследованиях
Вячеслав Федоров, ИЯФ СО РАН
Учебное пособие для студентов второго курса, обучающихся по направлению «Прикладная математика и физика».
Предмет книги
Программирование стало основным инструментом работы физика. Установка управляется кодом, данные обрабатываются кодом, результат в статье получен кодом. Качество этого кода определяет, можно ли доверять результату.
Обучение программированию осуществляется по остаточному принципу. На первом курсе студенту показывают синтаксис языка. О том, как организовать проект, как убедиться, что программа считает правильно, как обеспечить, чтобы через год в ней разобрался коллега, обычно не говорят. В результате появляются скрипты, работающие только у автора, только на его данных и только до первого изменения.
Программа, выполняющая некоторый расчёт, пишется за вечер. Чтобы посчитанному можно было доверять, а расчёт был воспроизводимым, требуется дисциплина. Этой дисциплине и посвящено настоящее пособие.
От общего курса программирования пособие отличается материалом, подобранным под задачи физического эксперимента: в нём разбираются работающие коды установок, а не учебные примеры.
Предполагается, что читатель знаком с основами программирования и с математическим аппаратом первого курса, то есть с анализом и линейной алгеброй. Всё остальное рассматривается по ходу изложения.
Результаты изучения пособия
В результате изучения пособия студент должен уметь:
- Пользоваться ИИ-помощниками и контролем версий. Языковые модели с пониманием того, где они помогают, а где вредят; Git как рабочий инструмент.
- Работать в GNU/Linux. Устройство системы, файловые системы, процесс загрузки, инструменты командной строки и диагностика неполадок: без этого минимума работа на вычислительном кластере невозможна.
- Владеть Python. Устройство объектов и коллекций, функции, декораторы, классы, генераторы и цена, скрытая за каждой операцией.
- Понимать алгоритмы и структуры данных. Это позволяет оценивать, справится ли расчёт с заданным объёмом данных, и выбирать подходящую структуру.
- Применять инженерные практики. Жизненный цикл программы, тестирование, превращение скрипта, написанного за вечер, в приложение, поддерживаемое годами, сети и базы данных.
- Обрабатывать и анализировать данные. NumPy, pandas, визуализация, классические алгоритмы машинного обучения и нейронные сети.
- Ускорять программы. Профилирование, многопоточность и GIL, асинхронность, вычисления на графических ускорителях.
- Читать чужой код. Разбор реальных программ, с помощью которых выполняются физические расчёты в институтах СО РАН, и одного веб-сервиса, взятого без физики, чтобы за ней не скрывалась архитектура, — вместе с заложенными в них компромиссами и с решениями, которые сегодня были бы приняты иначе.
Структура книги
Порядок частей продиктован зависимостями между ними.
Сначала рассматриваются инструменты: помощники на языковых моделях и контроль версий. Затем операционная система, от загрузки до устройства ядра, и контейнеры, основанные на его механизмах. Далее сам язык, его объекты, коллекции и классы, а следом алгоритмы и структуры данных, примеры для которых на этом языке и написаны. Инженерные практики идут после: жизненный цикл программы, требования к коду, сети, базы данных. Завершается пособие работой с данными эксперимента, ускорением расчётов, разбором реальных программ, написанных в институтах СО РАН, и заданиями для самостоятельной работы.
Читать пособие рекомендуется последовательно, поскольку главы опираются друг на друга. Если какая-либо тема требуется немедленно, достаточно воспользоваться оглавлением и перекрёстными ссылками.
Читать пособие без клавиатуры не рекомендуется. Каждый пример имеет смысл набрать самостоятельно, изменить и проанализировать результат. Задания в конце пособия предназначены именно для этого.
Интерпретация замеров времени
В пособии приведено много измерений вида «эта версия быстрее в сто раз» или «на миллионе элементов уходит две секунды».
Рассматривать следует отношения, а не секунды. Абсолютное время ничего не значит без указания машины, на которой оно получено: тот же код на ноутбуке пятилетней давности и на серверном процессоре даёт числа, отличающиеся в разы. Утверждение «Numba ускоряет этот цикл в сто раз» от процессора не зависит, а утверждение «эта функция считается 14 секунд» зависит. Все выводы в пособии построены на отношениях, и именно их целесообразно проверять, запуская код на собственной машине.
Одно и то же измерение, повторённое подряд, даёт разные числа, поскольку на результат влияют кеш процессора, сборщик мусора, фоновые процессы и троттлинг, снижающий частоту при нагреве. Поэтому замер повторяется многократно: %timeit в IPython показывает среднее и стандартное отклонение по семи прогонам, а timeit.repeat из стандартной библиотеки возвращает серию замеров, из которой берётся минимум. Единичного замера недостаточно: если два варианта различаются на десять процентов, а разброс составляет двадцать, измерение не даёт никакой информации. В экспериментальной физике число не приводят без погрешности и условий опыта; то же относится к производительности программ.
Электронная версия
Пособие поддерживается в актуальном состоянии в электронном виде, где собраны полные листинги, интерактивные графики и исправленные опечатки:
- Текст книги: https://phys-dev.github.io/soft-dev-book/
- Исходники и задания: https://github.com/phys-dev
Там же размещено приложение с экспресс-курсом по основам языка, NumPy и Matplotlib, в печатное издание не вошедшее: пересказывать документацию на бумаге нецелесообразно.
Замеченные ошибки и предложения направляются в issues репозитория; они будут учтены в следующем издании.