映射约束 - 2023.2 简体中文

AI 引擎内核与计算图编程指南 (UG1079)

Document ID
UG1079
Release Date
2023-12-04
Version
2023.2 简体中文

以下函数有助于在 AI 引擎阵列上对内核与缓冲器的物理映射构建各种类型的约束。

作用域

约束必须显示在用户 graph 构造函数内部。

内核位置构造函数

location_constraint tile(int col, int row)

此位置构造函数指向位于 AI 引擎阵列内特定的列和行的特定 AI 引擎 tile(拼块)。列和行的值基于零,其中第零行从带有计算处理器的最下层的行开始计数,第零列从最左侧的列开始计数。先前使用的构造函数 proc(col,row) 现已弃用。

location_constraint location<kernel> (kernel&)

此约束可使用以下赋值运算符提供句柄,该句柄指向内核位置,以便将此内核的位置约束在特定 tile 上,或者与另一个内核并置。

缓冲器位置构造函数

location_constraint address(int col, int row, int offset)

此位置构造函数指向特定 AI 引擎 tile 上的特定数据存储器地址偏移。偏移地址是相对于该 tile 的地址,从零开始且最大值为 32768 (32K)。

location_constraint bank(int col, int row, int bankid)
此位置构造函数指向特定 AI 引擎 tile 上的特定数据存储体。此 bank ID 是相对于该 tile 的 ID,值为 0、1、2 或 3。
注释: 硬件视图是位宽为 128 位的 8 个 bank。软件视图是位宽为 256 位的 4 个 bank。
location_constraint offset(int offset_value)

此位置构造函数用于指定数据存储器地址偏移。偏移地址介于 0 到 32768 (32K) 之间,且相对于编译器分配的 tile。

location_constraint location<buffer> (port<T>&)

此位置构造函数可提供句柄,该句柄指向连接到内核输入、输出或输入输出端口的缓冲器位置。它可使用如下赋值运算符,将该缓冲器的位置约束到特定地址或 bank,或者将其约束到与另一个内核位于相同 tile 上,或者与另一个缓冲器位于相同 bank 上。将两个缓冲器约束到相同地址是错误的行为。此构造函数仅适用于缓冲器内核端口。

location_constraint location<stack> (kernel&)

此位置构造函数可提供句柄,该句柄指向 AI 引擎的系统存储器(栈和堆)内用于映射指定内核的位置。由此提供了一种机制,用于根据该内核使用的其他缓冲器的相对位置来约束系统存储器的位置。

重要: 栈位置偏移必须为 32 字节的倍数。
location_constraint location<parameter> (parameter&)

此位置构造函数提供了句柄,该句柄指向 graph 中声明的参数阵列(例如,查找表)的位置。

边界框构造函数

location_constraint bounding_box(int column_min, int row_min, int column_max, int row_max)

此边界框构造函数为要布局在 AI 引擎拼块内的 graph 指定了矩形边界框,其范围为从 column_mincolumn_max 的列之间以及从 row_minrow_max 的行之间。在任一初始值设定项列表中均可使用多个边界框位置约束来指定一个不规则形状的边界区域。

运算符函数

location_constraint& operator=(location_constraint)

此运算符用于表述两个位置构造函数之间的等同性约束。它允许表述各种类型的绝对或相对位置约束。

以下示例演示了如何约束要布局在指定 AI 引擎拼块上的内核。

location<kernel>(k1) = tile(3,2);

以下模板演示了如何对连接到端口的双缓冲器的位置进行约束,其中端口将布局在特定地址或 bankid 上。在初始值设定项列表中应指定最多两个元素以约束双 bank 的位置。此外,如果这些缓冲器均由同一个 DMA 引擎进行读取或写入,则必须位于相同拼块上。

location<buffer>(port1) = { [address(c,r,o) | bank(c,r,id)] , [address(c,r,o) | bank(c,r,id)] };

以下模板演示了如何对内核的参数查找表或系统存储器的位置进行约束,其中内核将布局在特定地址或 bankid 上。

location<parameter>(param1) = [address(c,r,o) | bank(c,r,id)];

location<stack>(k1) = [address(c,r,o) | bank(c,r,id)];

以下示例演示了如何对要布局在同一个 AI 引擎上的两个内核进行相关约束。这强制两个内核按拓扑结构顺序进行排序,并且无需同步即可共享存储缓冲器。

location<kernel>(k1) = location<kernel>(k2);

以下示例演示了如何将缓冲器、栈或参数位置约束到与内核相同的拼块上。这样可确保另一个内核 k1 无需 DMA 即可访问缓冲器或参数阵列。

location<buffer>(port1) = location<kernel>(k1);

location<stack>(k2) = location<kernel>(k1);

location<parameter>(param1) = location<kernel>(k1);

以下示例演示了如何将缓冲器、栈或参数的位置与另一个缓冲器、栈或参数的位置约束到同一个 bank 上。当两个缓冲器并置时,这样即可将两个乒缓冲器约束到同一个 bank 上,同时将两个乓缓冲器约束到另一个 bank 上。

location<buffer>(port2) = location<buffer>(port1);

location<stack>(k1) = location<buffer>(port1);

location<parameter>(param1) = location<buffer>(port1);

以下示例演示了如何对要布局在边界框内的 graph 或者多个边界框内的联合区域进行约束。

location<graph>(g1) = bounding_box(1,1,2,2);

location<graph>(g2) = { bounding_box(3,3,4,4), bounding_box(5,5,6,6) };
以下示例演示了如何使用 DMA FIFO 搭配 aie_tile/memory_tile/shim_tile、tile 列号、tile 行号、存储器地址和大小作为输入参数和/或使用串流开关 FIFO 搭配 aie_tile/memory_tile/shim_tile、tile 列号、tile 行号及 FIFO 标识符作为输入参数来约束 FIFO 位置。
location(net0) = { dma_fifo(tile_type0, col0, row0, address0, size0), ss_fifo(tile_type1, col1, row1, fifo_id1), ... }

非等同性函数

void not_equal(location_constraint lhs, location_constraint rhs)

此函数用于为两个 location_constraint 参数(lhsrhs)表述 lhsrhs。它允许指定非并置约束。not_equal 缓冲器约束仅适用于单缓冲器。此约束不应搭配双缓冲器使用。

以下示例演示了如何指定两个内核 k1k2,这两个内核不应映射到相同 AI 引擎

not_equal(location<kernel>(k1), location<kernel>(k2));

以下示例演示了如何指定两个缓冲器 port1port2,这两个缓冲器不应映射到相同存储体。

not_equal(location<buffer>(port1), location<buffer>(port2));

约束盖戳和重复

以下示例演示了如何约束要布局在边界框内的 graph。在此例中,tx_chain0 graph 用作为参考,其对象将首先布局到 tx_chain1tx_chain2 graph 中,并在这两个 graph 中为这些对象盖戳。所有相同的 graph(参考 graph 和可盖戳的 graph)的行号必须相同,并且必须以相同的行奇偶性开始和结束,这表示参考 graph 的边界框始于偶数行且止于奇数行,那么所有盖戳的 graph 也必须遵循相同的规范。存在此限制的原因是因为 AI 引擎阵列中存在镜像拼块 (mirrored tile)。在一行中,AI 引擎后接存储器组,在下一行中,该存储器组后接 AI 引擎,且两者位于同一拼块内。

location<graph>(tx_chain0) = bounding_box(0,0,3,3);
location<graph>(tx_chain1) = bounding_box(4,0,7,3);
location<graph>(tx_chain2) = bounding_box(0,4,3,7);

location<graph>(tx_chain1) = stamp(location<graph>(tx_chain0));
location<graph>(tx_chain2) = stamp(location<graph>(tx_chain0));