データの再形成 - 2023.2 日本語

AI エンジン カーネルおよびグラフ プログラミング ガイド (UG1079)

Document ID
UG1079
Release Date
2023-12-04
Version
2023.2 日本語

AI エンジン API では、ベクター内の要素の位置を変更したり、大きなベクターからサブベクターを抽出したり、複数のベクターの要素を結合したりする演算を実行できます。

次の API は、特定のパターンのベクターの半分を取得します。

aie::filter_even
out = { v[0:step-1], v[2*step:3*step-1], ... } を使用してサイズが 1/2 のベクターを返します。
aie::filter_odd
out = { v[step:2*step-1], v[3*step:4*step-1], ... } を使用してサイズが 1/2 のベクターを返します。
注記: パラメーター step は、2 のべき乗である必要があります。
aie::vector<int32,16> xbuff;

// first parameter is the vector value
// second paramter is the step value
aie::vector<int32,8> result_e=aie::filter_even(xbuff,1);
aie::vector<int32,8> result_o=aie::filter_odd(xbuff,4);

次の図に、aie::filter_even および aie::filter_odd でどのように要素が選択されるかを示します。

図 1. aie::filter_even

図 2. aie::filter_odd

aie::select を使用して、2 つのベクター (または 1 つのスカラーと 1 つのベクター) から要素を選択し、新しいベクターを形成できます。aie::mask は、選択する要素を指定するのに使用します。

aie::select
マスク値 out[0] = {mask[0] == 0? a[0] : b[0], …} の各ビットを使用して要素を選択します。
aie::vector<int32,8> va,vb;
aie::mask<8> msk_value;

// vc[i]=(mask_value[i]==0)?va[i]:vb[i]
aie::vector<int32,8> vc=aie::select(va,vb,msk_value);

AI エンジン API には、ベクターのサイズと要素値を変更せずに特定の数値でシフトする次の関数があります。

aie::shuffle_down
out = {v[n], v[n+1], …, v[Elems-1], undefined[0],…,undefined[n-1]} を使用して要素を n 分下位にシフトします。出力の上位の要素 (output(out[n],out[n+1],…) は未定義です。Elems はベクターのサイズです。
aie::shuffle_up
out = {undefined[0],…,undefined[n-1],v[0], v[1], …} を使用して要素を n 分上位にシフトします。出力の下位の要素 (out[0],…,out[n-1]) は未定義です。
aie::shuffle_down_rotate
out = {v[n], v[n+1], …,v[Elems-1], v[0], …,v[n-1]} を使用して要素を n 分下位に循環させます。
aie::shuffle_up_rotate
out = {v[Elems-n], …, v[Elems-1], v[0], …,v[n-1]} を使用して要素を n 分上位に循環させます。
aie::shuffle_down_fill
out = {v[n], v[n+1], …, v[Elems-1], fill[0],…,fill[n-1]} を使用して、要素を n 分下位にシフトし、2 つ目のベクターからの要素を挿入します。出力の上位の要素 (out[n],out[n+1],…) に 2 つ目のベクター fill からの要素 (fill[0],…,fill[n-1]) を挿入します。
aie::shuffle_up_fill
out = {fill[Elems-n],…,fill[Elems-1],v[0], v[1], …} を使用して、要素を n 分上位にシフトし、2 つ目のベクターからの要素を挿入します。出力の下位の要素 (out[0],…,out[n-1]) に 2 つ目のベクター fill からの要素 (fill[Elems-n],…,fill[Elems-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);

// vd_r[0:4]=v[3:7],vd_r[5:7]=v[0:2] 
auto vd_r=aie::shuffle_down_rotate(v,3);

// vu_r[3:7]=v[0:4],vu_r[0:2]=v[5:7]
auto vu_r=aie::shuffle_up_rotate(v,3);

// 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]} を使用して要素を反転します。
// v_rev[0:7]=v[7:0]
aie::vector<int32,8> v_rev=aie::reverse(v);

AI エンジン API には、2 つの入力ベクターをシャッフルして大きい出力ベクターを作成する関数があります。2 つのベクターのデータ型とサイズは同じである必要があります。戻り値のデータ型は std::pair です。

aie::interleave_zip
2 つのベクターを選択して次のパターンで組み合わせ、ベクターの std::pair を返します: out = { v1[0:step-1], v2[0:step-1], v1[step:2*step-1], v2[step:2*step-1], ...}。
aie::interleave_unzip
2 つのベクターを選択して次のパターンで組み合わせ、ベクターの std::pair を返します: out = { v1[0:step-1], v1[2*step:3*step-1], ..., v2[0:step-1], v2[2*step:3*step-1], ..., v1[step:2*step-1], v1[3*step:4*step-1], ..., v2[step:2*step-1], v2[3*step:4*step-1], ...}。
注記: パラメーター step は、2 のべき乗である必要があります。
alignas(aie::vector_decl_align) int32 data[16]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
aie::vector<int32,8> rva=aie::load_v<8>(data);
aie::vector<int32,8> rvb=aie::load_v<8>(data+8);
std::pair<aie::vector<int32,8>,aie::vector<int32,8>> rv=aie::interleave_zip(rva,rvb,4); 
std::pair<aie::vector<int32,8>,aie::vector<int32,8>> rv2=aie::interleave_unzip(rva,rvb,2); 

// rv.first=1 2 3 4 9 10 11 12
aie::print(rv.first,true,"rv.first=");

// rv.second=5 6 7 8 13 14 15 16 
aie::print(rv.second,true,"rv.second=");

// rv2.first=1 2 5 6 9 10 13 14 
aie::print(rv2.first,true,"rv2.first=");

// rv2.second=3 4 7 8 11 12 15 16 
aie::print(rv2.second,true,"rv2.second=");
次の例は、実数を rva、虚数を rvb (aie::vector<int32,8> 型) に含む 2 つのベクターを取得し、新しい複素ベクターを作成します。実数部と虚数部を抽出し、元の値と比較する方法も示します。
aie::vector<int32,8> rva,rvb;
auto rv=aie::interleave_zip(rva,rvb,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,1);

// return value as true
bool ret=aie::equal(rva,uva) && aie::equal(rvb,uvb);
AI エンジン API は、入力ベクターを行と列で指定された次元の行列として解釈し、その転置を実行する関数を提供します。この関数は、指定された行列の転置として並べられたベクターを返します。行または列が 1 の場合、入力ベクターが返されます。
  • aie::transpose
alignas(aie::vector_decl_align) int16 data[16]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
aie::vector<int16,16> va=aie::load_v<16>(data);

// Row=4 & Col=4
auto va_t=aie::transpose(va,4,4);

// print va_t
// va_t=1 5 9 13 2 6 10 14 3 7 11 15 4 8 12 16 
aie::print(va_t,true,"va_t=");