2017年8月6日日曜日

TE0720 No.3 (BNN-PYNQを動かしてみる)

今度は BNN-PYNQ をTE0720で動かせるかをやってみている。
BNNはBinarized Neural Network (BNN) (2値化ニューラルネットワーク)のことで、BNN-PYNQはPYNQ-Z1ボードのシステム向けのBNNの実装だ。PYNQ-Z1に搭載されているZynqデバイスはZYNQ XC7Z020-1CLG400C、TE0720のそれはXC7Z020-1CLG484Cであり、ピン数は異なるがコアは同じXC7Z020なので動くんじゃないかと考えた。そのためには、PYNQ用のLinuxシステムをTE0720で動かす必要がある。PYNQ-Z1のprecompiled image(pynq_z1_image_2017_02_10.zip)をPYNQのGitHubからダウンロードして中を見てみた。

pynq_z1_image_2017_02_10.imgはディスクまるごとのイメージでboot用パーティションとrootfs用のパーティションが入っている。そこで、それぞれのパーティションのイメージをddコマンドで抽出した。

必要なのはrootfsの方なので、これをcpioイメージに変換しておく。

前回のブログで作成したpetalinuxのSDカードのrootfsパーティションの内容を、抽出したPYNQのrootfsに書き換え、TE0720に装着して起動してみた。

起動してコマンドプロンプト表示まで行くのだが、キー入力を受け付けない。
現状、FPGAのPL部はTE0720のsampleデザインになっており、PYNQ-Z1ボードのそれとは異なる。起動時の処理で初期化か何かでPL部にアクセスをしていた場合は当然ハングアップする可能性は考えられる。ただし、BNN-PYNQはBNNの推論部をFPGA Overlaysの機能を使ってシステム起動後にFPGAにダウンロードして動かしているはずであり、起動時のPL部にはその回路は入っていないはずである。GitHubからPYNQのプロジェクトをダウンロードし、VivadoでBlock Designを見てみた。

Arduino sheild用の回路やHDMI、GPIO等の回路が入っているようだ。これらを起動時に初期設定しているのかも知れない。そこで、rootfsの/etc/rc 関係を見てみたところ rc.local にあった。

各シェルスクリプトの内容を確認した結果、4_boot_leds.shでPL部のGPIOを介してボード上のLEDのon/offをしていることが判った。そこで、rc.localの4_boot_leds.shの呼び出し部分をコメントアウトするように変更し、再度TE0720に装着して起動してみたところ、今度はキー入力も受け付けるようになった。

イーサネットも動作しておりDHCPでIPも取得できている。

そこで、開発PCのブラウザからTE0720のJupyter notebookのポートにアクセスしてみた。

アクセスできた。
そこで、次にBNN-PYNQのGitHubのQuickStartの記載内容に従って、BNN-PYNQをインストールした。

  sudo pip3.6 install git+https://github.com/Xilinx/BNN-PYNQ.git

すると、Jupyter notebookの項目にbnnが現れた。


Cifar10.ipynbを選択して実行してみた。

が、Jupyter notebookカーネルが死んでしまった。 orz

cell単位でステップ実行してみると、最初のcellでカーネルが死んでしまっていた。
overlayでPL部にダウンロードするBNN-PYNQのBlock DesignをVivadoで見ると以下のようであった。

これを見るとデバイス外部への入出力は無いので、TE0720でも動きそうな気がするのだが・・・
そこで、スクリプトをpythonスクリプトとしてダウンロードし手動で実行してみた。


terminate called after throwing an instance of 'char const*'というメッセージが出て終了してしまっていた。念の為、最初のセルの内容だけのスクリプトを書いて実行してみた。

classifier = bnn.CnvClassifier('cifar10')でエラーになっているようだ。
そこから、/opt/python3.6/lib/python3.6/site-packages/にあるpynqディレクトリ下のスクリプトやbnnディレクトリ下のスクリプトを追ってみた。回路情報(bitファイル)の/dev/xdevcfgへの書き込みは成功しているようだが、その後のpython_hw-cnv-pynq.soというライブラリ内部で例外が発生しているようだ。ソースコードを見ると、このpython_hw-cnv-pynq.soはパラメータのダウンロードを行うライブラリのようだ。なぜここで例外になる??? うーむ……


2017年7月31日月曜日

GTX1050Ti と Tesla m2050

Deep learningの学習用にGTX1050Tiを購入した。

実はこれより前に、AmazonにTesla m2050の中古品が\3,680という破格値で出てたので購入した。見るからにゴツく、補助電源も2本必要というとっても電力を喰いそうなボードだ。パネルがついていないのでサーバーで使われていたものかも知れない。

PCにセットして動作させてみたところ問題なく動作し、NVIDIAからダウンロードしたCUDAのsampleプログラムも動作した。

…しかし残念ながらdeep learningには使えない。
NVIDIAのGPUにはCompute Capability(CC値)という性能指標のようなものがあり、このm2050は3.0だそうだが、Deep learningにはCC値が3.0以上のものでないと使えないそうだ。
https://www.tensorflow.org/install/install_sources
http://www.arcbrain.jp/support/NVIDIA/Deep_Learning/

そこで、CC値が3.0以上でDeep larningに使える安価なGPUは無いか探したところ、GTX1050Tiが使えることが判り、購入した。(GTX1050TiのCC値は6.1) この他にGTX1080Tiというのもあるが、価格が10万円近いので個人用に買うにはチョト、いや、かなり厳しい。



GTX1080Tiはm2050同様補助電源が必要だが、GTX1050Tiは補助電源不要という点もうれしいところだ。

「TensorFlowで学ぶディープラーニング入門」という書籍の「Chapter05/MNIST double layer CNN classification」を使って、CPUで演算した場合とGPUで演算した場合の性能差を見てみた。
cpuで演算するtensorflowライブラリを使用した場合は67分掛かった。
これに対してgpuで演算するtensorflowライブラリの場合は3分22秒だった。

約20倍の性能差があるということか。
ただし、使用しているCPUはAMDのAMD FX4170なのでXeon等と比べると演算性能は低い。
また、cpu演算版tensorflowライブラリはSSE等の命令を使っていないライブラリなので、それらを使うようにすれば性能は上がるかもしれない。一方GTX1050Tiの方はPCI Expressが3.0だが、使っているPCのマザーボードのPCI Expressは2.0のため2.0として動作している。PCI Express 3.0は2.0に対してスループットが2倍なので、PCI Express 3.0仕様のマザーボードにすればこちらも性能が上がる可能性がある。要するにどちらもまだ伸び代(高速化の余地)はあるということだ。




2017年7月30日日曜日

TE0720 No.2 (petalinux-image-full の build とインストール)

TE0720には出荷時設定でPetalinuxがインストールされているが、これは最小構成のものなので linux が動くということは判るがそれ以上のことはできそうにない。 GCCなどの開発ツールも入ったもっとリッチな環境にしたいし、いい機会なのでPetalinuxのビルドをやってみることにした。
基本的なビルド方法については、TrenzのWikiページを参考にした。

PetaLinux KICKstart
https://wiki.trenz-electronic.de/display/PD/PetaLinux+KICKstart#PetaLinuxKICKstart-PetalinuxProjectCreation-ShortHOWTO

Reference Design
http://www.trenz-electronic.de/fileadmin/docs/Trenz_Electronic/TE0720/Reference_Design/2016.4/test_board/te0720-test_board_noprebuilt-vivado_2016.4-build_08_20170529092723.zip

上記 Wiki にしたがってビルドしてできるPetalinuxはTE0720に入っているのと同じ最小構成のものだ。これをカスタマイズしたいが、 petalinux-config -c rootfs で1項目づつ追加する方法は面倒くさすぎてとてもじゃないがやってられない。 他になにか方法はないかと調べてみたところ、Petalinux-v2017.2-final には petalinux-image-full.bb というレシピファイルが存在することが判った。
※. petalinux-image-full.bbはインストレーションファイルのPetaLinux 2017.2 オープン コンポーネント ソース コード(petalinux-v2017.2-open_components.tar.gz)に含まれているのでpetalinux-v2017.2-final-installer.runと共にこれもインストールする必要がある。 (2018.08.19追記)

その内容を見るとgccの開発環境やX、openCV等、全部入りのレシピのようだ。

で、試行錯誤した結果、なんとかビルドすることが出来、望みのリッチな環境にすることができた。

やり方としてはちょっとダサいが、上記 Petalinux KICKstart に準じて最小構成のビルドをした後、oe-init-build-envをsourceし bitbake コマンドで rootfs のみ、即ち、 petalinux-image-full のみをビルドした。 因みに、oe-init-build-env はPetalinux インストールディレクトリ下のpetalinux-v2017.2-final/components/yocto/source/arm/layers/coreディレクトリにある。

以下、その手順

1. TE0720用最小構成のPetalinuxのビルド
 TE0720用のvivadoのhdfファイルと、device-tree、fsblが必要なので、上記 Reference Designをダウンロードし、_readme.txt に従って vivado 2016.4 でプロジェクトの生成まで実行し終了する。 petalinux-image-full.bb はpetalinux-v2016.4-finalには存在せず、petalinux-v2017.2-finalに存在するので、hdfファイルもvivado 2017.2で生成する必要がある。そのため、vivado 2016.4で生成したプロジェクトをvivado 2017.2で開き直し、そのバージョンでbitstream生成しhardwareのエクスポートをする必要がある。

次に、test_board/os ディレクトリ下に petalinux のプロジェクトを生成する。実際はプロジェクトを生成するディレクトリはどこでも良いが Reference Desginはtest_board/os 下に作成しているのでそれに準じた。


作成したTE0720ディレクトリ下にvivadoでエクスポートしたhdfファイルをコピーし、petalinux-config を実行する。



Configurationメニューが開くのでコンソール用シリアルポートやrootfs関連を設定する。

・ コンソール用シリアルポートは初期状態ではps7_uart_1になっているが、TE0720はps7_uart_0をコンソール用シリアルポートとしているのでps7_uart_0に変更する。
 トップメニューから、Subsystem AUTO Hardware Settings > Serial Settings > Primary stdin/stdout へと進み、ps7_uart_0を選択する。

・ Root filesystemの格納先をINITRAMFSからSDカードに変更する。
 トップメニューから、Image Packaging Configuration > Root filesystem type へと進み、SD cardを選択する。

・ デバイスツリー dtb イメージの格納先をSDカードに変更する。
 トップメニューから、Subsystem AUTO Hardware Settings > Advanced bootable images storage Settings > dtb image settings > image storage media へと進み、primary sdを選択する。

以上の項目を設定したらSaveしてConfiguration画面をExitする。
次に、fsbl等をTE0720用に変更したいところだが、build コマンドを実行しないと変更対象のfsblファイル群が生成されないので、ここで petalinux-build コマンドを実行する。

ビルド終了後、device-tree ファイルとfsblの変更を行う。

・Reference Designのsystem_top.dtsをsystem-user.dtsiにコピー
  test_board/os 下で、
  cp ./petalinux/project-spec/meta-user/recipes-dt/device-tree/files/system-top.dts./TE0720/project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi
  し、system_user.dtsiの1,3〜10行目を削除する。
変更前

変更後


・ fsblの変更
  Reference Designのfsbl_hooks.c、te_fsbl*.* をTE0720プロジェクトのfsblディレクトリ下にコピーする。
   test_board/os/TE0720 下で、
   cp ../../sw_lib/sw_apps/zynq_fsbl/src/fsbl_hooks.c  ./components/plnx_workspace/fsbl/src/fsbl_hooks.c
   cp ../../sw_lib/sw_apps/zynq_fsbl/src/te_fsbl*.*  ./components/plnx_workspace/fsbl/src/

  fsbl_hooks.cはFsblHookBeforeHandoff()関数からte_FsblHookBeforeHandoff()をコールするように変更されており、te_FsblHookBeforeHandoff()ではイーサネットのMACアドレスの設定やUSB-PHYのリセット等を行っている。USB-PHYのリセットはTE0720のシステムコントローラを介して行うようになっており、このシステムコントローラのI/FはI2Cで、Reference DesignではPSのIIC_1に接続されている。

上記変更後、再度 petalinux_build コマンドを実行する。
ビルドが完了したら、BOOT.BINを作成しておく。
test_boars/os/TE0720/images/linuxディレクトリに移動し、petalinux-packageコマンドでBOOT.binを生成する。

 
…と、ここまでが最小構成のPetalinux作成。ふぅ〜

2. petalinux-image-full のビルド
oe-init-build-envをsourceする。

次にbitbakeコマンドでpetalinux-image-fullをビルドする。

ここで必要なのはrootfsのみであるので -c do_image_cpioを付加する。また、これを付けないと、u-bootやfsblもビルドしにいってエラーになるので必ず付ける。

ビルドが始まった様子

ビルドが始まるとインタネット上のリポジトリからソースファイルを並列的に取得している様子で、ネットワーク負荷が重くなり、他のブラウザ等からのネットアクセスが一時的に出来なくり、暫くすると復旧するが、ビルド完了までにはかなり時間がかかる。特に上記のChecking sstate mirror object availabilityはもしかしてプログラムがハングアップしてんのか?って位に進捗が判りづらい。

ビルド中

ビルド成功


この方法の場合、イメージファイルはimage/linux/下ではなく、build/tmp/work/plnx_arm-xilinx-linux-gnueabi/petalinux-image-full/1.0-r0/deploy-petalinux-image-full-image-complete下に生成される。


これで全部入りのrootfsが出来た。 やったー \(^_^)/

SDカードに焼いて動くかどうかを見てみる。
SDカードにFAT32とext4形式の2つのパーティションを作成する。

FAT32にはimage/linuxディレクトリ下のBOOT.bin、image.ub、system.dtbをコピーする。

ext4パーティションにはrootfsをコピーするが、imageファイルがcpio形式なのでext4ディレクトリ上で以下のように展開する。

cpioファイルへのパスが長過ぎるのでシンボリックリンクを貼ってからcpioにそのファイル名を与えた。展開後は削除する。

展開できた。

syncコマンドを実行後SDカードをアンマウントし、TE0720に装着して起動すると無事Linuxが起動し、ログインプロンプトが表示された。

が、ここで問題発生。rootのパスワードが不明。どうやら root ではないようだ。
そこで、SDカードを開発PCにマウントしなおして、etc/passwdとetc/shadowをsudo vi で開いてrootのパスワードの部分を消去した。

passwdファイルのroot:x:0:0:・・・のx(shadowフアイルは*)を削除


これで、パスワード無しでログインできる。
ログイン後はパスワードを設定しておく。

/bin, /sbin, /usr/bin 等の各ディレクトリ下を見てみた。

/bin


/sbin


/usr/bin


/usr/sbin


/usr/libexec


/usr/include


gcc, pythonのバージョン


X WindowのウィンドウマネージャはMatchboxが入っている。


これだけ入っていれば色々遊べるだろう。


2017年6月25日日曜日

TE0720

ひっさびさにFPGAボードを購入した。

購入したのはTrenz ElectronicのTE0720-03-1CFで、ベースボードとGigaZee TRENZ付属品セットも一緒に購入した。


搭載されているFPGAはZYNQ XC7Z020-1CLG484C。
このサイズにZYNQ XC7Z020-1CLG484Cの他に1.5A DC/DC電源、32MbyteのSPI Flash memory、 4GbyteのeMMC、1GbyteのDDR3-SDRAM (バス幅は32bit)、RTC (Real Time Clock)、MEMS sensor、User LED等が搭載されているのだから驚きだ。

PYNQ-Z1の購入も考えたのだが、TE0720の方がDDR3 SDRAMの容量、バス幅等で性能が上回っていたのでこれを購入した。ベースボードに搭載されているI/FはEthernet、USBホスト、USBデバイス(JTAG及びUSB-UART用)、マイクロSDカードコネクタで、HDMIコネクタは実装されていない。FPGAからの信号は左右のランドに出ているのでそこにHDMI信号を出すことは出来ると思う。

ヒートシンクを取り付けた状態

ヒートシンクは本体とは別売りだが、この状態で動作させても結構熱くなるので必須と考えたほうがいい。ベースボードの4隅のネジ穴は支柱やゴム足等の取付用穴にも見えるが、穴径はΦ3.0以下(Φ2.6のネジなら入る)と小さい。両サイドのランドにはDINコネクタを実装するというのが設計意図のようで、この穴はそのコネクタを固定するための穴だ。ベースボードにDINコネクタが付属していた。

とりあえず、今のところはこのコネクタは実装せずΦ2.6のネジを足代わりに取り付けることにした。

ZYBOと並べて大きさを比べてみた。

電源を入れてみたところ、PetaLinuxが起動した。

搭載されているZYNQ FPGAはXC7Z020とPYNQ-Z1と同等なので、PYNQのシステムを移植して動かせるのではないかと考えている。最近はAIがバズワード化しており、ネットでもAI関連の記事を見ない日が無いほどだが、私も流行に乗り遅れないように「FPGAでAI」をお勉強してナウでヤングなエンジニアを目指そうと企んでいる今日このごろだ。・・・できるかな?

その前にHDMIコネクタを取り付けなくては。

ERROR: Failed to spawn fakeroot worker to run ...

なにかと忙しくてなかなか趣味の時間を確保できない。 ...orz  家の開発機のOSはLinux Mintなのだが、最近バージョンを22に更新したところ、myCNC用のpetalinuxをビルドできなくなってしまった。ビルドの途中で ERROR: Failed to spawn ...