Top: 4 lines / syttrea
Par: 6 lines
LM上に Float \(256 \times 16\) 行列 \(A\) と、長さ \(16\) のベクトル \(B\) があります。行列 \(C[i][j] = A[i][j] + B[j]\) を求め、LM 上に出力してください。
おさらいすると、 A[0][0] + B[0]; A[0][1] + B[1]; ... のような計算を行う問題です。
これまでの問題は入力サイズがすべて同じ演算でしたが、今回は行列とベクトルの加算です。
行列 \(A\) の 1 次元目のレイアウト (8_L2B:1, 4:2, 8_L1B:1) は、とりあえず L2B と L1B を無視すると、各 PE の LM0 に要素数 4 で、(4:2) の形で配置されていると考えることができます。
これは、2 長語(=4単語)ごとに、4 個の要素が配置されていることを意味します。
レイアウト表記は長語(64bit)単位、vsm の LM は単語(32bit)単位のアドレッシングであることに注意して考えると、 PE 単位の小行列の A[0][0] は $m0 に、A[1][0] は $m4 に配置されています。
\(B\) も同様に、b[0] は $m16 に、b[1] は $m17 に配置されています。
\(A\) も \(B\) も \(j\) 軸が 4_PE に分散されて配置されていますが、今回は \(j\) をまたいで加算する必要はないので、無視できます。
\(B\) は \(i\) 軸に対して分散して加算しないといけませんが、B@[MAB,L1B,L2B]) というレイアウトのとおり、それぞれの MAB, L1B, L2B で同じ内容が放送 (Broadcast)、つまり全ての MAB で同じ内容になっているので、MAB より上に放送する必要はありません。
なので実質的に、1 PE だけで考えると 行列 \(A\) はサイズ \(4\times4\) で ((4:2), (2:1, 2_W:1)) 、ベクトル \(b\) は長さ \(4\) で (2:1, 2_W:1) の形で格納されていて、行列 \(A\) の各行にベクトル \(b\) を加算すれば良いことが分かります。
PE 単位で見ると、行列 A の 0 列目 は $m[0,1,2,3]、1 列目 は $m[4,5,6,7] に、ベクトル \(b\) は $m[16,17,18,19] に格納されているので、fvadd 命令を使って加算していくと Accept です。
fvadd $m0v $s0v $n0v のように書くと、入力が両方 LM0 にもかかわらずアドレスが違うためにエラーになります。なので $m16v を一旦別のレジスタに退避させると良いでしょう。
$lm[0:16], (256,16)/((8_L2B:1, 4:2, 8_L1B:1), (2:1, 4_PE:1, 2_W:1); B@[MAB])
$lm[16:20], (16)/((2:1, 4_PE:1, 2_W:1); B@[MAB,L1B,L2B])
$ln[0:16], (256,16)/((8_L2B:1, 4:2, 8_L1B:1), (2:1, 4_PE:1, 2_W:1))
/ \(0.00001\) 以下の絶対誤差が許容されます