В этом документе описывается API псевдонимов XLA, который позволяет указать псевдонимы между входным и выходным буферами при создании программы XLA.
Определение псевдонимов во время компиляции
Например, рассмотрим тривиальный модуль HLO, который просто добавляет 1 к своим входным данным:
HloModule increment
ENTRY entry {
%p = f32[] parameter(0)
%c = f32[] constant(1)
ROOT %out = f32[] add(%p, %c)
}
Этот модуль выделит два 4-байтовых буфера: один для ввода %p и один для вывода %out .
Однако часто желательно выполнить обновление на месте (например, если во внешнем интерфейсе, генерирующем выражение, входная переменная больше не активна после вычисления, как в случае приращения p++ ).
Чтобы эффективно выполнить такое обновление, вы можете указать псевдоним ввода:
HloModule increment, input_output_alias={ {}: 0 }
ENTRY entry {
%p = f32[] parameter(0)
%c = f32[] constant(1)
ROOT %out = f32[] add(%p, %c)
}
Формат указывает, что весь вывод (отмеченный {} ) имеет псевдоним входного параметра 0 .
Чтобы программно указать псевдонимы, см. API XlaBuilder::SetUpAlias .
Определение псевдонимов во время выполнения
Псевдонимы, определенные на предыдущем шаге, указываются во время компиляции . Во время выполнения вы можете использовать API LocalClient::RunAsync , чтобы выбрать, передавать ли буфер.
Входные буферы программы заключены в ExecutionInput , которые, в свою очередь, содержат дерево MaybeOwningDeviceMemory . Если память указана как владеющая (владение буфером передается среде выполнения XLA), буфер фактически передается в дар, и обновление выполняется на месте, как того требует API псевдонимов во время компиляции.
Однако если буфер, которому присвоен псевдоним во время компиляции, не передается во время выполнения, срабатывает защита от копирования : выделяется дополнительный выходной буфер O , и содержимое входного буфера P , для которого должно было быть присвоено псевдоним, копируется в O (настолько эффективно, что программа может выполняться так, как если бы буфер O был передан во время выполнения).