LINUX.ORG.RU

Связать версии кода с версиями используемой библиотеки

 ,


0

0

Привет Лорчик!

У меня есть некая библиотека на Python, предоставляющяя инструменты для численного решения определенной задачи. Используя эту библиотеку, я провожу вычислительные эксперименты, результаты которых затем проверяются в лаборатории.

Формулировка эксперимента состоит из большого числа параметров и некоторой логики его проведения, поэтому проще всего зафиксировать конкретный эксперимент в виде коммита, который его воспроизводит. Библиотека, используемая в экспериментах, активно развивается и изменения в библиотеке могут также повлиять на результаты экспериментов. Поэтому постановку каждого эксперимента нужно фиксировать вместе с кодом (или версией кода) используемой библиотеки.

На данный момент все эксперименты зафиксированы как «висячие» коммиты в репозитории кода библиотеки. Т.е. от определенного коммита отходит несколько веток, содержащих по одному коммиту. Для удобства фильтрации логов используется определенная система тегов для численных экспериментов (т.е. коммитов, которые не вносят изменений в библиотеку, а просто генерируют некие артефакты с ее использованием).

Вопрос следующий: какие модифицировать данный workflow, чтобы численные эксперименты можно было вынести из репозитория библиотеки и при этом не потярять связь между кодом экспемента и кодом библиотеки? Желательно иметь удобный механизм для перезапуска экспериментов на разных версиях библиотеки.

★★★★★

Все это делается для воспроизводимости и наглядности причино-следственных связей.

Для воспроизводимости я планирую оперировать только версией кода моей основной библиотеки и кодом эксперимента. Сторонние библиотеки, используемые докер образы и т.д. фиксировать не планирую.

aquadon ★★★★★ ()

По-моему подход неправильный со всех сторон.

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

Для разных экспериментов лучше использовать разные директории с кодом, и если несмотря на всё вышесказанное ты хочешь параллельно пользоваться разными версиями библиотеки - можно в сборочный скрипт программ добавить подтягивание нужной её версии.

firkax ★★ ()

поэтому проще всего зафиксировать конкретный эксперимент в виде коммита

git головного мозга? Проще всего — каждый эксперимент в отдельном файле с кратким его описанием, конфигом, тегами, ссылкой на результаты, варева… и версией библиотеки, конечно (ссылкой на git-снепшот, например).

В отдельном файле или sqlite-БД можешь собирать краткий индекс, по которому затем искать свои эксперименты.

anonymous ()

git submodules для чего-то такого и придуманы, но последнее предложение топика все портит.

thesis ★★★★★ ()
Последнее исправление: thesis (всего исправлений: 1)

Если для эксперимента используются либы на компилируемых языках (типа C, C++, Fortran) и используется fpu то тогда эксперимент может не воспроизводиться т.к. считаться оно может немного не так. https://godbolt.org/z/sP19zP например.

SZT ★★★★★ ()
Ответ на: комментарий от firkax

если от доработки библиотеки изменились результаты - надо пересматривать ранее посчитанное и понять, была ли эта доработка исправлением ошибок или их добавлением

В частности, из этих соображений я и пересматриваю подход.

Однако, по поводу

не надо параллельно несколько версий использовать

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

aquadon ★★★★★ ()
Последнее исправление: aquadon (всего исправлений: 1)
Ответ на: комментарий от anonymous

Проще всего — каждый эксперимент в отдельном файле с кратким его описанием, конфигом, тегами, ссылкой на результаты, варева… и версией библиотеки, конечно (ссылкой на git-снепшот, например).

Можно и так, но к численным экспериментам сейчас прикручен CI/CD и отказываться от него не хочется. Через коммиты в репозитории это делается проще всего. В частности и на результаты ссылка удобно генерируется, т.у. они все складываются по хешу коммита.

aquadon ★★★★★ ()
Последнее исправление: aquadon (всего исправлений: 2)
Ответ на: комментарий от SZT

используется fpu то тогда эксперимент может не воспроизводиться

Это я знаю, спасибо. Именно поэтому нет перепроверять результаты должен человек.

aquadon ★★★★★ ()

Вопрос следующий: какие модифицировать данный workflow, чтобы численные эксперименты можно было вынести из репозитория библиотеки и при этом не потярять связь между кодом экспемента и кодом библиотеки?

Лучше пусть репа с экспериментами содержит сабмодулем репу с библиотекой. Переверни вложенность

Поэтому постановку каждого эксперимента нужно фиксировать вместе с кодом (или версией кода) используемой библиотеки

Во внешней репе git add lib_dir перед коммитом с экспериментом

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

Во внешней репе git checkout <commit1>; cd lib_dir; git checkout <commit2>

Crocodoom ★★★★★ ()

Формулировка эксперимента состоит из большого числа параметров и некоторой логики его проведения

А логику нельзя вынести в отдельный файл и держать его вместе с параметрами эксперимента? Уж что-что, а python это позволяет делать (importlib). А то как-то странно. Если в библиотеке была какая-то ошибка, например, забыли в уравнениях в квадрат возвести, то надо ошибку исправлять, переделывать моделирование, и если результаты поменялись, то грош цена результатам из предыдущей версии. Если уравнения меняются от эксперимента к эксперименту, то выносим их в отдельный модуль, как я выше написал.

knovich ()
Ответ на: комментарий от knovich

А логику нельзя вынести в отдельный файл и держать его вместе с параметрами эксперимента?

Логика эксперимента описана вместе с его параметрами в коде, который запускает эксперимент.

А то как-то странно. Если в библиотеке была какая-то ошибка, например, забыли в уравнениях в квадрат возвести, то надо ошибку исправлять, переделывать моделирование,

Не совсем так. Таких грубых ошибок, надеюсь, уже нет в библиотеке. Но в модель все еще могут быть внесены изменения, которые немного повлияют на результаты.

и если результаты поменялись, то грош цена результатам из предыдущей версии.

Тоже не совсем так. Если результат вычислений будет бессмысленным, то я его отброшу и буду искать ошибку. Если же получилось нечто правдоподобное и по эти данным были проведены эксперименты в лаборатории, то эти данные нужно хранить и учитывать в дальнейшей работе. Даже если при доработке библиотеки результаты того-же численного эксперимента слегка меняются.

aquadon ★★★★★ ()
Ответ на: комментарий от aquadon

Логика эксперимента описана вместе с его параметрами в коде, который запускает эксперимент.

Я это понял. Я предложил хранить ту часть, которая отвечает за логику, в отдельном небольшом модуле, который хранится вместе с файлом параметров эксперимента. А основная программа пускай подключает модуль динамически и подтягивает логику оттуда. Это, конечно, очень небезопасно, вдруг в модуле будет код для скачивания malware, но если мы доверяем пользователю, то почему нет?

Или там логики на две тысячи (или два миллиона) строк, и в произвольном месте может быть изменение (ключевое слово здесь «произвольное»)? Тогда я, конечно, не знаю, но мне кажется, надо бы реорганизовать.

А что за модель (эксперимент)?

knovich ()
Ответ на: комментарий от knovich

А что за модель (эксперимент)?

Лазерная сварка алюминиевых сплавов. Для проведения эксперимента нужно привести тестовую установку в нужную конфигурацию, откалибровать фокус лазера и высокоскоростных камер. После выполнения непосредственно сварки нужно обработать и исследовать под микроскопом образцы, сделать снимки, обработать видео с высокоскоростных камер и т.д. В общем, достаточно геморройный процесс.

aquadon ★★★★★ ()

Я бы разделил код на три условных «компонента»: «библиотека», «запускалка экспериментов» и «входные данные»

Их всех физически разделить на три git-репозитория. «Запускалку» можно считать главным и подключить «библиотеку» и «входные данные» через менеджер зависимостей. Если это сделать сложно, то можно подключить «библиотеку» и «входные данные» как субрепозитории, тогда можно четко версионировать все по-отдельности

nikolnik ★★★ ()
Ответ на: комментарий от knovich

И сколько примерно строк в библиотеке, вместе с параметрами какого-то конкретного эксперимента?

Примерно 2500 строк в библиотеке и 100-500 строк описание одного эксперимента (или серии связанных экспериментов).

aquadon ★★★★★ ()
Ответ на: комментарий от nikolnik

Я бы разделил код на три условных «компонента»: «библиотека», «запускалка экспериментов» и «входные данные»

Да, я тут подумал и решил сделать примерно также. Библиотеку оставлю в своем репозитории саму по себе, чтобы не было лишних коммитов, которые не относятся к ее непосредственной разработке.

Эксперименты постараюсь сгруппировать насколько эти имеет смысл, чтобы можно было вынести часть их постановки в простой список параметров для определенной группы.

Чтобы не переусложнить систему количеством возможных исходов («количество экспериментов» х «количество версий библиотеки»), буду ориентироваться на автоматизированный запуск экспериментов на последней стабильной версии библиотеки. Для полной воспроизводимости тех артефактов, на основе которых были проведены лаборатоные эксперименты, буду просто сохранять вместе с ними хеш задействованного коммита библиотеки. Или даже полную команду, необходимую для точного воспроизведения артефакта, включая скрипты с логикой, параметры и докер-образ, в котором это все должно работать.

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

aquadon ★★★★★ ()
Ответ на: комментарий от aquadon

Мне кажется, что если в любом месте из 2500 строк может быть произвольная модификация, то это уже сложно охватить мыслью. Я поддерживаю комментарий Связать версии кода с версиями используемой библиотеки (комментарий)

Надо разделять. Например, логика запускалки будет такой: сначала подключаем один модуль из библиотеки, который задаёт форму импульса (я не знаю, там у вас импульсный или непрерывный режим, но пусть так), обсчитываем распространение импульса в среде, параметры которой тоже как-то заданы. Понятно, что распространение импульса у вас считается всё время по одним уравнениям. Если это не так, то уравнения тоже можно отдельно задавать в другой функции модуля. Потом идёт часть, отвечающая за остывание вашего образца, там тоже более-менее постоянная модель, а меняются, может, какие-то граничные условия, которые, опять же, подключаются из другого модуля. При отсутствии того или иного модуля пусть будет некая функция по умолчанию. Как-то так.

Самое главное, что в запускалку уходят все процедуры, отвечающие за чтение параметров и вывод результатов, и вообще всё взаимодействие с пользователем. Если потом возникнет желание добавить какой-то новый формат данных, то все старые эксперименты можно будет запустить на новой версии. А сейчас придётся писать отдельную программу для преобразования, чтобы запускать старые эксперименты, либо как-то париться с гитом, но мне кажется, оно того не стоит.

P.S. опоздал, ну ладно.

knovich ()
Последнее исправление: knovich (всего исправлений: 1)
Ответ на: комментарий от knovich

Да, ты все правильно описал. Проблема в том, что при имеющейся сложности модели и огромном количестве параметров, приходится прикладывать нехилые умственные усилия, чтобы свести численно-лаборатоные испытания в понятную структурированную систему.

В общем, ушел думать и писать код. Всем отписавшимся спасибо.

aquadon ★★★★★ ()
Ограничение на отправку комментариев: только для зарегистрированных пользователей