数据重塑 - 2022.1 简体中文

AI 引擎内核编码 最佳实践指南 (UG1079)

Document ID
UG1079
Release Date
2022-05-25
Version
2022.1 简体中文

AI 引擎 API 提供了更改矢量内的元素位置、从更大的矢量中抽取子矢量或者将来自两个或两个以上矢量的元素加以组合的操作。

下列提供的 API 可用于按特定模式检索矢量的一半。

aie::filter_even
按如下方式返回大小减半的矢量:out = { v[0:step], v[2*step:3*step], ...}
aie::filter_odd
按如下方式返回大小减半的矢量:out = { v[step:2*step], v[3*step:4*step], ...}
注释: step 参数必须为 2 的幂值。
aie::vector<int32,8> result_e=aie::filter_even(xbuff, /*step=*/1);
aie::vector<int32,8> result_o=aie::filter_even(xbuff, /*step=*/4);

下图显示了 aie::filter_evenaie::filter_odd 选中元素的方式。

图 1. aie::filter_even

图 2. aie::filter_odd

aie::select 可用于从两个矢量(或者一个标量和一个矢量)中选择元素以构成一个新的矢量。aie::mask 用于指定要选中的元素。

aie::select
按掩码值的每个位来选择元素:out = {mask[0] == 0? a[0] : b[0], …}
aie::vector<int32,8> vc=aie::select(va,vb,msk_value);//vc[i]=(mask_value[i]==0)?va[i]:vb[i]

AI 引擎 API 可提供以下函数,用于将矢量元素按特定数值移位,但保留矢量大小和元素值。

aie::shuffle_down
将元素向下移 n 位:out = {v[n], v[n+1], …, v[Elems-1], undefined[0],…,undefined[n-1]}。这样会定义更高位的元素 output(out[n],out[n+1],…)。“Elems”表示矢量大小。
aie::shuffle_up
将元素向上移 n 位:out = {undefined[0],…,undefined[n-1],v[0], v[1], …}。这样会定义更低位的元素 output(out[0],…,out[n-1])。
aie::shuffle_down_rotate
将元素向下旋转 n 位:out = {v[n], v[n+1], …,v[Elems-1], v[0], …,v[n-1]}。
aie::shuffle_up_rotate
将元素向上旋转 n 位:out = {v[Elems-n], …, v[Elems-1], v[0], …,v[n-1]}。
aie::shuffle_down_fill
将元素向下移 n 位,并以来自第二个矢量的元素进行填充:out = {v[n], v[n+1], …, v[Elems-1], fill[0],…,fill[n-1]}。这样将以来自第二个矢量 "fill"(fill[0],…,fill[n-1]) 的元素填充更高位的元素 output(out[n],out[n+1],…)。
aie::shuffle_up_fill
将元素向上移 n 位,并以来自第二个矢量的元素进行填充:out = {fill[Elems-n],…,fill[Elems-1],v[0], v[1], …}。这样将以来自第二个矢量 "fill"(fill[Elems-n],…,fill[Elems-1]) 的元素填充更低位的元素 output(out[0],…,out[n-1])。
aie::vector<int32,8> v,fill;
//v_d[0:4]=v[3:7], (v_d[5],v_d[6],v_d[7] are undefined) 
auto v_d=aie::shuffle_down(v,3);
//v_u[3:7]=v[0:4], (v_u[0],v_u[1],v_u[2] are undefined) 
auto v_u=aie::shuffle_up(v,3);
auto vd_r=aie::shuffle_down_rotate(v,3);//vd_r[0:4]=v[3:7],vd_r[5:7]=v[0:2] 
auto vu_r=aie::shuffle_up_rotate(v,3);//vu_r[3:7]=v[0:4],vu_r[0:2]=v[5:7]
//v_d_fill[0:4]=v[3:7], v_d_fill[5:7]=fill[0:2]
auto v_d_fill=aie::shuffle_down_fill(v,fill,3);
//v_u_fill[3:7]=v[0:4], v_u_fill[0:2]=fill[5:7]
auto v_u_fill=aie::shuffle_up_fill(v,fill,3);

矢量可通过如下方式加以反转:

aie::reverse
反转元素:out = {v[Elems-1], …, v[1], v[0]}
aie::vector<int32,8> v_rev=aie::reverse(v,3);//v_rev[0:7]=v[7:0]

AI 引擎 API 可提供相应函数来打乱两个输入矢量的顺序,并将其组合为更大的输出矢量。这两个矢量的类型和大小必须相同。返回类型为 std::pair

aie::interleave_zip
按如下模式选中并组合两个矢量:out = { v1[0:step], v2[0:step], v1[step:2*step], v2[step:2*step], ...}
aie::inerleave_unzip
按如下模式选中并组合两个矢量:out = { v1[0:step], v1[2*step:3*step], ..., v2[0:step], v2[2*step:3*step], ..., v1[step:2*step], v1[3*step:4*step], ..., v2[step:2*step], v2[3*step:4*step], ...}
注释: step 参数必须为 2 的幂值。

以下示例会取两个包含 rva 中的实数和 rvb 中的虚数(类型为 aie::vector<int32,8>)的矢量,并创建一个新的复数矢量。它还显示了取回实数部分和虚数部分并将其与原始值进行比较的方式。

aie::vector<int32,8> rva,rvb;
auto rv=aie::interleave_zip(rva,rvb,/*step*/1);
aie::vector<cint32,8> cv=aie::concat(rv.first.cast_to<cint32>(),rv.second.cast_to<cint32>());

auto [uva,uvb]=aie::interleave_unzip(rv.first,rv.second,/*step*/1);
bool ret=aie::equal(rva,uva) && aie::equal(rvb,uvb);//return true