本文档介绍了 XLA 别名 API,您可以通过该 API 指定 构建 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
。
要以编程方式指定别名,请参阅
XlaBuilder::SetUpAlias
API。
在运行时定义别名
上一步中定义的混叠是在编译期间指定的。
在执行过程中,您可以使用
LocalClient::RunAsync
用于选择是否捐赠缓冲区的 API。
程序的输入缓冲区被封装
ExecutionInput
、
而后者又包含一个 MaybeOwningDeviceMemory
树。如果内存
指定为 owning(缓冲区的所有权会传递给 XLA 运行时),
缓冲区实际上是捐赠的,然后就地执行更新,
。
不过,如果在编译时设置了别名的缓冲区没有在
运行时,copy-protection 将发挥作用:分配一个额外的输出缓冲区 O
,
而原本打算设置别名的输入缓冲区 P
的内容会被复制
到 O
中(因此,程序实际上可以执行,就好像缓冲区 O
是
在运行时捐赠)。