Relay保留称为“模块”(在其他功能编程语言中通常称为“环境”)的全局数据结构,以跟踪全局函数的定义。 特别是,模块保持全局变量到它们表示的函数表达式的全局可访问映射。 该模块的实用性是它允许全局函数递归引用自己或任何其他全局函数(例如,在相互递归中)。注意Relay的模块类似于数据结构,用于跟踪基于计算图的IR中的子图。
Relay中的全局函数的行为与“函数”中定义的函数表达式相同,但具有文本格式的语法糖,可以将其定义输入模块。 即,全局函数定义包括全局标识符,并允许在主体中递归引用该标识符,如以下示例所示:
def @ackermann(%m : Tensor[(), int32], %n : Tensor[(), int32]) -> Tensor[(), int32] {
if (%m == 0) {
%n + 1
} else if (%m > 0 && %n == 0) {
@ackermann(%m - 1, 1)
} else {
@ackermann(%m - 1, @ackermann(%m, %n - 1))
}
}
此定义将导致模块条目将标识符@ackermann映射到具有上述参数,返回类型和主体的函数表达式。 然后,在代码中其他地方对标识符@ackermann的任何引用都可以在模块中查找标识符,并根据需要替换函数定义。