.. dotFunc ベクタ・ドット演算子の一覧 ========================== ベクタ・ドット演算子は、処理ターゲットベクタにドット記号を介して接続される他の言語におけるメンバ関数のような見た目の関数群です。 かならず操作対象のベクタが存在し、それを引数に基づき操作します。また、一部の演算子は引数にも副作用を与えるものが存在します。 ベクタ操作はその性格からインプレイスで行われるものがほとんどなので、記述にあたっては何が書き換えられるのか確認が必要です。 一般的なベクトルの演算処理 -------------------------- ベクタ・ドット演算子が付加されるターゲットベクタに対する操作を行う演算子群です。 結果はベクタであり、ターゲットベクタをインプレイスで書き換えます。 **clear() または zeros()** ターゲットベクタの全要素をゼロクリアします。 .. code-block:: none vTest0 : i16[32] = 99, ~ vTest0 = vTest0.zeros(); 上記例では vTest0は 全要素が値99で初期化されていますが、zeros()を実行した時点で全要素0に書き代わります。 **ones$X()** ターゲットベクタの全要素に1を立てます。 Xには要素サイズを示す語B, W, Lが入ります。 .. code-block:: none vTest0 : i16[32] = 99, ~ vTest0 = vTest0.ones$W(); 上記例では vTest0は 全要素が値99で初期化されていますが、ones()を実行した時点で全要素1に書き代わります。 **abs$X()** ターゲットベクタの各要素の絶対値をとります。Xには要素サイズを示す語B, W, Lが入りますが、現命令セットでサポートされるのはBのみです。 **bit_not()** ターゲットベクタの全要素のビットを反転します。 **min$XX(引数ベクタ)** ターゲットベクタと引数ベクタを要素毎に比較し、小さい方の値をとります。Xには符号なし、符号付きおよび要素サイズを示す語 UB, UW, UL, IB, IW, ILが入りますが、現命令セットでサポートされるのはUBとIWです。 .. code-block:: none vTest0 : i16[32] = vList[55, 99, 33, 44, 55, 66, 77, 88, 99, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32], vTest2 : i16[32] = 20, ~ vTest2 = vTest2.min$IW(vTest0); 上記の例の実行により、vTest2にはvTest0の値20より大きい要素がすべて20に置き換えられたベクトルが入ります。 **max$XX(引数ベクタ)** ターゲットベクタと引数ベクタを要素毎に比較し、大きい方の値をとります。Xには符号なし、符号付きおよび要素サイズを示す語 UB, UW, UL, IB, IW, ILが入りますが、現命令セットでサポートされるのはUBとIWです。 .. code-block:: none vTest0 : i16[32] = vList[55, 99, 33, 44, 55, 66, 77, 88, 99, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32], vTest1 : i16[32] = 20, ~ vTest1 = vTest1.max$IW(vTest0); 上記の例の実行により、vTest1にはvTest0の値20より小さい要素がすべて20に置き換えられたベクトルが入ります。 **add$XX(引数ベクタ)** ターゲットベクタと引数ベクタを要素毎に加算します。Xには符号なし、符号付きおよび要素サイズを示す語 UB, UW, UL, IB, IW, ILが入りますが、現命令セットでサポートされるのはUWのみです。 IWとUWの違いは飽和演算を行うか否かなので、飽和演算を行わないのであれば、符号付き数をUWで処理しても問題ありません。 **e_add$XX(ワークベクタ, スカラー値/スカラ変数)** ターゲットベクタの各要素にスカラー値を加算します。 計算のためにワークベクタ1個を必要とします。 Xには符号なし、符号付きおよび要素サイズを示す語 UB, UW, UL, IB, IW, ILが入りますが、現命令セットでサポートされるのはUWのみです。 IWとUWの違いは飽和演算を行うか否かなので、飽和演算を行わないのであれば、符号付き数をUWで処理しても問題ありません。 .. code-block:: none vTest1 = vTest1.e_add$UW(vTEMP, scalar_data); 上記の例では、vTest1ベクタの全要素に変数scalar_dataの保持する値が足し込まれます。 **sub$XX(引数ベクタ)** ターゲットベクタから引数ベクタを要素毎に減算します。Xには符号なし、符号付きおよび要素サイズを示す語 UB, UW, UL, IB, IW, ILが入りますが、現命令セットでサポートされるのはIWのみです。 なおIWはサチュレートします。(後日、サチュレートの有無の制御コンパイラディレクティブを追加の予定) **e_sub$XX(ワークベクタ, スカラー値/スカラ変数)** ターゲットベクタの各要素からスカラー値を減算します。 計算のためにワークベクタ1個を必要とします。 Xには符号なし、符号付きおよび要素サイズを示す語 UB, UW, UL, IB, IW, ILが入りますが、現命令セットでサポートされるのはIWのみです。 .. code-block:: none vTest1 = vTest1.e_sub$IW(vTEMP, scalar_data); 上記の例では、vTest1ベクタの全要素から変数scalar_dataの保持する値が減算されます。 **mul$XX(引数ベクタ)** ターゲットベクタと引数ベクタを要素毎に乗算します。Xには符号なし、符号付きおよび要素サイズを示す語 UB, UW, UL, IB, IW, ILが入りますが、現命令セットでサポートされるのはIWのみです。 なおIWはサチュレートします。(後日、サチュレートの有無の制御コンパイラディレクティブを追加の予定) **e_mul$XX(ワークベクタ, スカラー値/スカラ変数)** ターゲットベクタの各要素にスカラー値を乗じます。 計算のためにワークベクタ1個を必要とします。 Xには符号なし、符号付きおよび要素サイズを示す語 UB, UW, UL, IB, IW, ILが入りますが、現命令セットでサポートされるのはIWのみです。 .. code-block:: none vTest1 = vTest1.e_mul$IW(vTEMP, scalar_data); 上記の例では、vTest1ベクタの全要素に変数scalar_dataの保持する値が乗じられます。 **e_set$X(スカラー値/スカラ変数)** ターゲットベクタの全要素に同じスカラー値を代入します。 Xには要素サイズを示す語B, W, Lが入ります。 符号付き数も格納できますが、符号付き、符号なしに関わらず要素サイズ分の下位ビット数を代入します。 .. code-block:: none vTest0 = vTest0.e_set$W(2); 上記の例では、vTest0ベクタの全要素に値2が格納されます。 .. code-block:: none vTest1 = vTest1.e_mul$IW(vTEMP, scalar_data); 上記の例では、vTest1ベクタの全要素に変数scalar_dataの保持する値が乗じられます。 **element_shift_left$X(スカラー変数または定数)** ターゲットベクタの各要素を引数のスカラー量だけ左論理シフトします。 Xには要素サイズを示す語 B, W, Lが入りますが、現命令セットでサポートされるのはWのみです。 **element_shift_right$X(スカラー変数または定数)** ターゲットベクタの各要素を引数のスカラー量だけ右論理シフトします。 Xには要素サイズを示す語 B, W, Lが入りますが、現命令セットでサポートされるのはB, Wのみです。 **shift_up(ベクター変数1, ベクター変数2, スカラー変数または定数)** ベクター変数1全体をスカラー量ビットだけ、左シフトした値をターゲットベクタに格納します。 スカラー量として要素のビット幅を指定すれば、所望の数だけ各要素を要素番号が上になる方向にシフトすることができます。 このシフトにより、空いた下位の部分には、ベクター変数2の最上位要素が入ります。シフト量として許されるのは0~255ビットまでです。 **shift_down(ベクター変数1, ベクター変数2, スカラー変数または定数)** ベクター変数1全体をスカラー量ビットだけ、右シフトした値をターゲットベクタに格納します。 スカラー量として要素のビット幅を指定すれば、所望の数だけ各要素を要素番号が下になる方向にシフトすることができます。 このシフトにより、空いた上位の部分には、ベクター変数2の最下位要素が入ります。シフト量として許されるのは0~255ビットまでです。 **convert$X(ベクタ変数)** 引数のベクタ変数の形式を変換し、ターゲットベクタに格納します。 Xに入る変換型指定のうち現状サポートされるのは以下のものです。 * UB2UW 符号なしバイト要素のベクタをワード要素のベクタに変換 * IW2IB 符号ありワード要素のベクタをバイト要素のベクタに変換 **filter_sub(ベクタ変数, フィルタ値)** 引数のベクタ変数にフィルタ値を乗じた値をターゲットベクタに足し込みます。 ターゲットベクタ変数は、引数のベクタ変数より2ベクタ・レジスタ分長くなければなりません。 ベクトル要素の処理 ------------------ ベクタ・ドット演算子が付加されるターゲットベクタに対する操作を行いますが、その単位は要素が中心となる演算子群です。 要素を書き込むものはターゲットベクタをインプレイスで書き換えます。 要素を読み出すものはターゲットベクタには変更はなく、引数にとるスカラー変数が書き換えられます。 **init_ins_sort()** ターゲットベクタを挿入ソート用のリストに使えるように初期化します。 ターゲットベクタは、挿入ソートの期間中ベクタレジスタ上に保持されるよう固定アロケートする必要があります。 **ins_sort(挿入値、先頭要素番号、リターン要素番号変数)** 挿入値は32ビットの値で、変数もしくは即値として与えます。下の16ビットがソート対象のキーであり、 上の16ビットがなんらかのインデックスなどソートキーに結び付ける値です。 先頭要素番号で指定される要素からターゲットベクタの要素が挿入値と比較され昇順にソートされた順に格納されます。 先頭要素番号は通常0を与えることで先頭から検索が行われます。 ソート後リターン要素番号変数にデータ末尾の要素番号を返します。 ベクタ長を超える値が返った場合、末尾の結果はエリアが無いため捨てられたことを示します。 **get_element(取り出す要素番号、取り出し先変数)** 32ビット単位の要素番号で、ターゲットベクトルの途中の32ビット要素を取り出し先変数に取り出します。 **set_element(書き込む要素番号、書き込む変数または即値)** 32ビット単位の要素番号で、ターゲットベクトルの途中の32ビット要素に変数または即値を書き込みます。 **get_record(レコード番号, 要素番号, 取り出し先変数)** ターゲットベクトルをInteger変数が8個格納されたレコードとみなし、レコード番号とレコード内の要素番号で場所を指定し 32ビット要素を取り出し先変数に抽出します。 **set_record(レコード番号, 要素番号, 書き込む変数または即値)** ターゲットベクトルをInteger変数が8個格納されたレコードとみなし、レコード番号とレコード内の要素番号で場所を指定し 32ビット値を書き込みます。 **TODO** ドット演算子の拡充。名前で定義できるので記号演算子と違って数に制限なく定義できる。 必要なだけ追加する。 ins_sortは、降順の対応。キーを16ビットに限らない方式の追加。 get_element、set_elementは、32ビットに限らない方式の追加。 リダクション系演算子 -------------------- 本節ではベクトル要素間で演算を行って1個のスカラー値を得るリダクション系のドット演算子を説明します。 なお、本節の演算子はターゲットベクタを作業領域として使うため、alloc_vector()によりアロケートしたベクタを指定しなければなりません。 **sum$XX(引数ベクタ, スカラー変数)** 引数ベクタの全要素を積算した結果をスカラー変数に返します。 XXには符号なし、符号付きおよび要素サイズを示す語 UB, UW, UL, IB, IW, ILが入りますが、現命令セットでサポートされるのはIWのみです。 **prod$XX(引数ベクタ1, 引数ベクタ2,スカラー変数)** 引数ベクタ1と引数ベクタ2の各要素を乗じた結果を積算した数値をスカラー変数に返します。 XXには符号なし、符号付きおよび要素サイズを示す語 UB, UW, UL, IB, IW, ILが入りますが、現命令セットでサポートされるのはIWのみです。 この演算子により、ベクタの内積を計算することができます。 また、引数ベクタ1,2に同じベクタを指定すれば二乗和を求めることもできます。 **r_max$XX(引数ベクタ, スカラー変数)** 引数ベクタの全要素の中で最大のものをスカラー変数に返します。 XXには符号なし、符号付きおよび要素サイズを示す語 UB, UW, UL, IB, IW, ILが入りますが、現命令セットでサポートされるのはIWのみです。 .. code-block:: none vTest0 : i16[32] = vList[55, 99, 33, 44, 55, 66, 77, 88, 99, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32], ~ scalar_result : integer, ~ alloc_vector( vTEMP, __I16V, 16) ~ vTEMP = vTEMP.r_max$IW(vTest0, scalar_result); 上記の例の実行により、scalar_resultにはベクトルvTest0の値の最大値99が入ります **r_min$XX(引数ベクタ, スカラー変数)** 引数ベクタの全要素の中で最大のものをスカラー変数に返します。 XXには符号なし、符号付きおよび要素サイズを示す語 UB, UW, UL, IB, IW, ILが入りますが、現命令セットでサポートされるのはIWのみです。 .. code-block:: none vTest0 : i16[32] = vList[55, 99, 33, 44, 55, 66, 77, 88, 99, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32], ~ scalar_result : integer, ~ alloc_vector( vTEMP, __I16V, 16) ~ vTEMP = vTEMP.r_min$IW(vTest0, scalar_result); 上記の例の実行により、scalar_resultにはベクトルvTest0の値の最小値10が入ります **countIf$X(引数ベクタ, 比較値スカラー変数, 格納先スカラー変数)** 引数ベクタの全要素と比較値スカラー変数を比較し、一致する個数を格納先スカラー変数に返します。 Xには要素サイズを示す語 B, W, L が入りますが、現命令セットでサポートされるのはWのみです。 .. code-block:: none vTest0 : i16[32] = vList[55, 11, 33, 44, 11, 66, 77, 88, 99, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 11, 23, 24, 11, 26, 27, 28, 29, 11, 31, 32], ~ scalar_result : integer, scalar_data : integer; ~ alloc_vector( vTEMP, __I16V, 16) ~ scalar_data = 11; vTEMP = vTEMP.countIf$W(vTest0, scalar_data, scalar_result); 上記の例の実行により、scalar_resultにはベクトルvTest0内で値11を持つ要素の個数6が入ります **countOver$XX(引数ベクタ, 比較値スカラー変数, 格納先スカラー変数)** 引数ベクタの各要素と比較値スカラー変数を比較し、上回った個数を格納先スカラー変数に返します。 XXには符号なし、符号付きおよび要素サイズを示す語 UB, UW, UL, IB, IW, ILが入りますが、現命令セットでサポートされるのはUWのみです。 **countUnder$XX(引数ベクタ, 比較値スカラー変数, 格納先スカラー変数)** 引数ベクタの各要素と比較値スカラー変数を比較し、下回った個数を格納先スカラー変数に返します。 XXには符号なし、符号付きおよび要素サイズを示す語 UB, UW, UL, IB, IW, ILが入りますが、現命令セットでサポートされるのはUWのみです。 画像操作向け演算子 ------------------ 本節では画像操作向け機能を提供するドット演算子を説明します。 インタフェースのため、固定小数点数を取り扱える場合があります。 なお、本節の演算子はターゲットベクタを作業領域として使うため、alloc_vector()によりアロケートしたベクタを指定しなければなりません。 **get_array(引数は以下参照)** 画像バッファ領域より、矩形領域を切り出します。 転送元となる画像バッファ領域はバイト幅のデータの2次元配列です。 転送先となる画像バッファ領域はバイト幅の2次元配列でも、F16Qq形式の固定小数点数の2次元配列でも可能です。 F16Qq固定小数点型は、q=8~15の中で指定できます。 切り出せる領域の横幅はバイト単位でそのまま転送する場合、最大512要素幅まで、 バイトからF16Qn形式の固定小数点数への変換を伴う場合160要素幅までです。 なお、横幅は32の倍数に切り上げられます。 * 第1引数 転送先領域を指すポインタ変数を指定します。 * 第2引数 転送元画像バッファ領域を指すポインタ変数を指定します。use_image()コンパイラディレクティブなどで設定した変数を与えます。 * 第3引数 転送元画像での切り出し位置左上隅のx座標を保持する変数または即値を指定します。 * 第4引数 転送元画像での切り出し位置左上隅のy座標を保持する変数または即値を指定します。 * 第5引数 切り出す領域のバイト幅をパラメータまたは即値で指定します。 * 第6引数 切り出す領域の高さをパラメータまたは即値で指定します。 * 第7引数 処理タイプをパラメータまたは即値で指定します。 処理タイプに0を指定すると、バイト配列からバイト配列への単純転送が選択されます。 8以上15以下の数値を指定するとバイト配列からF16Qq形式への変換転送が選択され、指定された数値がqとなります。 転送元画像バッファ領域の横幅は、該当のポインタの保持するステップ幅から求められるので転送元画像バッファを指すポインタは正しく設定されていなければなりません。 また、取り扱うアドレスは32バイトアラインメントである必要があり、左上隅のx座標も32の倍数である必要があります。 ただし、この値は実行時に変数から読み込まれ、コンパイラはチェックを行いません。 不正な値を指定した場合、アドレスエラーが起こる可能性があります。 なお、第2引数のポインタ変数は、ポインタ変数か、ポインタ変数を指している byName引数であることをプログラマが担保しなければなりません。 第1引数のポインタ変数は、メモリアドレスを指している変数であれば、ポインタ変数に限らずExternal宣言された大域変数でも、ローカルなbyName引数でもかまいませんが、 その変数がアドレスを保持していることはやはりプログラマ管理です。 固定小数点プリミティブ演算子 ---------------------------- 主として8ビット数列に対して16ビット固定小数点係数列を積算(32ビット)するのに用いる演算子群です。 インプレイスでの処理に限定され、BLAS類似演算子、DNN向け演算子のようにメモリにアクセスすることはありません。 BLAS類似演算子、DNN向け演算子などの固定小数点演算子群よりも作用が小さいので「プリミティブ」という分類になっています。 **FPPvAvX8(引数は以下参照)** 入力Xベクトルと係数Aベクトルの同じ位置の要素同士を掛け合わせる度、その値を積算します。 入力Xベクトルを更新しながらこの演算を繰り返すことで、係数毎に多数回の積算を行わせることができます。 ターゲットはアロケート済のベクトルです。第2引数の係数ベクトル(F16Qq)と第3引数の入力ベクトル(符号なし8ビット)を要素毎乗じて得られた値を ターゲットの32ビット要素に積算します。vはベクトルの長さであり、128以下でなければなりません。 なお、第3引数の入力ベクトルをアロケートする際には6レジスタ以上を割り当てる必要があります。 * 第1引数 vの値を指定します。パラメータまたは即値で指定しなければなりません。 * 第2引数 固定小数点型の係数データをロードしたアロケート済ベクトルを指定します。 * 第3引数 U8型の要素を持つ入力データをロードしたアロケート済ベクトルを指定します。 **FPPvAuX8(引数は以下参照)** 入力Xベクトルの全要素に係数Aベクトルの特定位置の要素を掛け合わせる度、その値を積算します。 Aベクトルの処理対象位置を更新しながらこの演算を繰り返すことで、入力毎に多数回の積算を行わせることができます。 ターゲットはアロケート済のベクトルです。第2引数の係数ベクトル(F16Qq)の特定要素を第4引数で選択し、その値を第3引数の入力ベクトル(符号なし8ビット)の 全ての要素に乗じて得られるベクトル値をターゲットの32ビット要素に積算します。 uはベクトルの長さであり、128以下でなければなりません。 なお、第3引数の入力ベクトルをアロケートする際には7レジスタ以上を割り当てる必要があります。 * 第1引数 uの値を指定します。パラメータまたは即値で指定しなければなりません。 * 第2引数 固定小数点型の係数データをロードしたアロケート済ベクトルを指定します。 * 第3引数 U8型の要素を持つ入力データをロードしたアロケート済ベクトルを指定します。 * 第4引数 処理する係数の要素番号を持つ変数または即値を指定します。 **FPPmovAverage(引数は以下参照)** 重み付きの移動平均を計算します。この処理はFIRフィルタにも利用可能です。 入力ベクトルXをずらしながら重みベクトルAの要素と掛け合わせ、それぞれの位置で積算していきます。 結果の長さ(積算を求める位置の数)uは最大128。重みベクトルAの長さvは最大256です。 入力ベクトルXにはvの2倍-1の長さが最低必要です。 ターゲットはアロケート済のベクトルです。 第3引数の係数ベクトル(F16Qq)から1要素をとりだし、第3引数の入力ベクトル(符号なし8ビット)の 全ての要素に乗じて得られるベクトル値をターゲットの32ビット要素に積算したのち、 入力ベクトルを1要素シフトダウンします。 この処理を係数ベクトルの先頭から末尾までv回繰り返します。 入力データは破壊されます。 重みデータは保全されます。 * 第1引数 uの値を指定します。パラメータまたは即値で指定しなければなりません。 * 第2引数 vの値を指定します。パラメータまたは即値で指定しなければなりません。 * 第3引数 固定小数点型の重みデータをロードしたアロケート済ベクトルを指定します。 * 第4引数 U8型の要素を持つ入力データをロードしたアロケート済ベクトルを指定します。 * 第5引数 作業用のアロケート済ベクトルを指定します。最低レジスタ長3なければなりません。 **FPPv32tov16(引数は以下参照)** ターゲットはアロケート済のベクトルです。第1引数のQ値と、第2引数のv要素数にもとづきターゲットをインプレースでF16Qq型に変換します。 vはベクトルの長さであり、128以下でなければなりません。 * 第1引数 qの値を指定します。パラメータまたは即値で指定しなければなりません。 * 第2引数 vの値を指定します。パラメータまたは即値で指定しなければなりません。 BLAS類似演算子 -------------- 本節では一般的なBLASライブラリ類似の機能を提供するドット演算子を説明します。 すべて固定小数点数を取り扱います。 なお、本節の演算子はターゲットベクタを作業領域として使うため、alloc_vector()によりアロケートしたベクタを指定しなければなりません。 **FPBLmAvX_uB_L(引数は以下参照)** u行v列の配列mAとv列のベクタXを乗じた結果のu列のベクタにu列のベクタBを加えた結果を操作対象のベクタとして格納します。 以下で操作対象となるベクトルは、alloc_vectorコンパイラ・ディレクティブによりアロケート済でなければなりません。 入力データはポインタ変数の保持するアドレスから内部でロードされます。 また、出力データも「副作用として」ポインタ変数の指す先に内部でストアされるので、明示的に操作対象のベクトルを他に代入する必要はありません。 vは1024まで、uはメモリの許す限りの長さです。 演算型はF16Qq固定小数点型で、qは8,10,12の中で指定できます。 * 第1引数 qの値を指定します。パラメータまたは即値で指定しなければなりません。 * 第2引数 uの値を指定します。パラメータまたは即値で指定しなければなりません。 * 第3引数 vの値を指定します。パラメータまたは即値で指定しなければなりません。 * 第4引数 入力ベクトルXの値をロードするアロケート済ベクトル0を指定します。 * 第5引数 入力ベクトルXの値をロードするアロケート済ベクトル1を指定します。 * 第6引数 入力ベクトルXの値をロードするアロケート済ベクトル2を指定します。 * 第7引数 入力ベクトルXの値をロードするアロケート済ベクトル3を指定します。 * 第8引数 加算ベクトルBの値をロードするアロケート済ベクトルを指定します。 * 第9引数 入力ベクトルXの先頭を指すポインタ変数 * 第10引数 結果ベクトルYの先頭を指すポインタ変数 * 第11引数 加算ベクトルBの先頭を指すポインタ変数 * 第12引数 行列mAの先頭を指すポインタ変数 * 第13引数 結果をそのまま出力する場合は0, ReLU関数を施す場合は1 ここで、ポインタ変数は、メモリアドレスを指している変数であれば、ポインタ変数に限らずExternal宣言された大域変数でも、ローカルなbyName引数でもかまいません。 ただし、その変数がアドレスを保持していることはプログラマが担保しなければなりません。 また、内部でvは32の倍数毎に処理されるので、係数データは32の倍数となるようにあらかじめ0フィル調整が必要です。 uは8の倍数毎処理なので、u方向への0フィル調整も必要です。 これらの調整を行うツールが準備されているので、vFileで読み込む前に処理を行ってください。 **FPBLmAvX_uB(引数は以下参照)** u行v列の配列mAとv列のベクタXを乗じた結果のu列のベクタにu列のベクタBを加えた結果を操作対象のベクタとして格納します。 以下で操作対象となるベクトルは、alloc_vectorコンパイラ・ディレクティブによりアロケート済でなければなりません。 入力データはポインタ変数の保持するアドレスから内部でロードされます。 また、出力データも「副作用として」ポインタ変数の指す先に内部でストアされるので、明示的に操作対象のベクトルを他に代入する必要はありません。 現状、vは256まで、uは128までです。 演算型はF16Qq固定小数点型で、qは8,10,12の中で指定できます。 * 第1引数 qの値を指定します。パラメータまたは即値で指定しなければなりません。 * 第2引数 uの値を指定します。パラメータまたは即値で指定しなければなりません。 * 第3引数 vの値を指定します。パラメータまたは即値で指定しなければなりません。 * 第4引数 入力ベクトルXの値をロードするアロケート済ベクトルを指定します。 * 第5引数 加算ベクトルBの値をロードするアロケート済ベクトルを指定します。 * 第6引数 入力ベクトルXの先頭を指すポインタ変数 * 第7引数 結果ベクトルYの先頭を指すポインタ変数 * 第8引数 加算ベクトルBの先頭を指すポインタ変数 * 第9引数 行列mAの先頭を指すポインタ変数 ここで、ポインタ変数は、メモリアドレスを指している変数であれば、ポインタ変数に限らずExternal宣言された大域変数でも、ローカルなbyName引数でもかまいません。 ただし、その変数がアドレスを保持していることはプログラマが担保しなければなりません。 DNN向け演算子 ------------- 本節ではDNN向けの機能を提供するドット演算子を説明します。 すべて固定小数点数を取り扱います。 なお、本節の演算子はターゲットベクタを作業領域として使うため、alloc_vector()によりアロケートしたベクタを指定しなければなりません。 **DNN_poolingLayer(引数は以下参照)** プーリングレイヤ1チャネル分を処理します。 以下で操作対象となるベクトルは、alloc_vectorコンパイラ・ディレクティブによりアロケート済でなければなりません。 入力データはポインタ変数の保持するアドレスから内部でロードされます。 また、出力データも「副作用として」ポインタ変数の指す先に内部でストアされるので、明示的に操作対象のベクトルを他に代入する必要はありません。 演算型はF16Qq固定小数点型です。qは指定する必要はありません。 * 第1引数 カーネルサイズ値を指定します。パラメータまたは即値で2/3/5/7のいずれかを指定しなければなりません。 * 第2引数 ストライド値を指定します。パラメータまたは即値で1/2のいずれかを指定しなければなりません。 * 第3引数 入力チャネルの横要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第4引数 入力チャネルの縦要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第5引数 出力チャネルの横要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第6引数 出力チャネルの縦要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第7引数 入力チャネルをロードする作業用のアロケート済ベクトルを指定します。 * 第8引数 入力チャネルの先頭を指すポインタ変数 * 第9引数 出力先チャネルの先頭を指すポインタ変数 ここで、ポインタ変数は、メモリアドレスを指している変数であれば、ポインタ変数に限らずExternal宣言された大域変数でも、ローカルなbyName引数でもかまいません。 ただし、その変数がアドレスを保持していることはプログラマが担保しなければなりません。 なお、カーネルサイズ2、ストライド2を指定した場合は自動的に枠外なしの形式となります。 **DNN_convolutionLayer(引数は以下参照)** コンボリューションレイヤ入力1チャネル分を処理します。 入力データの外側に(カーネルサイズ-1)/2だけのパディング領域を想定する形です。 コンボリューションレイヤの出力1チャネルは全入力チャネルを積算する必要があるので出力1チャネル毎にこの処理を入力チャネルの数だけ繰り返す必要があります。 そしてその繰り返しを出力チャネルの数だけさらに繰り返します。 以下で操作対象となるベクトルは、alloc_vectorコンパイラ・ディレクティブによりアロケート済でなければなりません。 入力データはポインタ変数の保持するアドレスから内部でロードされます。 また、出力データも「副作用として」ポインタ変数の指す先に内部でストアされるので、明示的に操作対象のベクトルを他に代入する必要はありません。 演算型はF16Qq固定小数点型で、現状qは12でなければなりません。 * 第1引数 カーネルサイズ値を指定します。パラメータまたは即値で3/5のいずれかを指定しなければなりません。 * 第2引数 ストライド値を指定します。パラメータまたは即値で1/2のいずれかを指定しなければなりません。 * 第3引数 入力チャネルの横要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第4引数 入力チャネルの縦要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第5引数 出力チャネルの横要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第6引数 出力チャネルの縦要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第7引数 入力チャネルをロードする作業用のアロケート済ベクトルを指定します。 * 第8引数 入力チャネルの先頭を指すポインタ変数 * 第9引数 係数行列の先頭を指すポインタ変数 * 第10引数 バイアス値または前回結果アドレスの先頭を指すポインタ変数 * 第11引数 出力先チャネルの先頭を指すポインタ変数 * 第12引数 最初の入力チャネルの場合0、途中の入力チャネルの場合1、最後の入力チャネルの場合2をスカラー変数で与えます。 * 第13引数 F16Qqのq値を与えますが、現状は12でなければなりません。パラメータまたは即値で与えます。 ここで、ポインタ変数は、メモリアドレスを指している変数であれば、ポインタ変数に限らずExternal宣言された大域変数でも、ローカルなbyName引数でもかまいません。 ただし、その変数がアドレスを保持していることはプログラマが担保しなければなりません。 **DNN_convolutionLayerNPN(引数は以下参照)** コンボリューションレイヤ入力1チャネル分を処理します。 入力データの外側にパディング領域を想定せず、ストライド1、処理後のサイズが一辺カーネルサイズ-1だけ縮小する形です。 コンボリューションレイヤの出力1チャネルは全入力チャネルを積算する必要があるので出力1チャネル毎にこの処理を入力チャネルの数だけ繰り返す必要があります。 そしてその繰り返しを出力チャネルの数だけさらに繰り返します。 以下で操作対象となるベクトルは、alloc_vectorコンパイラ・ディレクティブによりアロケート済でなければなりません。 入力データはポインタ変数の保持するアドレスから内部でロードされます。 また、出力データも「副作用として」ポインタ変数の指す先に内部でストアされるので、明示的に操作対象のベクトルを他に代入する必要はありません。 演算型はF16Qq固定小数点型で、現状qは12でなければなりません。 * 第1引数 カーネルサイズ値を指定します。パラメータまたは即値で5を指定しなければなりません。 * 第2引数 ストライド値を指定します。パラメータまたは即値で1を指定しなければなりません。 * 第3引数 入力チャネルの横要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第4引数 入力チャネルの縦要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第5引数 出力チャネルの横要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第6引数 出力チャネルの縦要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第7引数 入力チャネルをロードする作業用のアロケート済ベクトルを指定します。 * 第8引数 入力チャネルの先頭を指すポインタ変数 * 第9引数 係数行列の先頭を指すポインタ変数 * 第10引数 バイアス値または前回結果アドレスの先頭を指すポインタ変数 * 第11引数 出力先チャネルの先頭を指すポインタ変数 * 第12引数 最初の入力チャネルの場合0、途中の入力チャネルの場合1、最後の入力チャネルの場合2をスカラー変数で与えます。 * 第13引数 F16Qqのq値を与えますが、現状は12でなければなりません。パラメータまたは即値で与えます。 ここで、ポインタ変数は、メモリアドレスを指している変数であれば、ポインタ変数に限らずExternal宣言された大域変数でも、ローカルなbyName引数でもかまいません。 ただし、その変数がアドレスを保持していることはプログラマが担保しなければなりません。 **DNN_convolutionLayerNP1(引数は以下参照)** コンボリューションレイヤ入力1チャネル分を処理します。 入力データの外側にパディング領域を想定せず、ストライド1、処理後のサイズが一辺カーネルサイズ-1だけ縮小する形です。 入力チャネルが1のときに特化し、入力したものをコンボリューション処理し、即座に出力します。 これを出力チャネルの数だけ繰り返します。 以下で操作対象となるベクトルは、alloc_vectorコンパイラ・ディレクティブによりアロケート済でなければなりません。 入力データはポインタ変数の保持するアドレスから内部でロードされます。 また、出力データも「副作用として」ポインタ変数の指す先に内部でストアされるので、明示的に操作対象のベクトルを他に代入する必要はありません。 演算型はF16Qq固定小数点型で、現状qは12でなければなりません。 * 第1引数 カーネルサイズ値を指定します。パラメータまたは即値で5を指定しなければなりません。 * 第2引数 ストライド値を指定します。パラメータまたは即値で1を指定しなければなりません。 * 第3引数 入力チャネルの横要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第4引数 入力チャネルの縦要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第5引数 出力チャネルの横要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第6引数 出力チャネルの縦要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第7引数 入力チャネルをロードする作業用のアロケート済ベクトルを指定します。 * 第8引数 入力チャネルの先頭を指すポインタ変数 * 第9引数 係数行列の先頭を指すポインタ変数 * 第10引数 バイアス値または前回結果アドレスの先頭を指すポインタ変数 * 第11引数 出力先チャネルの先頭を指すポインタ変数 * 第12引数 最初の入力チャネルの場合0、途中の入力チャネルの場合1、最後の入力チャネルの場合2をスカラー変数で与えます。 * 第13引数 F16Qqのq値を与えますが、現状は12でなければなりません。パラメータまたは即値で与えます。 ここで、ポインタ変数は、メモリアドレスを指している変数であれば、ポインタ変数に限らずExternal宣言された大域変数でも、ローカルなbyName引数でもかまいません。 ただし、その変数がアドレスを保持していることはプログラマが担保しなければなりません。 **DNN_localContrastNormalizationLayer(引数は以下参照)** 局所正規化レイヤを処理します。複数のチャネルを一度に処理できます。 以下で操作対象となるベクトルは、alloc_vectorコンパイラ・ディレクティブによりアロケート済でなければなりません。 入力データはポインタ変数の保持するアドレスから内部でロードされます。 また、出力データも「副作用として」ポインタ変数の指す先に内部でストアされるので、明示的に操作対象のベクトルを他に代入する必要はありません。 演算型はF16Qq固定小数点型で、現状qは12でなければなりません。 * 第1引数 カーネルサイズ値を指定します。パラメータまたは即値で5を指定しなければなりません。 * 第2引数 入力チャネルの横要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第3引数 入力チャネルの縦要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第4引数 出力チャネルの横要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第5引数 出力チャネルの縦要素数を指定します。パラメータまたは即値で指定しなければなりません。 * 第6引数 入力チャネルをロードする作業用のアロケート済ベクトルを指定します。 * 第7引数 積算用の1つめのアロケート済ベクトルを指定します。 * 第8引数 積算用の2つめのアロケート済ベクトルを指定します。 * 第9引数 入力チャネルの先頭を指すポインタ変数 * 第10引数 出力先チャネルの先頭を指すポインタ変数 * 第11引数 入力チャネル数をパラメータまたは即値で与えます。 * 第12引数 F16Qqのq値を与えますが、現状は12でなければなりません。パラメータまたは即値で与えます。 ここで、ポインタ変数は、メモリアドレスを指している変数であれば、ポインタ変数に限らずExternal宣言された大域変数でも、ローカルなbyName引数でもかまいません。 ただし、その変数がアドレスを保持していることはプログラマが担保しなければなりません。 **DNN_relu(引数は以下参照)** RELU活性化関数を処理します。 複数のチャネル/ユニットを一度に処理できますが処理単位は4x4要素を1処理単位としているので指定の際は注意する必要があります。 以下で操作対象となるベクトルは、alloc_vectorコンパイラ・ディレクティブによりアロケート済でなければなりません。 入力データはポインタ変数の保持するアドレスから内部でロードされ、処理された後同じアドレスに書き戻されます。 明示的に操作対象のベクトルを他に代入する必要はありません。 演算型はF16Qq固定小数点型で、現状qは12でなければなりません。 * 第1引数 処理対象チャネルの先頭を指すポインタ変数 * 第2引数 入力チャネルをロードする作業用のアロケート済ベクトルを指定します。 * 第3引数 処理単位数を指定します。パラメータまたは即値で指定しなければなりません。 * 第4引数 F16Qqのq値を与えますが、現状は12でなければなりません。パラメータまたは即値で与えます。 ここで、ポインタ変数は、メモリアドレスを指している変数であれば、ポインタ変数に限らずExternal宣言された大域変数でも、ローカルなbyName引数でもかまいません。 ただし、その変数がアドレスを保持していることはプログラマが担保しなければなりません。 **DNN_softmaxN(引数は以下参照)** softmax活性化関数を処理します。 入力はF16Q12固定小数点型です。 出力はF32Q16型で返ります。 * 第1引数 入力要素の先頭を指すポインタ変数 * 第2引数 出力要素の先頭を指すポインタ変数 * 第3引数 処理要素数。 * 第4引数 F16Qqのq値を与えますが、現状は12でなければなりません。パラメータまたは即値で与えます。 ここで、ポインタ変数は、メモリアドレスを指している変数であれば、ポインタ変数に限らずExternal宣言された大域変数でも、ローカルなbyName引数でもかまいません。 ただし、その変数がアドレスを保持していることはプログラマが担保しなければなりません。 **DNN_softmax(引数は以下参照)** softmax活性化関数を処理します。 入力はF16Q8固定小数点型です。ただし、引数Q値は12としなければなりません。 出力はF32Q16型で返ります。 * 第1引数 入力要素の先頭を指すポインタ変数 * 第2引数 出力要素の先頭を指すポインタ変数 * 第3引数 処理要素数。 * 第4引数 F16Qqのq値を与えますが、現状は12でなければなりません。パラメータまたは即値で与えます。 ここで、ポインタ変数は、メモリアドレスを指している変数であれば、ポインタ変数に限らずExternal宣言された大域変数でも、ローカルなbyName引数でもかまいません。 ただし、その変数がアドレスを保持していることはプログラマが担保しなければなりません。 **DNN_conv32to16(引数は以下参照)** F32Qn型からF16Qm型へのフォーマット変換を処理します。 以下で操作対象となるベクトルは、alloc_vectorコンパイラ・ディレクティブによりアロケート済でなければなりません。 複数のチャネル/ユニットを一度に処理できますが処理単位は4x4要素を1処理単位としているので指定の際は注意する必要があります。 * 第1引数 入力ベクトルの先頭を指すポインタ変数 * 第2引数 出力ベクトルの先頭を指すポインタ変数 * 第3引数 入力チャネルをロードする作業用のアロケート済ベクトルを指定します。 * 第4引数 処理単位数。4x4=16要素を1単位として指定します。パラメータまたは即値で指定しなければなりません。 * 第5引数 F32Qqのq値を与えます。パラメータまたは即値で与えます。 * 第6引数 F16Qqのq値を与えます。パラメータまたは即値で与えます。 ここで、ポインタ変数は、メモリアドレスを指している変数であれば、ポインタ変数に限らずExternal宣言された大域変数でも、ローカルなbyName引数でもかまいません。 ただし、その変数がアドレスを保持していることはプログラマが担保しなければなりません。 Q8LP形式量子化数行列積演算子 ---------------------------- 本節ではQ8LP形式の量子化数に対する計算機能を提供するドット演算子を説明します。 なお、本節の演算子はターゲットベクタを作業領域として使うため、alloc_vector()によりアロケートしたベクタを指定しなければなりません。 **MMLPmAmB(引数は以下参照)** M行K列の行列mAとK行N列の行列mBを乗じた結果のM行N列の行列を求めます。 行列の要素は入出力ともQ8LP形式の量子化数です。 入力行列、結果行列ともメモリ上に格納できる領域を確保しておく必要があります。 入力係数等の初期化を含む領域確保のためにはVFileQ8LP初期化関数を用いることができます。 確保の例を下に示します。 .. code-block:: none global lhsArray : pointer = vFileQ8LP["tA_16.flt", "tA_1", "Q8LP", "0.00392157", "0"], rhsArray : pointer = vFileQ8LP["tB_16.flt", "tB_1", "Q8LP", "0.00392157", "0"], resultArray : u8[M_SIZE, N_SIZE] = 0, result : pointer, ~ result = `resultArray; 各行列に関するパラメータはi32型の8要素ベクトルとして与えます、また、その直後にLHSスライスのワーク領域を確保しなければなりません。 パラメータ定義の例を下に示します。 .. code-block:: none paramList : i32[8] = vPattern[0, 1, 0, 1, 0, 1, 10, 0], lhsSlice : i32[M_SIZE] = 0, #MUST BE immediate after paramList!!! param : pointer, ~ param = `paramList; パラメータは以下のとおりです。 * 第1パラメータ 行列mAのオフセット値 * 第2パラメータ 行列mAのスケーリング値分子(整数) * 第3パラメータ 行列mBのオフセット値 * 第4パラメータ 行列mBのスケーリング値分子(整数) * 第5パラメータ 結果行列のオフセット値 * 第6パラメータ 結果行列のスケーリング値分子(整数) * 第7パラメータ 結果行列のシフト値 * 第8パラメータ 0を与えること。内部で使用される。 以下で操作対象となるベクトルは、alloc_vectorコンパイラ・ディレクティブによりアロケート済でなければなりません。 入力データはポインタ変数の保持するアドレスから内部でロードされます。 また、出力データも「副作用として」ポインタ変数の指す先に内部でストアされるので、明示的に操作対象のベクトルを他に代入する必要はありません。 * 第1引数 パラメータを格納したベクトルを指すポインタを指定します。 * 第2引数 mA(LHS)を格納したベクトルを指すポインタを指定します。 * 第3引数 mB(RHS)を格納したベクトルを指すポインタを指定します。 * 第4引数 resultの格納先のベクトルを指すポインタを指定します。 * 第5引数 mA(LHS)の値をロードするアロケート済ベクトル0を指定します。 * 第6引数 mB(RHS)の値をロードするアロケート済ベクトル1を指定します。 * 第7引数 作業用アロケート済ベクトル1を指定します。 * 第8引数 作業用アロケート済ベクトル2を指定します。 * 第9引数 行列のMサイズを整数またはパラメータで指定します。 * 第10引数 行列のKサイズを整数またはパラメータで指定します。 * 第11引数 行列のNサイズを整数またはパラメータで指定します。 * 第12引数 行列のMajor型、計算方法オプションなどを決定する値を整数またはパラメータで指定します。 行列のMajor型、計算方法オプションは、32ビット整数値の各ビットに意味が割り当てられています。 * ビット0 1であるとmA(LHS)は Column Majorメモリ配置、0であるとRow Majorとなります。 * ビット1 1であるとmB(RHS)は Column Majorメモリ配置、0であるとRow Majorとなります。 * ビット2 1であるとresultは Column Majorメモリ配置、0であるとRow Majorとなります。 * ビット3 1であるとオフセット値を無視します。0であるとオフセット値を有効として計算します。 ここで、ポインタ変数は、メモリアドレスを指している変数であれば、ポインタ変数に限らずExternal宣言された大域変数でも、ローカルなbyName引数でもかまいません。 ただし、その変数がアドレスを保持していることはプログラマが担保しなければなりません。 また、内部で各方向は32の倍数毎に処理されるので、データは32の倍数となるようにあらかじめ0フィル調整が必要です。 これらの調整を行うツールが準備されているので、vFileQ8LPで読み込む前に処理を行ってください。 **MMLP_32x4Kernel(引数は以下参照)** M方向32要素、N方向4要素、Kについては最大8160要素までのカーネル計算を行う計算部品です。 入力要素は入Q8LP形式、カーネル演算結果は、32x4要素=128要素のI32型ベクタです。 複数コアで大きな配列をK方向分割して並列処理するための単位部品の一つです。 * 第1引数 mA(LHS)を格納したベクトルを指すポインタを指定します。 * 第2引数 mB(RHS)を格納したベクトルを指すポインタを指定します。 * 第3引数 結果格納用のアロケート済ベクトルを指定します。 * 第4引数 mA(LHS)の値をロードするアロケート済ベクトルを指定します。 * 第5引数 mB(RHS)の値をロードするアロケート済ベクトルを指定します。 * 第6引数 mA(LHS)で次のKをアクセスするためのストライド値を指定します。 * 第7引数 mB(RHS)で次のNをアクセスするためのストライド値を指定します。 * 第8引数 depthに対するオフセット値を指定します。コア分割しない場合は0を指定します。 * 第9引数 処理すべきdepth(K)を指定します。 * 第10引数 処理対象のM方向位置を保持する変数を指定します。(M方向位置は32の倍数でなければなりません。) * 第11引数 処理対象のN方向位置を保持する変数を指定します。(N方向位置は、N方向のストライドを乗じておかねばなりません。) ここで、ポインタ変数は、メモリアドレスを指している変数であれば、ポインタ変数に限らずExternal宣言された大域変数でも、ローカルなbyName引数でもかまいません。 ただし、その変数がアドレスを保持していることはプログラマが担保しなければなりません。 また、内部で各方向は32の倍数毎に処理されるので、データは32の倍数となるようにあらかじめ0フィル調整が必要です。 これらの調整を行うツールが準備されているので、vFileQ8LPで読み込む前に処理を行ってください。