Loop¶
Loop - 25¶
版本¶
名称: Loop (GitHub)
域:
mainsince_version:
25函数:
False支持级别:
SupportType.COMMON形状推断:
True
此版本的操作符已在版本 25 及之后可用。
摘要¶
通用循环结构。此循环具有多个终止条件
行程计数。在运行时指定的迭代计数。通过指定输入 M 设置。可选。设置为空字符串表示省略。请注意,可以通过为输入 M 传入常量节点来指定静态行程计数(在图构造时指定)。
循环终止条件。这是操作符的一个输入,它决定是否运行第一次迭代,也是循环主体图的循环依赖。循环主体图必须为条件变量生成一个值,无论是否提供此输入。
此表总结了此操作符的运行模式,并附带等效的 C 风格代码
操作符输入定义为 (max_trip_count, condition_var)。
输入 ("",""): for (int i=0; ; ++i) { cond = … // 注意此值被忽略,但在循环体中是必需的 }
输入 ("", cond) // 注意这类似于 while 循环 bool cond = …; for (int i=0; cond; ++i) { cond = …; }
输入 ("", 1) // 注意这类似于 do-while 循环 bool cond = true for (int i=0; cond; ++i) { cond = …; }
输入 (trip_count, "") // 注意这类似于 for 循环 int trip_count = … for (int i=0; i < trip_count; ++i) { cond = …; // 忽略 }
输入 (trip_count, cond) int trip_count = …; bool cond = …; for (int i=0; i < trip_count && cond; ++i) { cond = …; }
使用示例 - 条件和行程计数
graph predict-net {
%a = Constant[value = <Scalar Tensor [3]>]()
%b = Constant[value = <Scalar Tensor [6]>]()
%keepgoing = Constant[value = <Scalar Tensor [1]>]()
%max_trip_count = Constant[value = <Scalar Tensor [10]>]()
%keepgoing_out, %b_out, %user_defined_vals = Loop[body = <graph body-net>](%max_trip_count, %keepgoing, %b)
return
}
graph body-net (
%i[INT32, scalar] // iteration number
%keepgoing_in[BOOL, scalar] // incoming loop-termination-condition; not used
%b_in[INT32, scalar] // incoming value of loop-carried-dependency b
) {
%my_local = Add(%a, %b_in)
%b_out = Sub(%a, %b_in) // outgoing value of loop-carried-dependency b
%keepgoing_out = Greater(%my_local, %b_out) // outgoing loop-termination-condition
%user_defined_val = Add(%b_in, %b_in) // scan-output value to be accumulated
return %keepgoing_out, %b_out, %user_defined_val
}
等效 C 代码示例
{
/* User-defined code (enclosing scope) */
int a = 3, b = 6;
bool keepgoing = true; // Analogous to input cond
/* End user-defined code */
/* Implicitly-defined code */
const int max_trip_count = 10; // Analogous to input M
int user_defined_vals[]; // Imagine this is resizable
/* End implicitly-defined code */
/* initialize loop-carried variables and scan-output variables */
bool keepgoing_out = keepgoing
int b_out = b
for (int i=0; i < max_trip_count && keepgoing_out; ++i) {
/* Implicitly-defined code: bind actual parameter values
to formal parameter variables of loop-body */
bool keepgoing_in = keepgoing_out;
bool b_in = b_out;
/* User-defined code (loop body) */
int my_local = a + b_in; // Reading value "a" from the enclosing scope is fine
b_out = a - b_in;
keepgoing_out = my_local > b_out;
user_defined_val = b_in + b_in; // b_in and b_out are different variables
/* End user-defined code */
/* Implicitly defined-code */
user_defined_vals[i] = user_defined_val // accumulate scan-output values
}
// int t = my_local; // Can't do this. my_local is not accessible here.
// The values below are bound to the output variables of the loop and therefore accessible
// b_out; user_defined_vals; keepgoing_out;
}
此代码片段中有几点值得注意
来自封闭范围的值(即此处的变量“a”)在范围内,并且可以在循环的输入中引用。
在循环体中计算的任何需要在后续迭代或循环后使用的值,都使用循环体中的一对变量来建模,包括一个输入变量(例如,b_in)和一个输出变量(例如,b_out)。这些被称为循环依赖项。循环操作节点为第一次迭代提供输入变量的输入值,并返回最终迭代生成的输出变量的输出值。
Scan_output 变量用于隐式连接在所有迭代中计算的值。在上面的示例中,在所有迭代中计算的 user_defined_val 的值被连接起来,并在循环后作为 user_defined_vals 的值返回。
在循环体中创建的值不能在封闭范围中访问,除非使用上述机制。
请注意,此操作符的语义支持“对角线”或“波前”执行。(有关示例,请参见此处的步骤 3:https://devblogs.nvidia.com/optimizing-recurrent-neural-networks-cudnn-5/)。前端应将多层 RNN 作为一系列 While 操作符(其中时间是内部循环维度)发出,每个后续层消耗前一层的 scan_outputs,可能通过几个逐点操作符(例如 dropout、残差连接、线性层)。
子图(由循环节点生成)的输入/输出匹配基于顺序而非名称。实现将根据此顺序确定名称。
属性¶
body - 图 (必需)
每次迭代运行的图。它有 2+N 个输入:(迭代次数、条件、循环依赖项...)。它有 1+N+K 个输出:(条件、循环依赖项...、扫描输出...)。每个扫描输出是通过在循环每次迭代结束时连接指定输出值而创建的。如果这些扫描输出的维度或数据类型在循环迭代中发生变化,则会发生错误。
输入¶
介于 2 到 2147483647 个输入之间。
M (可选,异构) - I
在运行时指定的循环最大行程计数。可选。传入空字符串以跳过。
cond (可选,异构) - B
布尔终止条件。可选。传入空字符串以跳过。
v_initial (可变参数) - V
任何循环依赖项的初始值(在循环迭代中更改的值)
输出¶
1 到 2147483647 个输出之间。
v_final_and_scan_outputs (可变参数) - V
最终的 N 个循环依赖值,然后是 K 个扫描输出。扫描输出必须是张量。
类型约束¶
V in (
optional(seq(tensor(bfloat16))),optional(seq(tensor(bool))),optional(seq(tensor(complex128))),optional(seq(tensor(complex64))),optional(seq(tensor(double))),optional(seq(tensor(float))),optional(seq(tensor(float16))),optional(seq(tensor(int16))),optional(seq(tensor(int32))),optional(seq(tensor(int64))),optional(seq(tensor(int8))),optional(seq(tensor(string))),optional(seq(tensor(uint16))),optional(seq(tensor(uint32))),optional(seq(tensor(uint64))),optional(seq(tensor(uint8))),optional(tensor(bfloat16)),optional(tensor(bool)),optional(tensor(complex128)),optional(tensor(complex64)),optional(tensor(double)),optional(tensor(float)),optional(tensor(float16)),optional(tensor(float4e2m1)),optional(tensor(float8e4m3fn)),optional(tensor(float8e4m3fnuz)),optional(tensor(float8e5m2)),optional(tensor(float8e5m2fnuz)),optional(tensor(float8e8m0)),optional(tensor(int16)),optional(tensor(int2)),optional(tensor(int32)),optional(tensor(int4)),optional(tensor(int64)),optional(tensor(int8)),optional(tensor(string)),optional(tensor(uint16)),optional(tensor(uint2)),optional(tensor(uint32)),optional(tensor(uint4)),optional(tensor(uint64)),optional(tensor(uint8)),seq(tensor(bfloat16)),seq(tensor(bool)),seq(tensor(complex128)),seq(tensor(complex64)),seq(tensor(double)),seq(tensor(float)),seq(tensor(float16)),seq(tensor(float4e2m1)),seq(tensor(float8e4m3fn)),seq(tensor(float8e4m3fnuz)),seq(tensor(float8e5m2)),seq(tensor(float8e5m2fnuz)),seq(tensor(float8e8m0)),seq(tensor(int16)),seq(tensor(int2)),seq(tensor(int32)),seq(tensor(int4)),seq(tensor(int64)),seq(tensor(int8)),seq(tensor(string)),seq(tensor(uint16)),seq(tensor(uint2)),seq(tensor(uint32)),seq(tensor(uint4)),seq(tensor(uint64)),seq(tensor(uint8)),tensor(bfloat16),tensor(bool),tensor(complex128),tensor(complex64),tensor(double),tensor(float),tensor(float16),tensor(float4e2m1),tensor(float8e4m3fn),tensor(float8e4m3fnuz),tensor(float8e5m2),tensor(float8e5m2fnuz),tensor(float8e8m0),tensor(int16),tensor(int2),tensor(int32),tensor(int4),tensor(int64),tensor(int8),tensor(string),tensor(uint16),tensor(uint2)),tensor(uint32),tensor(uint4)),tensor(uint64),tensor(uint8))所有张量、序列(张量)、可选(张量)和可选(序列(张量))类型,最高支持 IRv13。
I 在 (
tensor(int64))int64 型张量,应为标量。
B 在 (
tensor(bool))bool 型张量,应为标量。
Loop - 24¶
版本¶
名称: Loop (GitHub)
域:
main起始版本:
24函数:
False支持级别:
SupportType.COMMON形状推断:
True
此版本的操作符已可用于版本 24 及以上。
摘要¶
通用循环结构。此循环具有多个终止条件
行程计数。在运行时指定的迭代计数。通过指定输入 M 设置。可选。设置为空字符串表示省略。请注意,可以通过为输入 M 传入常量节点来指定静态行程计数(在图构造时指定)。
循环终止条件。这是操作符的一个输入,它决定是否运行第一次迭代,也是循环主体图的循环依赖。循环主体图必须为条件变量生成一个值,无论是否提供此输入。
此表总结了此操作符的运行模式,并附带等效的 C 风格代码
操作符输入定义为 (max_trip_count, condition_var)。
输入 ("",""): for (int i=0; ; ++i) { cond = … // 注意此值被忽略,但在循环体中是必需的 }
输入 ("", cond) // 注意这类似于 while 循环 bool cond = …; for (int i=0; cond; ++i) { cond = …; }
输入 ("", 1) // 注意这类似于 do-while 循环 bool cond = true for (int i=0; cond; ++i) { cond = …; }
输入 (trip_count, "") // 注意这类似于 for 循环 int trip_count = … for (int i=0; i < trip_count; ++i) { cond = …; // 忽略 }
输入 (trip_count, cond) int trip_count = …; bool cond = …; for (int i=0; i < trip_count && cond; ++i) { cond = …; }
使用示例 - 条件和行程计数
graph predict-net {
%a = Constant[value = <Scalar Tensor [3]>]()
%b = Constant[value = <Scalar Tensor [6]>]()
%keepgoing = Constant[value = <Scalar Tensor [1]>]()
%max_trip_count = Constant[value = <Scalar Tensor [10]>]()
%keepgoing_out, %b_out, %user_defined_vals = Loop[body = <graph body-net>](%max_trip_count, %keepgoing, %b)
return
}
graph body-net (
%i[INT32, scalar] // iteration number
%keepgoing_in[BOOL, scalar] // incoming loop-termination-condition; not used
%b_in[INT32, scalar] // incoming value of loop-carried-dependency b
) {
%my_local = Add(%a, %b_in)
%b_out = Sub(%a, %b_in) // outgoing value of loop-carried-dependency b
%keepgoing_out = Greater(%my_local, %b_out) // outgoing loop-termination-condition
%user_defined_val = Add(%b_in, %b_in) // scan-output value to be accumulated
return %keepgoing_out, %b_out, %user_defined_val
}
等效 C 代码示例
{
/* User-defined code (enclosing scope) */
int a = 3, b = 6;
bool keepgoing = true; // Analogous to input cond
/* End user-defined code */
/* Implicitly-defined code */
const int max_trip_count = 10; // Analogous to input M
int user_defined_vals[]; // Imagine this is resizable
/* End implicitly-defined code */
/* initialize loop-carried variables and scan-output variables */
bool keepgoing_out = keepgoing
int b_out = b
for (int i=0; i < max_trip_count && keepgoing_out; ++i) {
/* Implicitly-defined code: bind actual parameter values
to formal parameter variables of loop-body */
bool keepgoing_in = keepgoing_out;
bool b_in = b_out;
/* User-defined code (loop body) */
int my_local = a + b_in; // Reading value "a" from the enclosing scope is fine
b_out = a - b_in;
keepgoing_out = my_local > b_out;
user_defined_val = b_in + b_in; // b_in and b_out are different variables
/* End user-defined code */
/* Implicitly defined-code */
user_defined_vals[i] = user_defined_val // accumulate scan-output values
}
// int t = my_local; // Can't do this. my_local is not accessible here.
// The values below are bound to the output variables of the loop and therefore accessible
// b_out; user_defined_vals; keepgoing_out;
}
此代码片段中有几点值得注意
来自封闭范围的值(即此处的变量“a”)在范围内,并且可以在循环的输入中引用。
在循环体中计算的任何需要在后续迭代或循环后使用的值,都使用循环体中的一对变量来建模,包括一个输入变量(例如,b_in)和一个输出变量(例如,b_out)。这些被称为循环依赖项。循环操作节点为第一次迭代提供输入变量的输入值,并返回最终迭代生成的输出变量的输出值。
Scan_output 变量用于隐式连接在所有迭代中计算的值。在上面的示例中,在所有迭代中计算的 user_defined_val 的值被连接起来,并在循环后作为 user_defined_vals 的值返回。
在循环体中创建的值不能在封闭范围中访问,除非使用上述机制。
请注意,此操作符的语义支持“对角线”或“波前”执行。(有关示例,请参见此处的步骤 3:https://devblogs.nvidia.com/optimizing-recurrent-neural-networks-cudnn-5/)。前端应将多层 RNN 作为一系列 While 操作符(其中时间是内部循环维度)发出,每个后续层消耗前一层的 scan_outputs,可能通过几个逐点操作符(例如 dropout、残差连接、线性层)。
子图(由循环节点生成)的输入/输出匹配基于顺序而非名称。实现将根据此顺序确定名称。
属性¶
body - 图 (必需)
每次迭代运行的图。它有 2+N 个输入:(迭代次数、条件、循环依赖项...)。它有 1+N+K 个输出:(条件、循环依赖项...、扫描输出...)。每个扫描输出是通过在循环每次迭代结束时连接指定输出值而创建的。如果这些扫描输出的维度或数据类型在循环迭代中发生变化,则会发生错误。
输入¶
介于 2 到 2147483647 个输入之间。
M (可选,异构) - I
在运行时指定的循环最大行程计数。可选。传入空字符串以跳过。
cond (可选,异构) - B
布尔终止条件。可选。传入空字符串以跳过。
v_initial (可变参数) - V
任何循环依赖项的初始值(在循环迭代中更改的值)
输出¶
1 到 2147483647 个输出之间。
v_final_and_scan_outputs (可变参数) - V
最终的 N 个循环依赖值,然后是 K 个扫描输出。扫描输出必须是张量。
类型约束¶
V in (
optional(seq(tensor(bfloat16))),optional(seq(tensor(bool))),optional(seq(tensor(complex128))),optional(seq(tensor(complex64))),optional(seq(tensor(double))),optional(seq(tensor(float))),optional(seq(tensor(float16))),optional(seq(tensor(int16))),optional(seq(tensor(int32))),optional(seq(tensor(int64))),optional(seq(tensor(int8))),optional(seq(tensor(string))),optional(seq(tensor(uint16))),optional(seq(tensor(uint32))),optional(seq(tensor(uint64))),optional(seq(tensor(uint8))),optional(tensor(bfloat16)),optional(tensor(bool)),optional(tensor(complex128)),optional(tensor(complex64)),optional(tensor(double)),optional(tensor(float)),optional(tensor(float16)),optional(tensor(float4e2m1)),optional(tensor(float8e4m3fn)),optional(tensor(float8e4m3fnuz)),optional(tensor(float8e5m2)),optional(tensor(float8e5m2fnuz)),optional(tensor(float8e8m0)),optional(tensor(int16)),optional(tensor(int32)),optional(tensor(int4)),optional(tensor(int64)),optional(tensor(int8)),optional(tensor(string)),optional(tensor(uint16)),optional(tensor(uint32)),optional(tensor(uint4)),optional(tensor(uint64)),optional(tensor(uint8)),seq(tensor(bfloat16)),seq(tensor(bool)),seq(tensor(complex128)),seq(tensor(complex64)),seq(tensor(double)),seq(tensor(float)),seq(tensor(float16)),seq(tensor(float4e2m1)),seq(tensor(float8e4m3fn)),seq(tensor(float8e4m3fnuz)),seq(tensor(float8e5m2)),seq(tensor(float8e5m2fnuz)),seq(tensor(float8e8m0)),seq(tensor(int16)),seq(tensor(int32)),seq(tensor(int4)),seq(tensor(int64)),seq(tensor(int8)),seq(tensor(string)),seq(tensor(uint16)),seq(tensor(uint32)),seq(tensor(uint4)),seq(tensor(uint64)),seq(tensor(uint8)),tensor(bfloat16),tensor(bool),tensor(complex128),tensor(complex64),tensor(double),tensor(float),tensor(float16),tensor(float4e2m1)),tensor(float8e4m3fn)),tensor(float8e4m3fnuz)),tensor(float8e5m2)),tensor(float8e5m2fnuz)),tensor(float8e8m0)),tensor(int16),tensor(int32),tensor(int4)),tensor(int64),tensor(int8),tensor(string),tensor(uint16),tensor(uint32),tensor(uint4)),tensor(uint64),tensor(uint8))所有张量、序列(张量)、可选(张量)和可选(序列(张量))类型,最高支持 IRv11。
I 在 (
tensor(int64))int64 型张量,应为标量。
B 在 (
tensor(bool))bool 型张量,应为标量。
Loop - 23¶
版本¶
名称: Loop (GitHub)
域:
main起始版本:
23函数:
False支持级别:
SupportType.COMMON形状推断:
True
此版本的操作符已可用于版本 23 及以上。
摘要¶
通用循环结构。此循环具有多个终止条件
行程计数。在运行时指定的迭代计数。通过指定输入 M 设置。可选。设置为空字符串表示省略。请注意,可以通过为输入 M 传入常量节点来指定静态行程计数(在图构造时指定)。
循环终止条件。这是操作符的一个输入,它决定是否运行第一次迭代,也是循环主体图的循环依赖。循环主体图必须为条件变量生成一个值,无论是否提供此输入。
此表总结了此操作符的运行模式,并附带等效的 C 风格代码
操作符输入定义为 (max_trip_count, condition_var)。
输入 ("",""): for (int i=0; ; ++i) { cond = … // 注意此值被忽略,但在循环体中是必需的 }
输入 ("", cond) // 注意这类似于 while 循环 bool cond = …; for (int i=0; cond; ++i) { cond = …; }
输入 ("", 1) // 注意这类似于 do-while 循环 bool cond = true for (int i=0; cond; ++i) { cond = …; }
输入 (trip_count, "") // 注意这类似于 for 循环 int trip_count = … for (int i=0; i < trip_count; ++i) { cond = …; // 忽略 }
输入 (trip_count, cond) int trip_count = …; bool cond = …; for (int i=0; i < trip_count && cond; ++i) { cond = …; }
使用示例 - 条件和行程计数
graph predict-net {
%a = Constant[value = <Scalar Tensor [3]>]()
%b = Constant[value = <Scalar Tensor [6]>]()
%keepgoing = Constant[value = <Scalar Tensor [1]>]()
%max_trip_count = Constant[value = <Scalar Tensor [10]>]()
%keepgoing_out, %b_out, %user_defined_vals = Loop[body = <graph body-net>](%max_trip_count, %keepgoing, %b)
return
}
graph body-net (
%i[INT32, scalar] // iteration number
%keepgoing_in[BOOL, scalar] // incoming loop-termination-condition; not used
%b_in[INT32, scalar] // incoming value of loop-carried-dependency b
) {
%my_local = Add(%a, %b_in)
%b_out = Sub(%a, %b_in) // outgoing value of loop-carried-dependency b
%keepgoing_out = Greater(%my_local, %b_out) // outgoing loop-termination-condition
%user_defined_val = Add(%b_in, %b_in) // scan-output value to be accumulated
return %keepgoing_out, %b_out, %user_defined_val
}
等效 C 代码示例
{
/* User-defined code (enclosing scope) */
int a = 3, b = 6;
bool keepgoing = true; // Analogous to input cond
/* End user-defined code */
/* Implicitly-defined code */
const int max_trip_count = 10; // Analogous to input M
int user_defined_vals[]; // Imagine this is resizable
/* End implicitly-defined code */
/* initialize loop-carried variables and scan-output variables */
bool keepgoing_out = keepgoing
int b_out = b
for (int i=0; i < max_trip_count && keepgoing_out; ++i) {
/* Implicitly-defined code: bind actual parameter values
to formal parameter variables of loop-body */
bool keepgoing_in = keepgoing_out;
bool b_in = b_out;
/* User-defined code (loop body) */
int my_local = a + b_in; // Reading value "a" from the enclosing scope is fine
b_out = a - b_in;
keepgoing_out = my_local > b_out;
user_defined_val = b_in + b_in; // b_in and b_out are different variables
/* End user-defined code */
/* Implicitly defined-code */
user_defined_vals[i] = user_defined_val // accumulate scan-output values
}
// int t = my_local; // Can't do this. my_local is not accessible here.
// The values below are bound to the output variables of the loop and therefore accessible
// b_out; user_defined_vals; keepgoing_out;
}
此代码片段中有几点值得注意
来自封闭范围的值(即此处的变量“a”)在范围内,并且可以在循环的输入中引用。
在循环体中计算的任何需要在后续迭代或循环后使用的值,都使用循环体中的一对变量来建模,包括一个输入变量(例如,b_in)和一个输出变量(例如,b_out)。这些被称为循环依赖项。循环操作节点为第一次迭代提供输入变量的输入值,并返回最终迭代生成的输出变量的输出值。
Scan_output 变量用于隐式连接在所有迭代中计算的值。在上面的示例中,在所有迭代中计算的 user_defined_val 的值被连接起来,并在循环后作为 user_defined_vals 的值返回。
在循环体中创建的值不能在封闭范围中访问,除非使用上述机制。
请注意,此操作符的语义支持“对角线”或“波前”执行。(有关示例,请参见此处的步骤 3:https://devblogs.nvidia.com/optimizing-recurrent-neural-networks-cudnn-5/)。前端应将多层 RNN 作为一系列 While 操作符(其中时间是内部循环维度)发出,每个后续层消耗前一层的 scan_outputs,可能通过几个逐点操作符(例如 dropout、残差连接、线性层)。
子图(由循环节点生成)的输入/输出匹配基于顺序而非名称。实现将根据此顺序确定名称。
属性¶
body - 图 (必需)
每次迭代运行的图。它有 2+N 个输入:(迭代次数、条件、循环依赖项...)。它有 1+N+K 个输出:(条件、循环依赖项...、扫描输出...)。每个扫描输出是通过在循环每次迭代结束时连接指定输出值而创建的。如果这些扫描输出的维度或数据类型在循环迭代中发生变化,则会发生错误。
输入¶
介于 2 到 2147483647 个输入之间。
M (可选,异构) - I
在运行时指定的循环最大行程计数。可选。传入空字符串以跳过。
cond (可选,异构) - B
布尔终止条件。可选。传入空字符串以跳过。
v_initial (可变参数) - V
任何循环依赖项的初始值(在循环迭代中更改的值)
输出¶
1 到 2147483647 个输出之间。
v_final_and_scan_outputs (可变参数) - V
最终的 N 个循环依赖值,然后是 K 个扫描输出。扫描输出必须是张量。
类型约束¶
V in (
optional(seq(tensor(bfloat16))),optional(seq(tensor(bool))),optional(seq(tensor(complex128))),optional(seq(tensor(complex64))),optional(seq(tensor(double))),optional(seq(tensor(float))),optional(seq(tensor(float16))),optional(seq(tensor(int16))),optional(seq(tensor(int32))),optional(seq(tensor(int64))),optional(seq(tensor(int8))),optional(seq(tensor(string))),optional(seq(tensor(uint16))),optional(seq(tensor(uint32))),optional(seq(tensor(uint64))),optional(seq(tensor(uint8))),optional(tensor(bfloat16)),optional(tensor(bool)),optional(tensor(complex128)),optional(tensor(complex64)),optional(tensor(double)),optional(tensor(float)),optional(tensor(float16)),optional(tensor(float4e2m1)),optional(tensor(float8e4m3fn)),optional(tensor(float8e4m3fnuz)),optional(tensor(float8e5m2)),optional(tensor(float8e5m2fnuz)),optional(tensor(int16)),optional(tensor(int32)),optional(tensor(int4)),optional(tensor(int64)),optional(tensor(int8)),optional(tensor(string)),optional(tensor(uint16)),optional(tensor(uint32)),optional(tensor(uint4)),optional(tensor(uint64)),optional(tensor(uint8)),seq(tensor(bfloat16)),seq(tensor(bool)),seq(tensor(complex128)),seq(tensor(complex64)),seq(tensor(double)),seq(tensor(float)),seq(tensor(float16)),seq(tensor(float4e2m1)),seq(tensor(float8e4m3fn)),seq(tensor(float8e4m3fnuz)),seq(tensor(float8e5m2)),seq(tensor(float8e5m2fnuz)),seq(tensor(int16)),seq(tensor(int32)),seq(tensor(int4)),seq(tensor(int64)),seq(tensor(int8)),seq(tensor(string)),seq(tensor(uint16)),seq(tensor(uint32)),seq(tensor(uint4)),seq(tensor(uint64)),seq(tensor(uint8)),tensor(bfloat16),tensor(bool),tensor(complex128),tensor(complex64),tensor(double),tensor(float),tensor(float16),tensor(float4e2m1)),tensor(float8e4m3fn)),tensor(float8e4m3fnuz)),tensor(float8e5m2)),tensor(float8e5m2fnuz)),tensor(int16),tensor(int32),tensor(int4)),tensor(int64),tensor(int8),tensor(string),tensor(uint16),tensor(uint32),tensor(uint4)),tensor(uint64),tensor(uint8))所有张量、序列(张量)、可选(张量)和可选(序列(张量))类型,最高支持 IRv11。
I 在 (
tensor(int64))int64 型张量,应为标量。
B 在 (
tensor(bool))bool 型张量,应为标量。
Loop - 21¶
版本¶
名称: Loop (GitHub)
域:
mainsince_version:
21函数:
False支持级别:
SupportType.COMMON形状推断:
True
此版本的操作符自 版本 21 起可用。
摘要¶
通用循环结构。此循环具有多个终止条件
行程计数。在运行时指定的迭代计数。通过指定输入 M 设置。可选。设置为空字符串表示省略。请注意,可以通过为输入 M 传入常量节点来指定静态行程计数(在图构造时指定)。
循环终止条件。这是操作符的一个输入,它决定是否运行第一次迭代,也是循环主体图的循环依赖。循环主体图必须为条件变量生成一个值,无论是否提供此输入。
此表总结了此操作符的运行模式,并附带等效的 C 风格代码
操作符输入定义为 (max_trip_count, condition_var)。
输入 ("",""): for (int i=0; ; ++i) { cond = … // 注意此值被忽略,但在循环体中是必需的 }
输入 ("", cond) // 注意这类似于 while 循环 bool cond = …; for (int i=0; cond; ++i) { cond = …; }
输入 ("", 1) // 注意这类似于 do-while 循环 bool cond = true for (int i=0; cond; ++i) { cond = …; }
输入 (trip_count, "") // 注意这类似于 for 循环 int trip_count = … for (int i=0; i < trip_count; ++i) { cond = …; // 忽略 }
输入 (trip_count, cond) int trip_count = …; bool cond = …; for (int i=0; i < trip_count && cond; ++i) { cond = …; }
使用示例 - 条件和行程计数
graph predict-net {
%a = Constant[value = <Scalar Tensor [3]>]()
%b = Constant[value = <Scalar Tensor [6]>]()
%keepgoing = Constant[value = <Scalar Tensor [1]>]()
%max_trip_count = Constant[value = <Scalar Tensor [10]>]()
%keepgoing_out, %b_out, %user_defined_vals = Loop[body = <graph body-net>](%max_trip_count, %keepgoing, %b)
return
}
graph body-net (
%i[INT32, scalar] // iteration number
%keepgoing_in[BOOL, scalar] // incoming loop-termination-condition; not used
%b_in[INT32, scalar] // incoming value of loop-carried-dependency b
) {
%my_local = Add(%a, %b_in)
%b_out = Sub(%a, %b_in) // outgoing value of loop-carried-dependency b
%keepgoing_out = Greater(%my_local, %b_out) // outgoing loop-termination-condition
%user_defined_val = Add(%b_in, %b_in) // scan-output value to be accumulated
return %keepgoing_out, %b_out, %user_defined_val
}
等效 C 代码示例
{
/* User-defined code (enclosing scope) */
int a = 3, b = 6;
bool keepgoing = true; // Analogous to input cond
/* End user-defined code */
/* Implicitly-defined code */
const int max_trip_count = 10; // Analogous to input M
int user_defined_vals[]; // Imagine this is resizable
/* End implicitly-defined code */
/* initialize loop-carried variables and scan-output variables */
bool keepgoing_out = keepgoing
int b_out = b
for (int i=0; i < max_trip_count && keepgoing_out; ++i) {
/* Implicitly-defined code: bind actual parameter values
to formal parameter variables of loop-body */
bool keepgoing_in = keepgoing_out;
bool b_in = b_out;
/* User-defined code (loop body) */
int my_local = a + b_in; // Reading value "a" from the enclosing scope is fine
b_out = a - b_in;
keepgoing_out = my_local > b_out;
user_defined_val = b_in + b_in; // b_in and b_out are different variables
/* End user-defined code */
/* Implicitly defined-code */
user_defined_vals[i] = user_defined_val // accumulate scan-output values
}
// int t = my_local; // Can't do this. my_local is not accessible here.
// The values below are bound to the output variables of the loop and therefore accessible
// b_out; user_defined_vals; keepgoing_out;
}
此代码片段中有几点值得注意
来自封闭范围的值(即此处的变量“a”)在范围内,并且可以在循环的输入中引用。
在循环体中计算的任何需要在后续迭代或循环后使用的值,都使用循环体中的一对变量来建模,包括一个输入变量(例如,b_in)和一个输出变量(例如,b_out)。这些被称为循环依赖项。循环操作节点为第一次迭代提供输入变量的输入值,并返回最终迭代生成的输出变量的输出值。
Scan_output 变量用于隐式连接在所有迭代中计算的值。在上面的示例中,在所有迭代中计算的 user_defined_val 的值被连接起来,并在循环后作为 user_defined_vals 的值返回。
在循环体中创建的值不能在封闭范围中访问,除非使用上述机制。
请注意,此操作符的语义支持“对角线”或“波前”执行。(有关示例,请参见此处的步骤 3:https://devblogs.nvidia.com/optimizing-recurrent-neural-networks-cudnn-5/)。前端应将多层 RNN 作为一系列 While 操作符(其中时间是内部循环维度)发出,每个后续层消耗前一层的 scan_outputs,可能通过几个逐点操作符(例如 dropout、残差连接、线性层)。
子图(由循环节点生成)的输入/输出匹配基于顺序而非名称。实现将根据此顺序确定名称。
属性¶
body - 图 (必需)
每次迭代运行的图。它有 2+N 个输入:(迭代次数、条件、循环依赖项...)。它有 1+N+K 个输出:(条件、循环依赖项...、扫描输出...)。每个扫描输出是通过在循环每次迭代结束时连接指定输出值而创建的。如果这些扫描输出的维度或数据类型在循环迭代中发生变化,则会发生错误。
输入¶
介于 2 到 2147483647 个输入之间。
M (可选,异构) - I
在运行时指定的循环最大行程计数。可选。传入空字符串以跳过。
cond (可选,异构) - B
布尔终止条件。可选。传入空字符串以跳过。
v_initial (可变参数) - V
任何循环依赖项的初始值(在循环迭代中更改的值)
输出¶
1 到 2147483647 个输出之间。
v_final_and_scan_outputs (可变参数) - V
最终的 N 个循环依赖值,然后是 K 个扫描输出。扫描输出必须是张量。
类型约束¶
V in (
optional(seq(tensor(bfloat16))),optional(seq(tensor(bool))),optional(seq(tensor(complex128))),optional(seq(tensor(complex64))),optional(seq(tensor(double))),optional(seq(tensor(float))),optional(seq(tensor(float16))),optional(seq(tensor(int16))),optional(seq(tensor(int32))),optional(seq(tensor(int64))),optional(seq(tensor(int8))),optional(seq(tensor(string))),optional(seq(tensor(uint16))),optional(seq(tensor(uint32))),optional(seq(tensor(uint64))),optional(seq(tensor(uint8))),optional(tensor(bfloat16)),optional(tensor(bool)),optional(tensor(complex128)),optional(tensor(complex64)),optional(tensor(double)),optional(tensor(float)),optional(tensor(float16)),optional(tensor(float8e4m3fn)),optional(tensor(float8e4m3fnuz)),optional(tensor(float8e5m2)),optional(tensor(float8e5m2fnuz)),optional(tensor(int16)),optional(tensor(int32)),optional(tensor(int4)),optional(tensor(int64)),optional(tensor(int8)),optional(tensor(string)),optional(tensor(uint16)),optional(tensor(uint32)),optional(tensor(uint4)),optional(tensor(uint64)),optional(tensor(uint8)),seq(tensor(bfloat16)),seq(tensor(bool)),seq(tensor(complex128)),seq(tensor(complex64)),seq(tensor(double)),seq(tensor(float)),seq(tensor(float16)),seq(tensor(float8e4m3fn)),seq(tensor(float8e4m3fnuz)),seq(tensor(float8e5m2)),seq(tensor(float8e5m2fnuz)),seq(tensor(int16)),seq(tensor(int32)),seq(tensor(int4)),seq(tensor(int64)),seq(tensor(int8)),seq(tensor(string)),seq(tensor(uint16)),seq(tensor(uint32)),seq(tensor(uint4)),seq(tensor(uint64)),seq(tensor(uint8)),tensor(bfloat16),tensor(bool),tensor(complex128),tensor(complex64),tensor(double),tensor(float),tensor(float16),tensor(float8e4m3fn)),tensor(float8e4m3fnuz)),tensor(float8e5m2)),tensor(float8e5m2fnuz)),tensor(int16),tensor(int32),tensor(int4)),tensor(int64),tensor(int8),tensor(string),tensor(uint16),tensor(uint32),tensor(uint4)),tensor(uint64),tensor(uint8))所有张量、序列(张量)、可选(张量)和可选(序列(张量))类型,最高支持 IRv10。
I 在 (
tensor(int64))int64 型张量,应为标量。
B 在 (
tensor(bool))bool 型张量,应为标量。
Loop - 19¶
版本¶
名称: Loop (GitHub)
域:
mainsince_version:
19函数:
False支持级别:
SupportType.COMMON形状推断:
True
此版本的操作符自 版本 19 起可用。
摘要¶
通用循环结构。此循环具有多个终止条件
行程计数。在运行时指定的迭代计数。通过指定输入 M 设置。可选。设置为空字符串表示省略。请注意,可以通过为输入 M 传入常量节点来指定静态行程计数(在图构造时指定)。
循环终止条件。这是操作符的一个输入,它决定是否运行第一次迭代,也是循环主体图的循环依赖。循环主体图必须为条件变量生成一个值,无论是否提供此输入。
此表总结了此操作符的运行模式,并附带等效的 C 风格代码
操作符输入定义为 (max_trip_count, condition_var)。
输入 ("",""): for (int i=0; ; ++i) { cond = … // 注意此值被忽略,但在循环体中是必需的 }
输入 ("", cond) // 注意这类似于 while 循环 bool cond = …; for (int i=0; cond; ++i) { cond = …; }
输入 ("", 1) // 注意这类似于 do-while 循环 bool cond = true for (int i=0; cond; ++i) { cond = …; }
输入 (trip_count, "") // 注意这类似于 for 循环 int trip_count = … for (int i=0; i < trip_count; ++i) { cond = …; // 忽略 }
输入 (trip_count, cond) int trip_count = …; bool cond = …; for (int i=0; i < trip_count && cond; ++i) { cond = …; }
使用示例 - 条件和行程计数
graph predict-net {
%a = Constant[value = <Scalar Tensor [3]>]()
%b = Constant[value = <Scalar Tensor [6]>]()
%keepgoing = Constant[value = <Scalar Tensor [1]>]()
%max_trip_count = Constant[value = <Scalar Tensor [10]>]()
%keepgoing_out, %b_out, %user_defined_vals = Loop[body = <graph body-net>](%max_trip_count, %keepgoing, %b)
return
}
graph body-net (
%i[INT32, scalar] // iteration number
%keepgoing_in[BOOL, scalar] // incoming loop-termination-condition; not used
%b_in[INT32, scalar] // incoming value of loop-carried-dependency b
) {
%my_local = Add(%a, %b_in)
%b_out = Sub(%a, %b_in) // outgoing value of loop-carried-dependency b
%keepgoing_out = Greater(%my_local, %b_out) // outgoing loop-termination-condition
%user_defined_val = Add(%b_in, %b_in) // scan-output value to be accumulated
return %keepgoing_out, %b_out, %user_defined_val
}
等效 C 代码示例
{
/* User-defined code (enclosing scope) */
int a = 3, b = 6;
bool keepgoing = true; // Analogous to input cond
/* End user-defined code */
/* Implicitly-defined code */
const int max_trip_count = 10; // Analogous to input M
int user_defined_vals[]; // Imagine this is resizable
/* End implicitly-defined code */
/* initialize loop-carried variables and scan-output variables */
bool keepgoing_out = keepgoing
int b_out = b
for (int i=0; i < max_trip_count && keepgoing_out; ++i) {
/* Implicitly-defined code: bind actual parameter values
to formal parameter variables of loop-body */
bool keepgoing_in = keepgoing_out;
bool b_in = b_out;
/* User-defined code (loop body) */
int my_local = a + b_in; // Reading value "a" from the enclosing scope is fine
b_out = a - b_in;
keepgoing_out = my_local > b_out;
user_defined_val = b_in + b_in; // b_in and b_out are different variables
/* End user-defined code */
/* Implicitly defined-code */
user_defined_vals[i] = user_defined_val // accumulate scan-output values
}
// int t = my_local; // Can't do this. my_local is not accessible here.
// The values below are bound to the output variables of the loop and therefore accessible
// b_out; user_defined_vals; keepgoing_out;
}
此代码片段中有几点值得注意
来自封闭范围的值(即此处的变量“a”)在范围内,并且可以在循环的输入中引用。
在循环体中计算的任何需要在后续迭代或循环后使用的值,都使用循环体中的一对变量来建模,包括一个输入变量(例如,b_in)和一个输出变量(例如,b_out)。这些被称为循环依赖项。循环操作节点为第一次迭代提供输入变量的输入值,并返回最终迭代生成的输出变量的输出值。
Scan_output 变量用于隐式连接在所有迭代中计算的值。在上面的示例中,在所有迭代中计算的 user_defined_val 的值被连接起来,并在循环后作为 user_defined_vals 的值返回。
在循环体中创建的值不能在封闭范围中访问,除非使用上述机制。
请注意,此操作符的语义支持“对角线”或“波前”执行。(有关示例,请参见此处的步骤 3:https://devblogs.nvidia.com/optimizing-recurrent-neural-networks-cudnn-5/)。前端应将多层 RNN 作为一系列 While 操作符(其中时间是内部循环维度)发出,每个后续层消耗前一层的 scan_outputs,可能通过几个逐点操作符(例如 dropout、残差连接、线性层)。
子图(由循环节点生成)的输入/输出匹配基于顺序而非名称。实现将根据此顺序确定名称。
属性¶
body - 图 (必需)
每次迭代运行的图。它有 2+N 个输入:(迭代次数、条件、循环依赖项...)。它有 1+N+K 个输出:(条件、循环依赖项...、扫描输出...)。每个扫描输出是通过在循环每次迭代结束时连接指定输出值而创建的。如果这些扫描输出的维度或数据类型在循环迭代中发生变化,则会发生错误。
输入¶
介于 2 到 2147483647 个输入之间。
M (可选,异构) - I
在运行时指定的循环最大行程计数。可选。传入空字符串以跳过。
cond (可选,异构) - B
布尔终止条件。可选。传入空字符串以跳过。
v_initial (可变参数) - V
任何循环依赖项的初始值(在循环迭代中更改的值)
输出¶
1 到 2147483647 个输出之间。
v_final_and_scan_outputs (可变参数) - V
最终的 N 个循环依赖值,然后是 K 个扫描输出。扫描输出必须是张量。
类型约束¶
V in (
optional(seq(tensor(bfloat16))),optional(seq(tensor(bool))),optional(seq(tensor(complex128))),optional(seq(tensor(complex64))),optional(seq(tensor(double))),optional(seq(tensor(float))),optional(seq(tensor(float16))),optional(seq(tensor(int16))),optional(seq(tensor(int32))),optional(seq(tensor(int64))),optional(seq(tensor(int8))),optional(seq(tensor(string))),optional(seq(tensor(uint16))),optional(seq(tensor(uint32))),optional(seq(tensor(uint64))),optional(seq(tensor(uint8))),optional(tensor(bfloat16)),optional(tensor(bool)),optional(tensor(complex128)),optional(tensor(complex64)),optional(tensor(double)),optional(tensor(float)),optional(tensor(float16)),optional(tensor(float8e4m3fn)),optional(tensor(float8e4m3fnuz)),optional(tensor(float8e5m2)),optional(tensor(float8e5m2fnuz)),optional(tensor(int16)),optional(tensor(int32)),optional(tensor(int64)),optional(tensor(int8)),optional(tensor(string)),optional(tensor(uint16)),optional(tensor(uint32)),optional(tensor(uint4)),optional(tensor(uint64)),optional(tensor(uint8)),seq(tensor(bfloat16)),seq(tensor(bool)),seq(tensor(complex128)),seq(tensor(complex64)),seq(tensor(double)),seq(tensor(float)),seq(tensor(float16)),seq(tensor(float8e4m3fn)),seq(tensor(float8e4m3fnuz)),seq(tensor(float8e5m2)),seq(tensor(float8e5m2fnuz)),seq(tensor(int16)),seq(tensor(int32)),seq(tensor(int64)),seq(tensor(int8)),seq(tensor(string)),seq(tensor(uint16)),seq(tensor(uint32)),seq(tensor(uint4)),seq(tensor(uint64)),seq(tensor(uint8)),tensor(bfloat16),tensor(bool),tensor(complex128),tensor(complex64),tensor(double),tensor(float),tensor(float16),tensor(float8e4m3fn)),tensor(float8e4m3fnuz)),tensor(float8e5m2)),tensor(float8e5m2fnuz)),tensor(int16),tensor(int32),tensor(int64),tensor(int8),tensor(string),tensor(uint16),tensor(uint32),tensor(uint4)),tensor(uint64),tensor(uint8))所有张量、序列(张量)、可选(张量)和可选(序列(张量))类型,最高支持 IRv9。
I 在 (
tensor(int64))int64 型张量,应为标量。
B 在 (
tensor(bool))bool 型张量,应为标量。
Loop - 16¶
版本¶
名称: Loop (GitHub)
域:
mainsince_version:
16函数:
False支持级别:
SupportType.COMMON形状推断:
True
此版本的运算符自 版本 16 起可用。
摘要¶
通用循环结构。此循环具有多个终止条件
行程计数。在运行时指定的迭代计数。通过指定输入 M 设置。可选。设置为空字符串表示省略。请注意,可以通过为输入 M 传入常量节点来指定静态行程计数(在图构造时指定)。
循环终止条件。这是操作符的一个输入,它决定是否运行第一次迭代,也是循环主体图的循环依赖。循环主体图必须为条件变量生成一个值,无论是否提供此输入。
此表总结了此操作符的运行模式,并附带等效的 C 风格代码
操作符输入定义为 (max_trip_count, condition_var)。
输入 ("",""): for (int i=0; ; ++i) { cond = … // 注意此值被忽略,但在循环体中是必需的 }
输入 ("", cond) // 注意这类似于 while 循环 bool cond = …; for (int i=0; cond; ++i) { cond = …; }
输入 ("", 1) // 注意这类似于 do-while 循环 bool cond = true for (int i=0; cond; ++i) { cond = …; }
输入 (trip_count, "") // 注意这类似于 for 循环 int trip_count = … for (int i=0; i < trip_count; ++i) { cond = …; // 忽略 }
输入 (trip_count, cond) int trip_count = …; bool cond = …; for (int i=0; i < trip_count && cond; ++i) { cond = …; }
使用示例 - 条件和行程计数
graph predict-net {
%a = Constant[value = <Scalar Tensor [3]>]()
%b = Constant[value = <Scalar Tensor [6]>]()
%keepgoing = Constant[value = <Scalar Tensor [1]>]()
%max_trip_count = Constant[value = <Scalar Tensor [10]>]()
%keepgoing_out, %b_out, %user_defined_vals = Loop[body = <graph body-net>](%max_trip_count, %keepgoing, %b)
return
}
graph body-net (
%i[INT32, scalar] // iteration number
%keepgoing_in[BOOL, scalar] // incoming loop-termination-condition; not used
%b_in[INT32, scalar] // incoming value of loop-carried-dependency b
) {
%my_local = Add(%a, %b_in)
%b_out = Sub(%a, %b_in) // outgoing value of loop-carried-dependency b
%keepgoing_out = Greater(%my_local, %b_out) // outgoing loop-termination-condition
%user_defined_val = Add(%b_in, %b_in) // scan-output value to be accumulated
return %keepgoing_out, %b_out, %user_defined_val
}
等效 C 代码示例
{
/* User-defined code (enclosing scope) */
int a = 3, b = 6;
bool keepgoing = true; // Analogous to input cond
/* End user-defined code */
/* Implicitly-defined code */
const int max_trip_count = 10; // Analogous to input M
int user_defined_vals[]; // Imagine this is resizable
/* End implicitly-defined code */
/* initialize loop-carried variables and scan-output variables */
bool keepgoing_out = keepgoing
int b_out = b
for (int i=0; i < max_trip_count && keepgoing_out; ++i) {
/* Implicitly-defined code: bind actual parameter values
to formal parameter variables of loop-body */
bool keepgoing_in = keepgoing_out;
bool b_in = b_out;
/* User-defined code (loop body) */
int my_local = a + b_in; // Reading value "a" from the enclosing scope is fine
b_out = a - b_in;
keepgoing_out = my_local > b_out;
user_defined_val = b_in + b_in; // b_in and b_out are different variables
/* End user-defined code */
/* Implicitly defined-code */
user_defined_vals[i] = user_defined_val // accumulate scan-output values
}
// int t = my_local; // Can't do this. my_local is not accessible here.
// The values below are bound to the output variables of the loop and therefore accessible
// b_out; user_defined_vals; keepgoing_out;
}
此代码片段中有几点值得注意
来自封闭范围的值(即此处的变量“a”)在范围内,并且可以在循环的输入中引用。
在循环体中计算的任何需要在后续迭代或循环后使用的值,都使用循环体中的一对变量来建模,包括一个输入变量(例如,b_in)和一个输出变量(例如,b_out)。这些被称为循环依赖项。循环操作节点为第一次迭代提供输入变量的输入值,并返回最终迭代生成的输出变量的输出值。
Scan_output 变量用于隐式连接在所有迭代中计算的值。在上面的示例中,在所有迭代中计算的 user_defined_val 的值被连接起来,并在循环后作为 user_defined_vals 的值返回。
在循环体中创建的值不能在封闭范围中访问,除非使用上述机制。
请注意,此操作符的语义支持“对角线”或“波前”执行。(有关示例,请参见此处的步骤 3:https://devblogs.nvidia.com/optimizing-recurrent-neural-networks-cudnn-5/)。前端应将多层 RNN 作为一系列 While 操作符(其中时间是内部循环维度)发出,每个后续层消耗前一层的 scan_outputs,可能通过几个逐点操作符(例如 dropout、残差连接、线性层)。
子图(由循环节点生成)的输入/输出匹配基于顺序而非名称。实现将根据此顺序确定名称。
属性¶
body - 图 (必需)
每次迭代运行的图。它有 2+N 个输入:(迭代次数、条件、循环依赖项...)。它有 1+N+K 个输出:(条件、循环依赖项...、扫描输出...)。每个扫描输出是通过在循环每次迭代结束时连接指定输出值而创建的。如果这些扫描输出的维度或数据类型在循环迭代中发生变化,则会发生错误。
输入¶
介于 2 到 2147483647 个输入之间。
M (可选,异构) - I
在运行时指定的循环最大行程计数。可选。传入空字符串以跳过。
cond (可选,异构) - B
布尔终止条件。可选。传入空字符串以跳过。
v_initial (可变参数) - V
任何循环依赖项的初始值(在循环迭代中更改的值)
输出¶
1 到 2147483647 个输出之间。
v_final_and_scan_outputs (可变参数) - V
最终的 N 个循环依赖值,然后是 K 个扫描输出。扫描输出必须是张量。
类型约束¶
V in (
optional(seq(tensor(bfloat16))),optional(seq(tensor(bool))),optional(seq(tensor(complex128))),optional(seq(tensor(complex64))),optional(seq(tensor(double))),optional(seq(tensor(float))),optional(seq(tensor(float16))),optional(seq(tensor(int16))),optional(seq(tensor(int32))),optional(seq(tensor(int64))),optional(seq(tensor(int8))),optional(seq(tensor(string))),optional(seq(tensor(uint16))),optional(seq(tensor(uint32))),optional(seq(tensor(uint64))),optional(seq(tensor(uint8))),optional(tensor(bfloat16)),optional(tensor(bool)),optional(tensor(complex128)),optional(tensor(complex64)),optional(tensor(double)),optional(tensor(float)),optional(tensor(float16)),optional(tensor(int16)),optional(tensor(int32)),optional(tensor(int64)),optional(tensor(int8)),optional(tensor(string)),optional(tensor(uint16)),optional(tensor(uint32)),optional(tensor(uint64)),optional(tensor(uint8)),seq(tensor(bfloat16)),seq(tensor(bool)),seq(tensor(complex128)),seq(tensor(complex64)),seq(tensor(double)),seq(tensor(float)),seq(tensor(float16)),seq(tensor(int16)),seq(tensor(int32)),seq(tensor(int64)),seq(tensor(int8)),seq(tensor(string)),seq(tensor(uint16)),seq(tensor(uint32)),seq(tensor(uint64)),seq(tensor(uint8)),tensor(bfloat16),tensor(bool),tensor(complex128),tensor(complex64),tensor(double),tensor(float),tensor(float16),tensor(int16),tensor(int32),tensor(int64),tensor(int8),tensor(string),tensor(uint16),tensor(uint32),tensor(uint64),tensor(uint8))所有张量、序列(张量)、可选(张量)和可选(序列(张量))类型,最高支持 IRv4。
I 在 (
tensor(int64))int64 型张量,应为标量。
B 在 (
tensor(bool))bool 型张量,应为标量。
Loop - 13¶
版本¶
名称: Loop (GitHub)
域:
main起始版本:
13函数:
False支持级别:
SupportType.COMMON形状推断:
True
此版本的运算符自 版本 13 起可用。
摘要¶
通用循环结构。此循环具有多个终止条件
行程计数。在运行时指定的迭代计数。通过指定输入 M 设置。可选。设置为空字符串表示省略。请注意,可以通过为输入 M 传入常量节点来指定静态行程计数(在图构造时指定)。
循环终止条件。这是操作符的一个输入,它决定是否运行第一次迭代,也是循环主体图的循环依赖。循环主体图必须为条件变量生成一个值,无论是否提供此输入。
此表总结了此操作符的运行模式,并附带等效的 C 风格代码
操作符输入定义为 (max_trip_count, condition_var)。
input ("", ""):
for (int i=0; ; ++i) {
cond = ... // Note this value is ignored, but is required in the body
}
input ("", cond) // Note this is analogous to a while loop
bool cond = ...;
for (int i=0; cond; ++i) {
cond = ...;
}
input ("", 1) // Note this is analogous to a do-while loop
bool cond = true
for (int i=0; cond; ++i) {
cond = ...;
}
input (trip_count, "") // Note this is analogous to a for loop
int trip_count = ...
for (int i=0; i < trip_count; ++i) {
cond = ...; // ignored
}
input (trip_count, cond)
int trip_count = ...;
bool cond = ...;
for (int i=0; i < trip_count && cond; ++i) {
cond = ...;
}
使用示例 - 条件和行程计数
graph predict-net {
%a = Constant[value = <Scalar Tensor [3]>]()
%b = Constant[value = <Scalar Tensor [6]>]()
%keepgoing = Constant[value = <Scalar Tensor [1]>]()
%max_trip_count = Constant[value = <Scalar Tensor [10]>]()
%keepgoing_out, %b_out, %user_defined_vals = Loop[body = <graph body-net>](%max_trip_count, %keepgoing, %b)
return
}
graph body-net (
%i[INT32, scalar] // iteration number
%keepgoing_in[BOOL, scalar] // incoming loop-termination-condition; not used
%b_in[INT32, scalar] // incoming value of loop-carried-dependency b
) {
%my_local = Add(%a, %b_in)
%b_out = Sub(%a, %b_in) // outgoing value of loop-carried-dependency b
%keepgoing_out = Greater(%my_local, %b_out) // outgoing loop-termination-condition
%user_defined_val = Add(%b_in, %b_in) // scan-output value to be accumulated
return %keepgoing_out, %b_out, %user_defined_val
}
等效 C 代码示例
{
/* User-defined code (enclosing scope) */
int a = 3, b = 6;
bool keepgoing = true; // Analogous to input cond
/* End user-defined code */
/* Implicitly-defined code */
const int max_trip_count = 10; // Analogous to input M
int user_defined_vals[]; // Imagine this is resizable
/* End implicitly-defined code */
/* initialize loop-carried variables and scan-output variables */
bool keepgoing_out = keepgoing
int b_out = b
for (int i=0; i < max_trip_count && keepgoing_out; ++i) {
/* Implicitly-defined code: bind actual parameter values
to formal parameter variables of loop-body */
bool keepgoing_in = keepgoing_out;
bool b_in = b_out;
/* User-defined code (loop body) */
int my_local = a + b_in; // Reading value "a" from the enclosing scope is fine
b_out = a - b_in;
keepgoing_out = my_local > b_out;
user_defined_val = b_in + b_in; // b_in and b_out are different variables
/* End user-defined code */
/* Implicitly defined-code */
user_defined_vals[i] = user_defined_val // accumulate scan-output values
}
// int t = my_local; // Can't do this. my_local is not accessible here.
// The values below are bound to the output variables of the loop and therefore accessible
// b_out; user_defined_vals; keepgoing_out;
}
此代码片段中有几点值得注意
来自封闭范围的值(即此处的变量“a”)在范围内,并且可以在循环的输入中引用。
在循环体中计算的任何需要在后续迭代或循环后使用的值,都使用循环体中的一对变量来建模,包括一个输入变量(例如,b_in)和一个输出变量(例如,b_out)。这些被称为循环依赖项。循环操作节点为第一次迭代提供输入变量的输入值,并返回最终迭代生成的输出变量的输出值。
Scan_output 变量用于隐式连接在所有迭代中计算的值。在上面的示例中,在所有迭代中计算的 user_defined_val 的值被连接起来,并在循环后作为 user_defined_vals 的值返回。
在循环体中创建的值不能在封闭范围中访问,除非使用上述机制。
请注意,此操作符的语义支持“对角线”或“波前”执行。(有关示例,请参见此处的步骤 3:https://devblogs.nvidia.com/optimizing-recurrent-neural-networks-cudnn-5/)。前端应将多层 RNN 作为一系列 While 操作符(其中时间是内部循环维度)发出,每个后续层消耗前一层的 scan_outputs,可能通过几个逐点操作符(例如 dropout、残差连接、线性层)。
子图(由循环节点生成)的输入/输出匹配基于顺序而非名称。实现将根据此顺序确定名称。
属性¶
body - 图 (必需)
每次迭代运行的图。它有 2+N 个输入:(迭代次数、条件、循环依赖项...)。它有 1+N+K 个输出:(条件、循环依赖项...、扫描输出...)。每个扫描输出是通过在循环每次迭代结束时连接指定输出值而创建的。如果这些扫描输出的维度或数据类型在循环迭代中发生变化,则会发生错误。
输入¶
介于 2 到 2147483647 个输入之间。
M (可选,异构) - I
在运行时指定的循环最大行程计数。可选。传入空字符串以跳过。
cond (可选,异构) - B
布尔终止条件。可选。传入空字符串以跳过。
v_initial (可变参数) - V
任何循环依赖项的初始值(在循环迭代中更改的值)
输出¶
1 到 2147483647 个输出之间。
v_final_and_scan_outputs (可变参数) - V
最终的 N 个循环依赖值,然后是 K 个扫描输出。扫描输出必须是张量。
类型约束¶
V in (
seq(tensor(bool)),seq(tensor(complex128)),seq(tensor(complex64)),seq(tensor(double)),seq(tensor(float)),seq(tensor(float16)),seq(tensor(int16)),seq(tensor(int32)),seq(tensor(int64)),seq(tensor(int8)),seq(tensor(string)),seq(tensor(uint16)),seq(tensor(uint32)),seq(tensor(uint64)),seq(tensor(uint8)),tensor(bool),tensor(complex128),tensor(complex64),tensor(double),tensor(float),tensor(float16),tensor(int16),tensor(int32),tensor(int64),tensor(int8),tensor(string),tensor(uint16),tensor(uint32),tensor(uint64),tensor(uint8))所有张量和序列类型
I 在 (
tensor(int64))int64 型张量,应为标量。
B 在 (
tensor(bool))bool 型张量,应为标量。
Loop - 11¶
版本¶
名称: Loop (GitHub)
域:
main起始版本:
11函数:
False支持级别:
SupportType.COMMON形状推断:
True
此版本的运算符自 版本 11 起可用。
摘要¶
通用循环结构。此循环具有多个终止条件
行程计数。在运行时指定的迭代计数。通过指定输入 M 设置。可选。设置为空字符串表示省略。请注意,可以通过为输入 M 传入常量节点来指定静态行程计数(在图构造时指定)。
循环终止条件。这是操作符的一个输入,它决定是否运行第一次迭代,也是循环主体图的循环依赖。循环主体图必须为条件变量生成一个值,无论是否提供此输入。
此表总结了此操作符的运行模式,并附带等效的 C 风格代码
操作符输入定义为 (max_trip_count, condition_var)。
input ("", ""):
for (int i=0; ; ++i) {
cond = ... // Note this value is ignored, but is required in the body
}
input ("", cond) // Note this is analogous to a while loop
bool cond = ...;
for (int i=0; cond; ++i) {
cond = ...;
}
input ("", 1) // Note this is analogous to a do-while loop
bool cond = true
for (int i=0; cond; ++i) {
cond = ...;
}
input (trip_count, "") // Note this is analogous to a for loop
int trip_count = ...
for (int i=0; i < trip_count; ++i) {
cond = ...; // ignored
}
input (trip_count, cond)
int trip_count = ...;
bool cond = ...;
for (int i=0; i < trip_count && cond; ++i) {
cond = ...;
}
使用示例 - 条件和行程计数
graph predict-net {
%a = Constant[value = <Scalar Tensor [3]>]()
%b = Constant[value = <Scalar Tensor [6]>]()
%keepgoing = Constant[value = <Scalar Tensor [1]>]()
%max_trip_count = Constant[value = <Scalar Tensor [10]>]()
%keepgoing_out, %b_out, %user_defined_vals = Loop[body = <graph body-net>](%max_trip_count, %keepgoing, %b)
return
}
graph body-net (
%i[INT32, scalar] // iteration number
%keepgoing_in[BOOL, scalar] // incoming loop-termination-condition; not used
%b_in[INT32, scalar] // incoming value of loop-carried-dependency b
) {
%my_local = Add(%a, %b_in)
%b_out = Sub(%a, %b_in) // outgoing value of loop-carried-dependency b
%keepgoing_out = Greater(%my_local, %b_out) // outgoing loop-termination-condition
%user_defined_val = Add(%b_in, %b_in) // scan-output value to be accumulated
return %keepgoing_out, %b_out, %user_defined_val
}
等效 C 代码示例
{
/* User-defined code (enclosing scope) */
int a = 3, b = 6;
bool keepgoing = true; // Analogous to input cond
/* End user-defined code */
/* Implicitly-defined code */
const int max_trip_count = 10; // Analogous to input M
int user_defined_vals[]; // Imagine this is resizable
/* End implicitly-defined code */
/* initialize loop-carried variables and scan-output variables */
bool keepgoing_out = keepgoing
int b_out = b
for (int i=0; i < max_trip_count && keepgoing_out; ++i) {
/* Implicitly-defined code: bind actual parameter values
to formal parameter variables of loop-body */
bool keepgoing_in = keepgoing_out;
bool b_in = b_out;
/* User-defined code (loop body) */
int my_local = a + b_in; // Reading value "a" from the enclosing scope is fine
b_out = a - b_in;
keepgoing_out = my_local > b_out;
user_defined_val = b_in + b_in; // b_in and b_out are different variables
/* End user-defined code */
/* Implicitly defined-code */
user_defined_vals[i] = user_defined_val // accumulate scan-output values
}
// int t = my_local; // Can't do this. my_local is not accessible here.
// The values below are bound to the output variables of the loop and therefore accessible
// b_out; user_defined_vals; keepgoing_out;
}
此代码片段中有几点值得注意
来自封闭范围的值(即此处的变量“a”)在范围内,并且可以在循环的输入中引用。
在循环体中计算的任何需要在后续迭代或循环后使用的值,都使用循环体中的一对变量来建模,包括一个输入变量(例如,b_in)和一个输出变量(例如,b_out)。这些被称为循环依赖项。循环操作节点为第一次迭代提供输入变量的输入值,并返回最终迭代生成的输出变量的输出值。
Scan_output 变量用于隐式连接在所有迭代中计算的值。在上面的示例中,在所有迭代中计算的 user_defined_val 的值被连接起来,并在循环后作为 user_defined_vals 的值返回。
在循环体中创建的值不能在封闭范围中访问,除非使用上述机制。
请注意,此操作符的语义支持“对角线”或“波前”执行。(有关示例,请参见此处的步骤 3:https://devblogs.nvidia.com/optimizing-recurrent-neural-networks-cudnn-5/)。前端应将多层 RNN 作为一系列 While 操作符(其中时间是内部循环维度)发出,每个后续层消耗前一层的 scan_outputs,可能通过几个逐点操作符(例如 dropout、残差连接、线性层)。
属性¶
body - 图 (必需)
每次迭代运行的图。它有 2+N 个输入:(迭代次数、条件、循环依赖项...)。它有 1+N+K 个输出:(条件、循环依赖项...、扫描输出...)。每个扫描输出是通过在循环每次迭代结束时连接指定输出值而创建的。如果这些扫描输出的维度或数据类型在循环迭代中发生变化,则会发生错误。
输入¶
介于 2 到 2147483647 个输入之间。
M (可选,异构) - I
在运行时指定的循环最大行程计数。可选。传入空字符串以跳过。
cond (可选,异构) - B
布尔终止条件。可选。传入空字符串以跳过。
v_initial (可变参数) - V
任何循环依赖项的初始值(在循环迭代中更改的值)
输出¶
1 到 2147483647 个输出之间。
v_final_and_scan_outputs (可变参数) - V
最终 N 个循环依赖值,然后是 K 个扫描输出
类型约束¶
V in (
tensor(bool),tensor(complex128),tensor(complex64),tensor(double),tensor(float),tensor(float16),tensor(int16),tensor(int32),tensor(int64),tensor(int8),tensor(string),tensor(uint16),tensor(uint32),tensor(uint64),tensor(uint8))所有张量类型
I 在 (
tensor(int64))int64 型张量,应为标量。
B 在 (
tensor(bool))bool 型张量,应为标量。
Loop - 1¶
版本¶
名称: Loop (GitHub)
域:
main起始版本:
1函数:
False支持级别:
SupportType.COMMON形状推断:
True
此版本的运算符自 版本 1 起可用。
摘要¶
通用循环结构。此循环具有多个终止条件
行程计数。在运行时指定的迭代计数。通过指定输入 M 设置。可选。设置为空字符串表示省略。请注意,可以通过为输入 M 传入常量节点来指定静态行程计数(在图构造时指定)。
循环终止条件。这是操作符的一个输入,它决定是否运行第一次迭代,也是循环主体图的循环依赖。循环主体图必须为条件变量生成一个值,无论是否提供此输入。
此表总结了此操作符的运行模式,并附带等效的 C 风格代码
操作符输入定义为 (max_trip_count, condition_var)。
input ("", ""):
for (int i=0; ; ++i) {
cond = ... // Note this value is ignored, but is required in the body
}
input ("", cond) // Note this is analogous to a while loop
bool cond = ...;
for (int i=0; cond; ++i) {
cond = ...;
}
input ("", 1) // Note this is analogous to a do-while loop
bool cond = true
for (int i=0; cond; ++i) {
cond = ...;
}
input (trip_count, "") // Note this is analogous to a for loop
int trip_count = ...
for (int i=0; i < trip_count; ++i) {
cond = ...; // ignored
}
input (trip_count, cond)
int trip_count = ...;
bool cond = ...;
for (int i=0; i < trip_count && cond; ++i) {
cond = ...;
}
使用示例 - 条件和行程计数
graph predict-net {
%a = Constant[value = <Scalar Tensor [3]>]()
%b = Constant[value = <Scalar Tensor [6]>]()
%keepgoing = Constant[value = <Scalar Tensor [1]>]()
%max_trip_count = Constant[value = <Scalar Tensor [10]>]()
%keepgoing_out, %b_out, %user_defined_vals = Loop[body = <graph body-net>](%max_trip_count, %keepgoing, %b)
return
}
graph body-net (
%i[INT32, scalar]
%keepgoing[BOOL, scalar]
%b[INT32, scalar]
) {
%my_local = Add(%a, %b)
%b_out = Sub(%a, %b)
%keepgoing_out = Greater(%my_local, %b_out)
%user_defined_vals = Add(%b, %b)
return %keepgoing_out, %b_out, %user_defined_vals
}
等效 C 代码示例
{
/* User-defined code (enclosing scope) */
int a = 3, b = 6;
bool keepgoing = true; // Analogous to input cond
/* End user-defined code */
/* Implicitly-defined code */
const int max_trip_count = 10; // Analogous to input M
int user_defined_vals[]; // Imagine this is resizable
/* End implicitly-defined code */
for (int i=0; i < max_trip_count && keepgoing; ++i) {
/* User-defined code (loop body) */
int my_local = a + b; // Reading values in the enclosing scope is fine
b = a - b; // writes fine if we specify b as a loop-carried dependency
keepgoing = my_local > b; // keepgoing is a loop-carried dependency
user_defined_vals[i] = b + b;
/* End user-defined code */
}
// my_local = 123; // Can't do this. my_local was defined in the body
// These below values are live-out from the loop and therefore accessible
b_out; user_defined_vals; keepgoing_out;
}
此代码片段中有几点值得注意
来自封闭范围的值(即此处的变量 a)在范围内,并且可以在循环的输入中引用。
您希望在封闭范围中可用的任何变量(即变量 b 和 keepgoing)都必须声明为循环依赖项(在操作符输入和输出以及主体网络输入和输出处)或扫描输出。
在循环体中创建的值不能在封闭范围中访问。
请注意,此操作符的语义支持“对角线”或“波前”执行。(有关示例,请参见此处的步骤 3:https://devblogs.nvidia.com/optimizing-recurrent-neural-networks-cudnn-5/)。前端应将多层 RNN 作为一系列 While 操作符(其中时间是内部循环维度)发出,每个后续层消耗前一层的 scan_outputs,可能通过几个逐点操作符(例如 dropout、残差连接、线性层)。
属性¶
body - 图 (必需)
每次迭代运行的图。它有 2+N 个输入:(迭代次数、条件、循环依赖项...)。它有 1+N+K 个输出:(条件、循环依赖项...、扫描输出...)。每个扫描输出是通过在循环每次迭代结束时连接指定输出值而创建的。如果这些扫描输出的维度或数据类型在循环迭代中发生变化,则会发生错误。
输入¶
3 到 2147483647 个输入之间。
M (可选,异构) - I
在运行时指定的循环最大行程计数。可选。传入空字符串以跳过。
cond (可选,异构) - B
布尔终止条件。可选。传入空字符串以跳过。
v_initial (可变参数) - V
任何循环依赖项的初始值(在循环迭代中更改的值)
输出¶
1 到 2147483647 个输出之间。
v_final_and_scan_outputs (可变参数) - V
最终 N 个循环依赖值,然后是 K 个扫描输出
类型约束¶
V in (
tensor(bool),tensor(complex128),tensor(complex64),tensor(double),tensor(float),tensor(float16),tensor(int16),tensor(int32),tensor(int64),tensor(int8),tensor(string),tensor(uint16),tensor(uint32),tensor(uint64),tensor(uint8))所有张量类型
I 在 (
tensor(int64))int64 型张量,应为标量。
B 在 (
tensor(bool))bool 型张量,应为标量。