-mpmd-absorb-inferred-fragments

Фрагменты корня поглощают предполагаемые фрагменты.

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

  • фрагмент пользователя или
  • не используется никаким другим фрагментом (например, фрагмент, используемый только для обратной операции или передачи), или
  • не является пользователем значений, полученных каким-либо другим фрагментом (например, пользователем аргументов блока или передач).

Для этого в процессе выполнения применяются следующие шаблоны до достижения фиксированной точки:

(1) Если для корневого фрагмента rf существует выведенный фрагмент ipf такой, что ipf является производителем rf , а rf является ближайшим потребителем ipf , то ipf объединяется с rf .

И вдвойне:

(2) Если для корневого фрагмента rf существует предполагаемый потребитель icf такой, что icf является потребителем rf , а rf является ближайшим производителем icf , то icf объединяется с rf .

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

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

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

Параметры

-absorb-on-entry-point-function : Whether to absorb inferred fragments into user-defined fragments on entry-point functions, in addition to targets of mpmd.calls.

-mpmd-call-inline

Встраивает все операции mpmd.call .

Встраивает операции mpmd.call , копируя их атрибуты во все встраиваемые операции.

-mpmd-copy-constants

Копирует константы, созданные в одном фрагменте, для их потребителей.

Копирует константы из фрагментов-производителей в фрагменты-потребители, возможно, посредством передачи.

Пример:

%f = fragment () () {
  return constant
}
%t = transfer %f
fragment (%t) (%arg) {
  op(... %arg ...)
  ...
}

 ~~>

%f = fragment () () {
  return constant
}
%t = transfer %f
fragment (%t) (%arg) {
  %c = constant
  op(... %c ...)
  ...
}

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

-mpmd-erase-unused-callee-block-arguments

Удаляет все аргументы блока вызова mpmd, которые не используются в вычислениях (hlo).

Удаляет неиспользуемые аргументы блока из функций, вызываемых с помощью mpmd.calls. Мы считаем аргумент блока неиспользуемым, если он не используется или используется только терминатором функции, то есть если он не используется ни одним вычислением hlo.

-mpmd-fragment-dce

Удаляет неиспользуемые аргументы/результаты фрагментов и упрощает области фрагментов.

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

-mpmd-fragment-dedup

Удаляет все повторяющиеся операнды и приводит к получению фрагментов.

Удаляет все повторяющиеся используемые аргументы и результаты во фрагментах. При этом повторяющиеся аргументы и результаты останутся неиспользованными. Для удаления неиспользуемых аргументов и результатов следует выполнить дополнительные проходы.

-mpmd-from-unroll-to-call-counter

Преобразует атрибут счетчика развертывания вызова в атрибут счетчика вызовов.

Если операция вызова имеет атрибут unroll_counter , этот проход заменяет его атрибутом call_counter . Это необходимо в случаях, когда последовательность вызовов является результатом развертывания цикла в MLIR (например, с помощью -mpmd-unroll-for-loops ), а не развертывания цикла на уровне Python.

-mpmd-merge-forward-with-backward

Объединить прямые фрагменты с обратными фрагментами.

Объединить прямой фрагмент производителя с обратным фрагментом потребителя, если первый находится непосредственно перед вторым. Это справедливо только для последнего этапа в расписании 1F1B, поэтому объединение фрагментов на предыдущих этапах не произойдет, что является запланированным поведением.

-mpmd-merge-inferred-fragments

Объединяет предполагаемые фрагменты с фрагментами, заданными пользователем.

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

Параметры

-merge-any-consumer : Whether to merge with any consumer or only the closest consumer.
-merge-sideways     : Whether to merge with the next fragment in the same mesh (neighbor), even if not a consumer.

-mpmd-merge-transfers

Объединяет наборы трансферов, имеющие общие фрагменты производителя и потребителя.

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

Объединение набора трансферов означает: конкатенацию переданных значений на стороне производителя и их разделение на стороне потребителя.

-mpmd-merge-user-fragments-into-scheduling-units

Объединение фрагментов, созданных на основе пользовательских данных, перед этапами планирования конвейера.

Объединяет пары определяемых пользователем фрагментов для совместного использования в процессе планирования конвейера.

-mpmd-move-transfers-to-producer

Переводы игроков происходят рядом с их продюсерами.

Перемещает передаваемые данные рядом с их производителями: если операнд является аргументом блока, перемещает передаваемые данные в начало блока, в противном случае перемещает их после определяющей операции.

-mpmd-remove-transfer-cycles

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

Удаляет циклы передачи данных.

Например, в символической форме:

x1 = transfer(x0) : m0 -> m1 x2 = transfer(x1) : m1 -> m2 x3 = transfer(x2) : m2 -> m3 x0_1 = transfer(x3) : m3 -> m0 x1_1 = transfer(x0_1) : m0 -> m1

~~>

x1 = transfer(x0) : m0 -> m1 x2 = transfer(x1) : m1 -> m2 x3 = transfer(x2) : m2 -> m3 x0_1 = x0 x1_1 = x1

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

Следует отметить, что это может увеличить нагрузку на память, поскольку передача данных туда и обратно означает период, когда данные отсутствуют на устройстве. Поэтому мы делаем это только в том случае, если цикл содержит только передачу данных между устройствами, например, поскольку цикл device -> host -> device может использоваться для экономии памяти.

В этом варианте не используется канонизатор MLIR, поскольку он не гарантирует канонизацию всего содержимого, а также его применение обходится дороже.

-mpmd-rule-based-merge

Объединяет фрагменты на основе заданных пользователем правил.

Объединяет фрагменты на основе указанного списка правил, каждое из которых определяет список исходных фрагментов для объединения (на основе информации о фрагменте) и целевую информацию для маркировки объединенного фрагмента.

Параметры

-rules                       : A list of fragment merge rules, each with a list of source fragment infos and a target fragment info.
-remove-control-dependencies : Whether to remove control dependencies at the end of the pass.

-mpmd-scheduling-units-verifier

Проверяет, содержит ли программа необходимые модули планирования.

-mpmd-sink-negligible-ops-into-call-op

Включает незначительные операции в операции вызова (т.е. в вызываемую функцию).

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

-mpmd-split-and-prioritize-transfer-independent-computations

Разделяет обратные фрагменты на основе переданных результатов.

Разделяет фрагмент на два фрагмента, чтобы мы могли начать вычисления раньше. То есть мы разделяем фрагмент на два фрагмента A -> B, где A не зависит от результатов передачи и является максимально большим, а B зависит от результатов передачи.

-mpmd-split-bwd-fragments

Разделяет обратные фрагменты на основе переданных результатов.

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

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

-mpmd-uniquify-function-inputs-outputs

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

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

def f(x):
  y = x + x
  return y, y

z1, z2 = f(5)
z1 += 1
print(z1) ~~> 6
print(z2) ~~> 5

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

Параметры

-use-transfer-instead-of-fragment : Whether to use mpmd.transfer or mpmd.fragment for uniquification

-mpmd-unroll-for-loops

Полностью разворачивает циклы mpmd.for .

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

Требуется, чтобы коэффициент развертывания был равен количеству итераций.

-mpmd-verify-stage-merging

Проверяет, успешно ли выполнено слияние фрагментов, отнесенных к этапам.

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

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

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