スカラーおよびベクター プログラミングの概要 - 2023.2 日本語

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

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

このセクションでは、スカラーおよびベクター プロセッシング要素のカーネル プログラミングの重要な要素について、概要を説明します。各要素および最適化手法の詳細は、その後のセクションで説明します。

次の例は、スカラー エンジンのみを使用しています。512 個の int32 要素を反復する for ループを示します。各ループ反復は、int32 a と int32 b を乗算を 1 回実行し、結果を c に格納して、出力バッファーに書き込みます。scalar_mul カーネルは、データ input_buffer<int32> の 2 つの入力ブロック (バッファー) に演算を実行し、データ output_buffer<int32> の出力バッファーを生成します。

バッファーへのアクセスには、スカラー反復子とベクター反復子が使用されます。バッファー API の詳細は、ストリーミング データ API を参照してください。

void scalar_mul(input_buffer<int32> & data1,
			input_buffer<int32> & data2,
			output_buffer<int32> & out){
        auto pin1 = aie::begin(data1);
        auto pin2 = aie::begin(data2);
        auto pout = aie::begin(out);
	for(int i=0;i<512;i++)
	{
		int32 a=*pin1++;
		int32 b=*pin2++;
		int32 c=a*b;
		*pout++ = c;
	}
}

次の例は、同じカーネルのベクター バージョンです。

void vect_mul(input_buffer<int32> & __restrict data1,
			input_buffer<int32> & __restrict data2,
			output_buffer<int32> & __restrict out){
        auto pin1 = aie::begin_vector<8>(data1);
        auto pin2 = aie::begin_vector<8>(data2);
        auto pout = aie::begin_vector<8>(out);
	for(int i=0;i<64;i++)
	chess_prepare_for_pipelining
	{
		aie::vector<int32,8> va=*pin1++;
		aie::vector<int32,8> vb=*pin2++;
		aie::accum<acc80,8> vt=mul(va,vb);
		aie::vector<int32,8> vc=srs(vt,0);
		*pout++ = vc;
	}
}

上記のコードでは、データ型 vector<int32,8> および accum<acc80,8> が使用されています。バッファー API begin_vector<8> は 8 個の int32 ベクターに対して反復処理を実行する反復子を返し、変数 va および vb に格納します。これらの 2 つの変数はベクター型変数であり、組み込み関数 mul に渡され、accum<acc80,8> 型の vt が生成されます。accum<acc80,8> 型は、vector<int32,8> 型変数 vc を返して出力ウィンドウに書き込むシフト/丸め/飽和関数 srs によってリダクションされます。AI エンジンでサポートされるデータ型の追加の詳細は、この後のセクションで説明します。

vect_mul 関数の入力パラメーターと出力パラメーターに __restrict キーワードを使用すると、データの独立性が明示的に示され、コンパイラで最適化をより積極的に実行できます。

chess_prepare_for_pipelining は、カーネル コンパイラでループの最適化パイプラインが実現されるよう指示するコンパイラ プラグマです。

この関数例のスカラー バージョンは 1055 サイクルかかりますが、ベクター バージョンは 99 サイクルしかかかりません。カーネルのベクター バージョンを使用すると、10 倍以上高速になります。ベクター プロセッシング自体は、int32 乗算の 8 倍のスループットを達成しますが、レイテンシが高く、全体的なスループットは 8 倍になりません。ループ最適化を使用すると、10 倍近くになります。この後のセクションでは、使用可能なさまざまなデータ型、使用可能なレジスタ、ループでのソフトウェアのパイプライン処理などの概念や __restrict などのキーワード使用して AI エンジンで実現可能な最適化について詳しく説明します。