Funsor 工厂

class Fresh(fn)[source]

基类: object

make_funsor() 装饰函数的类型提示。这提供了关于新鲜变量(名称)和返回类型的提示。

示例

Fresh[Real]  # a constant known domain
Fresh[lambda x: Array[x.dtype, x.shape[1:]]  # args are Domains
Fresh[lambda x, y: Bint[x.size + y.size]]
参数

fn (可调用对象) – 一个 lambda 函数,接受命名参数(顺序不限),这些参数将填充为装饰函数中同名 funsor 参数的域。此 lambda 应根据参数的域计算所需的最终域。

class Bound[source]

基类: object

make_funsor() 装饰函数的类型提示。这提供了关于绑定变量(名称)的提示。

class Has(bound)[source]

基类: object

make_funsor() 装饰函数的类型提示。

此提示断言一组 Bound 变量始终出现在被标注参数的 .inputs 中。

例如,我们可以编写一个命名为 matmul 的函数,该函数断言两个参数始终包含被归约的输入,并且不能相对于该输入保持不变。

@make_funsor
def MatMul(
    x: Has[{"i"}],
    y: Has[{"i"}],
    i: Bound,
) -> Fresh[lambda x: x]:
    return (x * y).reduce(ops.add, i)

这里的字符串 "i"xy 的标注中指的是我们 MatMul 函数的参数 i,该参数已知是 Bound(即它不出现在评估 Matmul(x, y, "i").inputs 中)。

警告

此标注是实验性的,将来可能会被移除。

请注意,由于 Funsor 本质上是外延的,违反 Has 约束只会引发一个 SyntaxWarning,而不是完整的 TypeError,而且即使如此也仅在 reflect() 解释下发生。

因此,应谨慎使用 Has 标注,仅限于程序员完全控制函数输入且知道某个参数将始终依赖于绑定变量的情况,例如在编写一次性 Funsor 项来描述神经网络中的自定义层时。

参数

bound (集合) – 一个 set,包含 make_funsor() 装饰函数中的 Bound 参数的名称字符串。

make_funsor(fn)[source]

一个装饰器,用于动态创建一个 Funsor 的子类,并附带一个默认的即时(eager)模式。

它从类型提示中推断出输入、输出、新鲜变量和绑定变量,遵循以下约定

  • Funsor 输入被标注为 Funsor 类型。

  • 绑定变量输入(名称)被标注为 Bound 类型。

  • 新鲜变量输入(名称)被标注为 Fresh 类型,并附带用于计算依赖域的 lambda 函数。

  • 基础值输入(例如 Python 整数)被标注为 Value 类型,并附带其实际数据类型,例如 Value[int]

  • 返回值被标注为 Fresh 类型,并附带用于计算依赖返回域的 lambda 函数。

例如,要将单个坐标展平为一个坐标对,我们可以定义

@make_funsor
def Unflatten(
    x: Funsor,
    i: Bound,
    i_over_2: Fresh[lambda i: Bint[i.size // 2]],
    i_mod_2: Fresh[lambda: Bint[2]],
) -> Fresh[lambda x: x]:
    assert i.output.size % 2 == 0
    return x(**{i.name: i_over_2 * Number(2, 3) + i_mod_2})
参数

fn (可调用对象) – 一个带有类型标注的 Funsor 函数。

返回类型

Funsor 的子类