(первоначально опубликовано в 2015 году на сайте bionics.it)

Как только поднимается тема научных рабочих процессов, всегда найдется несколько поклонников Make, горячо настаивающих на том, что проблема рабочих процессов решена раз и навсегда с помощью GNU make, впервые написанного в 70-х годах :)

Лично я не был так уверен. С одной стороны, я знаю, что инструмент решает множество проблем для многих людей. Кроме того, есть что-то очень привлекательное в построении инструмента, который, как вы можете быть уверены, будет доступен более или менее во всех unix-подобных операционных системах в ближайшие десятилетия.

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

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

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

Они перечисляют проблемы по трем основным категориям:

  • Файлы представлены строками
  • [Проблемы с] комбинаторными зависимостями
  • Непредставимые структуры зависимостей.

Ниже я приведу некоторые избранные части по каждой из категорий.

Файлы представлены строками

«… с нашей точки зрения, make — это декларативный язык для указания зависимостей. Кажется, это именно то, что нам нужно, и действительно решает некоторые проблемы, описанные выше. Однако у make есть несколько новых проблем, из-за которых он не является идеальным решением нашей проблемы».

«…есть три серьезные проблемы…»

«Основная проблема здесь заключается в том, что файл представляется строкой, его именем. Для машинного обучения и экспериментов по обработке естественного языка гораздо более естественно представить файл в виде набора пар ключ-значение. …”

[Проблемы с] комбинаторными зависимостями

«Вторая проблема с make заключается в том, что очень сложно указать комбинаторные зависимости. Если продолжать писать make-файл, описанный выше, в конечном итоге потребуется написать конечную цель all, чтобы указать все файлы, которые необходимо собрать. Таких файлов 60 […] Нет простого способа перечислить эти 60 файлов естественным образом. Можно перейти к сценарию оболочки или использовать функцию foreach из GNU make, но оба способа запутаны».

Непредставимые структуры зависимостей

«Последняя проблема с make также связана с зависимостями. Это более тонко, но оказывается, что есть некоторые виды структур зависимостей, которые не могут быть представлены в make. Предположим, я хочу сравнить эффект от использования одного из трех синтаксических анализаторов, одного из трех анализаторов частей речи и одного из трех фрагментаторов для эксперимента по суммированию. Это включает в себя три отдельных трехсторонних различия в make-файле, где для каждого из них могут быть запущены три разные команды. Неработающий пример показан на рис. 3. Проблема в том, что правила шаблона make (правила, использующие символ %) могут соответствовать только суффиксу или префиксу имени файла. Этот make-файл не работает, потому что он требует, чтобы синтаксический анализатор, блокировщик и тегировщик были последней частью имени файла перед суффиксом типа».

Но в любом случае, взгляните на бумагу сами! :)

Некоторые комментарии

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

Он может не полностью попасть в точку со всем описанием проблемы. Например, я не думаю, что на основе имени файла или на основе параметра есть проблема, если у вас просто есть мощный механизм шаблонов имен файлов, который позволяет вам свободно и гибко включать имена и значения параметров в любое желаемое место в файле. шаблон имени файла. Так обстоит дело, например, в Инструменте рабочего процесса Spotify Luigi, который мы использовали в нашей работе на pharmb.io.

Однако два других момента, касающиеся некоторых шаблонов графов зависимостей, с которыми непрактично работать, похоже, близко касаются сути проблемы. как я упоминал ранее, в Make вы должны указать шаблон имени файла результирующего набора данных, чтобы управлять правилами/задачами upstream.

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

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

Интересно, что этот подход используется в таких инструментах, как NextFlow, и, по-видимому, в несколько более ограниченной степени в таких инструментах, как BPipe. (EDIT: И обязательно в нашей новой библиотеке на Go SciPipe).

Следует отметить, однако, что SnakeMake на основе Python предоставляет некоторые конструкции, которые делают некоторые из проблем, описанных выше, намного более решаемыми для реализации, даже несмотря на то, что базовый механизм выполнения основан на вытягивании, как и в самой make (вы указываете желаемый шаблон целевого файла для управления восходящими задачами), но он имеет гораздо лучшую обработку именованных входных и выходных данных, чем GNU make, а также более мощный механизм интерполяции шаблона файла, где вы можете использовать код Python для интерполяции шаблона файла любым способом.

Будем надеяться, что в будущем мы увидим больше инструментов рабочего процесса, вдохновленных потоком данных, а пока следите за NextFlow, BPipe и (также SnakeMake, если вы можете жить с его механизмом, основанным на вытягивании)!

// Самуил

ОБНОВЛЕНИЕ: я должен уточнить, что проблемы, обсуждаемые ниже, не относятся к некоторым способам работы с make, таким как этот интересный метод Пьера Линденбаума, где make-файл генерируется из XML description, таким образом используя make как своего рода язык ассемблера, в который компилируются определения рабочего процесса более высокого уровня. Пьер упоминает здесь еще несколько проблем с make.

(первоначально опубликовано в 2015 году на сайте bionics.it)