雑多な趣味の記録帳

tom01h.exblog.jp

タグ:tiny-dnn ( 44 ) タグの人気記事

tiny-dnn アクセラレータを Ultra96 で動かしたい4

キャッシュ付き DMA をいったんあきらめて、キャッシュなしで DMA 転送をしてみました。
こんな感じ で、転送と演算を並列動作しているプログラムは認識率は 97.41% で安定。
並列化していないプログラムは不安定。

プログラムを見比べて思いつく疑惑。

DMA の終了判定を間違っているっぽい。
DMA の転送が終わっていないのに、DMA リセットをかけているのか、IP 側の受け取り状態を解除しているのが原因じゃないかと思う。

よく見る終了判定
while ((dma_addr[0x04/4] & 0x1000)!=0x1000); // Wait for the tx to finish
最初のうちに起きていたハングアップを避けるために今まで使っていた終了判定
while ((dma_addr[0x04/4] & 0x3)==0); // Wait for the tx to finish

よく見る終了判定に変更したら、並列化していないプログラムも 97.41% で安定しました。

シミュレーション結果と一致しないのは、コンパイラのバージョン違いってことにしておきます。

DMA でキャッシュを使う設定(AxCACHE=0xf,AxPROT=0x2,FF41A040=0x3)にしたら…
やはり認識率が一定しません。

この設定で udmabuf を O_SYNC 付きで開くと期待通りの動きです。
やっぱりキャッシュ付き転送になっていないのかな?

残念ながら時間切れ。来週は DMA 単体でテストするかな…

[PR]
by tom01h | 2018-12-13 23:59 | Trackback | Comments(0)

tiny-dnn アクセラレータを Ultra96 で動かしたい3

tiny-dnn アクセラレータがいまだ Ultra96 上では安定して動きません。
実行時間的にはだいたい期待通りなんだけど、実行結果(認識率)に再現性がないです。
いやなことに、正解だと思っている認識率 96.95% よりも高いことが多いのですが…

Interface の 2019年1月号 の読み返したけど、やり忘れていることはなさそう。
udmabuf の説明 を読んでみると、デバイスツリーに登録して dma-coherent を設定しないといけない気もしますが、試してみたけど変わりません。
DMA の設定の相性問題 で Petalinux ツールがうまく動かないのも疑ってみたけど違うようです。
しかも、いつからか Wifi が使えなくなっています。
DMA のデバイスツリーから dma-coherent を外すと Wifi 復活しました。→ 単に dd の書き損じの可能性もあります。

しかし、Ultra96 は何をやるにも時間がかかります。
だいたいの原因は、ルートファイルシステムが 1.5GB もある事かと…
しかも、Petalinux ツールはルートファイルシステムのコピーを何種類も作って、あっちで作ってこっちにコピーとかもしています。
あと、dd もすごく時間かかるし、たまにうまく書けていないこともある感じです。
ちなみに、VirtualBox が PC 内蔵の SD カードリーダを認識してくれないので、古い USB カードリーダを持ち出しています。
それが原因で dd が遅いのもあると思います。
また、形が悪くて隣りのポートもつぶしたりするので USB カードリーダを買ったのですがまだ届きません。
ついでに、机のわきに固定する形の USB ハブ を買いました。
f0054075_20030769.jpg
悪いのは DMA の使い方じゃないのかなぁ?
CORA はちゃんと動いているみたいだけど…

[PR]
by tom01h | 2018-12-11 23:46 | Trackback | Comments(0)

tiny-dnn アクセラレータを Ultra96 で動かしたい2

前回は reserved-memory で Linuz が使わないようにした領域を DMA バッファに使おうと思って上手く出来ませんでした。
udmabuf の使い方もわかったところで、再度 Ultra96 上での実行に挑戦してみます。

結論。速くなったけど、結果に再現性がない。まだ上手く行っていないところあるのかなぁ?
ちなみに認識率はちゃんと動いていると思われる時よりも高くなります。
[覚悟を決めて Verilator で 20000 サンプルの学習をしてみました。96.95% でした。ちなみに 10分ちょっとかかりました。]
f0054075_20231846.png
まだなんか怪しいけど、github に置きました。グラフの上の方を見たければそちらをどうぞ。

Ultra96 への移植では Interface 2019年1月号 がとっても参考になりました。
もう一度読み返して、怪しい動作の解析をしたいと思います。

そうは言っても、記事で気になるところを…
汎用 GEMM アクセラレータを作るのが目的ならこの記事で良いのかなと思います。
が、畳み込みを高速化したいのなら、CPU で im2col をやったらダメかと思います。
転送速度がネックだとわかっていつつ、ほぼ 9倍(3x3conv)にデータを増やしてから転送するなんて…
いや、他がすごく良かったのでここが気になるって話です。
あと、HLS 使ったら仕方ないのか?って気もしますが、ユーザメモリから DMA バッファへの同じデータの転送を何度もやらない工夫をしているみたいですが、何度も同じデータを DMA 転送しているのも気になります。
さらに、IP の中もダブルバッファ化するとか HLS でも出来るのですかね?
出来ないなら、HLS もまだまだって気もします。

[PR]
by tom01h | 2018-12-09 21:18 | Trackback | Comments(0)

tiny-dnn アクセラレータのバグ取りの日

tiny-dnn アクセラレータの動きが不審なので、落ち着いて解析してみます。

まずは認識率に再現性がなくなったところから。
tiny-dnn は学習過程でランダムを使っていないみたいで、毎回同じ認識率を出していました。
ところが最近、いつからか分からないけど、認識率に再現性がなくなっていました。
原因はおそらく DMA バッファ(アクセラレータ→ユーザ空間)の上書きです。
DMA バッファからユーザ空間への転送を演算と並列処理できるようにしたことで、演算がとっても短いときにデータの転送が終わる前に次のデータで上書きされていたのかと思います。
DMA バッファをダブルバッファにしたことで、認識率が 96.95% で落ち着くようになりました。
97% 割ってしまったのは悔しいですが…
というか、再現しないときの方が認識率が高いって…

次は傾きの逆伝搬がとっても遅い原因を探ります。
CPU で流している限りは順伝搬と同じくらいの計算量に見えています。
だから、アクセラレータを使っても同じくらいの時間で終わるはずと思ったのですが…
このアクセラレータは出力の深さだけ並列実行できるのですが、逆伝搬では入出力が逆転して入力の深さだけ並列実行するようになります。
そして、入力層の深さは 1ですから、入力の傾きを求める計算では並列実行できません。
バグで遅いのかと思っていたけど違って、このアクセラレータの弱点っぽいです。
がしかし、入力の傾きって必要ないですよね?
少しずるいけど、取っちゃいました。
[Corei5 の値が間違っていたので差し替えました。あと、目標が高すぎるとくじけるので、Celeron 追加しました。]
f0054075_15482969.png
あともう一個。
こっちはまだ直してないけど、乗算器のステージングが1ステージ少なかった。
BRAM から読んだデータを、そのサイクルで乗算器が使っている模様…

[PR]
by tom01h | 2018-12-08 22:40 | Trackback | Comments(0)

tiny-dnn アクセラレータで udmabuf を使う

tiny-dnn アクセラレータの動きが怪しいので udmabuf を使ってみたいと思います。

その前に、バイアスの傾き計算を少し変更しました。
出力の傾きを DMA バッファにコピーするときに、同時にバイアスの傾きを計算することでデータアクセス回数を削減する狙いです。
計算量は少ないので CPU で計算させています。
速くはなりましたが、期待していたほどの効果はありませんでした。
逆伝搬はどこに時間がかかっているのか解析が必要みたいです。

で、udmabuf の話に戻ります。
ドライバ開発の手順はやはり、ここ を参考に進めます。
udmabuf のページのサンプルコードの文字列がなぜか unsigend char* でコンパイルできずにはまりましたが、それ以外は2つのリンク先の通りにやると出来ました。
具体的なことは明日 github に書けることを期待して…

ついでに非キャッシュで DMA をするとどうなるか試してみました。
パイプライン化の効果があったか、パラメタの傾き計算以外はあまり変わりません。
(昨日の絵でオレンジと青が遅くなろうが変わらないってこと。)
パラメタの傾き計算では、すでにテータ転送がネックになるのでしょうか?

あと、遅いのはパラメタの傾き計算じゃなくて、傾きの逆伝搬でした。
条件の違うデータがいろいろと混ざっていますが…
f0054075_00292352.png
続きは明日やろう…

[PR]
by tom01h | 2018-12-07 23:59 | Trackback | Comments(0)

tiny-dnn アクセラレータをパイプライン処理する1

先日は tiny-dnn アクセラレータの処理時間を (順方向だけだが) 大雑把に見積もってみました。
CORA では鉛筆なめた数字に結構近い結果が出ているみたいです。

ついでなので、データ転送と演算の並列処理化を進めたいと思います。
第1段ではユーザメモリと DMA バッファ間の転送とそれ以外を並列処理します。
こんな感じ。
f0054075_20013073.png
大雑把な見積もりでは 7.09秒かかる処理が、CORA では実際には 7.8秒かかっています。

ちなみにこの変更で認識率が上がったのですが、その値が Ultra96 での認識率と一致しています(誤報?)。
Ultra96 はまだちゃんと動いていないのでこっちがおかしいのかと思っていたのですが、おかしいのは今までの CORA の環境なんですかね?

もう少しいじっていたらさらに認識率が上がりました… わけわかんない…
いや、再現性が無いぞ。

[PR]
by tom01h | 2018-12-06 23:14 | Trackback | Comments(0)

tiny-dnn アクセラレータの計算時間を見積もってみた

Ultra96 上で tiny-dnn アクセラレータがうまく動かないので、気晴らしに理屈をこねてみることにします。

Ultra96 上ではキャッシュを使っての DMA 転送になっていないようで、CORA で実行するよりも遅いです。
順方向の畳み込みの総実行時間が、CORA では 8.4秒に対して Ultra96 では 12.6秒くらいかかっています。
じゃあ、理想的にはどうなのよ?

まず計算時間から。
出力チャンネル方向は並列実行するので、カーネルの(幅×高さ×深さ)×出力の(幅×高さ) が1層分の計算時間(サイクル)です。
下のような構造なので、
f0054075_20263635.png
下のような計算で、1画像の計算量は 24256 サイクルかかります。
f0054075_20273425.png
20000 画像の学習を 100MHz で実行すると約 4.85秒。

データ転送量はフィルタが、カーネルの(幅×高さ×深さ)×出力の深さをミニバッチに付き1回転送。
入力データと出力データは、それぞれの幅×高さ×深さを各データごとに転送する。
DMA バッファから tiny-dnn アクセラレータへの転送は1サイクルあたり 1データです。
[追記 出力データは core から出力バッファへの転送にも同じだけ時間がかかっていることを思い出しました。]
ミニバッチが 16なので、1画像ごとの転送量は下のような計算で 6713.375 [11203.375] サイクルかかります。
20000 画像の学習を 100MHz で実行すると約 1.34[2.24]秒。
f0054075_19202339.png
合わせて約 6.19[7.09]秒。
実際はこれに加えてユーザメモリから DMA バッファへの転送時間も必要ですが、見積もり難しいので数字を出すのは諦めます。
これらすべてに実際にかかっている時間が、CORA では 8.4秒に対して Ultra96 では 12.6秒くらいです。
いまはまだ、一切パイプライン処理が出来ていないので、想像以上に良い線行っている気もします。

[PR]
by tom01h | 2018-12-04 22:17 | Trackback | Comments(0)

tiny-dnn アクセラレータを Ultra96 で動かしたい2

tiny-dnn アクセラレータを Ultra96 で動かそうと思って苦労しています。

Interface 1月号の3部4章の ”高速化その3” には 3つの変更が必要と書いてあります。
Zynq7 でも同じような機能を使っているけど 0.5個だけしか必要ありませんでした。
これやらなくても、計算結果は違えどハングアップはないよなぁ… と思いつつも残りの 2.5個を対応します。
やっぱりハングアップは直りません。

結局 printf デバッグをして、プログラムにバグを仕込んだことを発見。
Ultra96 になってから scp が出来るようになったので、printf デバッグがはかどります。
ハングアップの原因は、64bit になったからかな?データ型変換で WARNING が出ていたので変更したのですが、そこにバグを入れ込んでいました。

直したら動いたんだけど… Zynq7 より遅い。
O_SYNC 付けても実行時間変わらないし、リザーブメモリの扱いが違うのかな?

reusable 付ければよいのかな?
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
dma_reserved: dma@0x7ff00000 {
reusable;
reg = <0x0 0x7ff00000 0x0 0x00100000>;
};
};
変わりません…
だいたいこんな感じです。アクセラレータと関係ないところは結構速くなっていていい感じです。
f0054075_22502236.png
Interface の真似をして、udmabuf 使ってみますかね?
いずれは、SMMU を使いたいんだけど…

理由は分からないけど、昨日と同じように SDK でクロスコンパイルしてみたら出来ました。

[PR]
by tom01h | 2018-12-03 23:39 | Trackback | Comments(0)

tiny-dnn アクセラレータを Ultra96 で動かしたい1

tiny-dnn アクセラレータを Ultra96 で動かしたいのですが…

まず最初に、SDK のコンパイラではうまくクロスコンパイルできないので、apt を使って Ubuntu 用のクロスコンパイラをインストールしました。
その結果、ライブラリのバージョンの問題かな?もう一度 -static オプションを復活する必要がありました。
[追記 理由は分からないけど、翌日同じように SDK でクロスコンパイルしてみたら出来ました。]

これで実行は出来たのですがハングアップします。
で、uioを確認すると。
f0054075_19144294.png
ここ直したけどまだ動きません。

なんの脈略もないけど Ultra96 ボードのアップの写真を貼っておきます。
よく見ると、部品の載っていないパタンが結構たくさんあります。
f0054075_19191788.jpg
VirtualBox が USB をマウントできなくなることがあって、何度も作業を中断させられて頭に来ます…
いろいろいじっているとマウントできるようになるのですが、何が利いているのかも良く分かりません…

[PR]
by tom01h | 2018-12-02 22:13 | Trackback | Comments(0)

Petalinux を DMA 入りの BD でコンパイルする

今までの Petalinux のコンパイルは、tiny-dnn アクセラレータと DMA の代わりに BRAM を置いて作っていました。
うまくコンパイルできない理由をちゃんと検索してみると、どうやら Petalinux ツールが バグ DMA の設定と相性が悪いようです。
ここ とか ここ に情報がありました。
結構長い事、放置されているようですね。

かなり強引な手に見えますが、1個目の方法で対策しました。
UIO デバイス名ちゃんと見えてます。
f0054075_22150767.png
ついでに無駄に大きかった DMA バッファを 1MB に縮小しました。

[追記 interface 1月号はこれ問題になっていないかと思って読み返してみたんだけど、DMA の設定で ”Enable Single AXI4 Data Interface” を選んでいるのがいけない気がしてきました。→ リンク先のページにもちゃんと書いてありました。]

[PR]
by tom01h | 2018-12-01 23:25 | Trackback | Comments(0)