2022年7月10日日曜日

YoctoでGoogle CoralのEdgeTPU

 目的


今更ながらGoogle Coralのライブラリgoogle-coral/libedgetpuがbazelでなくてもビルドできることを知った。


なので、これをYoctoのレシピ化して見ることにした。


libedgetpuのレシピ


TensorFlow Liteをレシピ化しているmeta-tensorflow-liteに追加。


レシピ化するときにつまづいた点


すべてではないが、レシピかするときにつまずいた点、ちょっとだけ工夫した点を列挙。


ビルドのワーキングディレクトリの指定

今回、Makefileベースのレシピで作成したが、Makefileはトップディレクトリにない。
このため、${B}でMakefileがあるディレクトリを指定が必要。
ただ、Yoctoのドキュメントには

とあり、タスク[dirs]で指定して、${B}は有効でないとある。

しかしながら、タスク[dirs]で指定してもワークディレクトリは変更されなかった。。。
base.bbclassで上書き${B}で上書きされているので、${B}は必要なんじゃないのかな?
わたしの指定方法がまちがっているかもしれないが。。。


abseil-cppの必要なリンクするライブラリの不足


libedgetpuはabseil-cppのライブラリをいくつかリンクする。
Yoctoのkirkstoneにあるabseil-cppのバージョン( 20211102.0+gitX)はlibedgepuのGrouper(2021.7.27リリース)より新しい。
これが影響してか、ライブラリのリンクに不足(undefined symbol)が発生、パッチで修正した。

また、当初、Yoctoではなく、x86のubuntu22.04上でビルドしてリンク不足の修正を確認していた。その中でabseil-cppをソースビルド&スタティックリンクライブラリ(*.a)をリンクしたところ、undefined symbolが解消できないことがわかった(スタティックリンクだとabseeil-cppの一部がビルドされない?)。
Yoctoのabseil-cppのレシピは共有ライブラリ(*.so)を生成するオプションのため問題はなかったが、この違いによってハマってしまった。

libedgetpuのリポジトリにも同じようなissueがあり、解決できていなかったようなのでコメントしてみた。

gold リンカーを指定するとリンクエラー(risc-v)


RISC-V(meta-riscv)ターゲット向けにビルド時、goldリンカーはないとのエラーが発生する。
libedgetpuのMakefileでは -fuse-ld=gold が指定されている。
ARMターゲット(meta-raspberrypi)ではエラーにならないので、クロスコンパイラの違いが原因と思われる。
なので、Makefileから指定を削除した。



TensorFlow v2.9への対応


もともと、libedgetpuはTensorFlow v2.5のころのソースを一部利用している。
このなかでもcommon.cはC言語のソースだった。

TensorFlow v2.9では、common.cはcommon.ccに変更になっている。

これにあわせて、Makefileを修正している。


xxd: command not foundの解決


edgetpuのfirmwareをビルドする際にxxd(16進数のダンプコマンド)をつかっている。
このxxdコマンド、Yoctoでどのレシピを追加すればよいのかよくわからなかった、、、
OpenEmbedded Layer Indexをつかって検索してもよくわからず、、、

最終的にvim-nativeのレシピ(openembedded-core )を追加することで解決した。
(いつも使うコマンドがどんなパッケージにあるか?ってあまり意識しない時もある。こういうケースでは検索がなかなか大変。。。)


libedgetpu-maxとlibedgetpu-std


libedgetpuには動作周波数を変更する二つのライブラリが存在する。

この2つをレシピ化することにした。
方針としては以下にした。
  • レシピはlibedgetpu-std、libedgetpu-maxとする。
  • 共通部分をcommon.incに切り出して、EXTRA_OEMAKEに指定するフラグとインストールパス(do_install)を定義
  • お互いのレシピは同時に指定されたくないので、RCONFLICTSでコンフリクトするように指定。


ターゲットのBSP


今回は2つのBSPで動作させてみた。

Sipeed Lichee RV Dock向けについては、前回のブログを参照。
meta-riscvからforkしたリポジトリをつかう。

なお、Sipeed Lichee RV Dock向けについては、後述のとおり物体検出やセグメンテーションのモデルはうまく動いていない、、、


イメージの作成


いつもどおり、bitbakeしてみる。
Yoctoのバージョンはkirkstone。


Raspberry Pi 4


まずは、必要なリポジトリをclone。
$ git clone -b kirkstone git://git.yoctoproject.org/poky.git
$ git clone -b kirkstone git://git.yoctoproject.org/meta-raspberrypi
$ git clone -b kirkstone git://git.openembedded.org/meta-openembedded
$ git clone https://github.com/NobuoTsukamoto/meta-tensorflow-lite.git
$ source poky/oe-init-build-env rpi-build

$ bitbake-layers add-layer ../meta-openembedded/meta-oe/
$ bitbake-layers add-layer ../meta-openembedded/meta-python/
$ bitbake-layers add-layer ../meta-openembedded/meta-networking/
$ bitbake-layers add-layer ../meta-openembedded/meta-multimedia/
$ bitbake-layers add-layer ../meta-raspberrypi/
$ bitbake-layers add-layer ../meta-tensorflow-lite/

conf/auto.confに必要なパッケージを追加。
FORTRAN:forcevariable = ",fortran"
MACHINE ?= "raspberrypi4-64"
IMAGE_INSTALL:append = " \
  python3-tensorflow-lite \
  libedgetpu-max \
  opencv \
"
VIDEO_CAMERA = "1"

bitbake。
$ bitbake core-image-weston
...
Build Configuration:
BB_VERSION           = "2.0.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "aarch64-poky-linux"
MACHINE              = "raspberrypi4-64"
DISTRO               = "poky"
DISTRO_VERSION       = "4.0.1"
TUNE_FEATURES        = "aarch64 armv8a crc cortexa72"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "kirkstone:4aeda14352a9fa9dd5ba50cf940a2b514fd1ac3c"
meta-oe              
meta-python          
meta-networking      
meta-multimedia      = "kirkstone:fcc7d7eae82be4c180f2e8fa3db90a8ab3be07b7"
meta-raspberrypi     = "kirkstone:0135a02ea577bd39dd552236ead2c5894d89da1d"
meta-tensorflow-lite = "main:4299e649292a9471732e1fff2dc0eb776aba68f5"
...

イメージをSDカードに書き込む。


Sipeed Lichee RV Dock


こちらも同様に必要なリポジトリをclone。
$ git clone -b kirkstone git://git.yoctoproject.org/poky.git
$ git clone -b kirkstone https://github.com/openembedded/openembedded-core.git
$ git clone -b kirkstone https://github.com/openembedded/meta-openembedded.git
$ git clone -b kirkstone_licheerv https://NobuoTsukamoto/riscv/meta-riscv.git
$ git clone https://github.com/NobuoTsukamoto/meta-tensorflow-lite.git
$ source poky/oe-init-build-env licheerv-build

$ bitbake-layers add-layer ../meta-openembedded/meta-oe/
$ bitbake-layers add-layer ../meta-openembedded/meta-python/
$ bitbake-layers add-layer ../meta-openembedded/meta-networking/
$ bitbake-layers add-layer ../meta-openembedded/meta-multimedia/
$ bitbake-layers add-layer ../meta-riscv/
$ bitbake-layers add-layer ../meta-tensorflow-lite/

conf/auto.confに必要なパッケージ・オプションを追加。
FORTRAN:forcevariable = ",fortran"
MACHINE ?= "licheerv"
IMAGE_INSTALL:append = " \
  python3-tensorflow-lite \
  libedgetpu-std \
  opencv \
"

bitbake。
$ bitbake core-image-minimal
...
Build Configuration:
BB_VERSION           = "2.0.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "riscv64-poky-linux"
MACHINE              = "licheerv"
DISTRO               = "poky"
DISTRO_VERSION       = "4.0.1"
TUNE_FEATURES        = "riscv64"
meta                 
meta-poky            
meta-yocto-bsp       = "kirkstone:4aeda14352a9fa9dd5ba50cf940a2b514fd1ac3c"
meta-oe              
meta-python          
meta-networking      
meta-multimedia      = "kirkstone:fcc7d7eae82be4c180f2e8fa3db90a8ab3be07b7"
meta-riscv           = "kirkstone_licheerv:9083c701acede92b2378eb3f0df77fefb8ae29a0"
meta-tensorflow-lite = "main:4299e649292a9471732e1fff2dc0eb776aba68f5"
...

イメージを書き込む。


動作確認


こちらのPythonスクリプトを使っての動作確認。
(レシピ化していないのでSDカードに直接コードとモデルをコピーした)


Raspberry Pi 4


ラズパイ向けでは正常に動作するようだ。


Sipeed Lichee RV Dock


Lichee RV Dockの場合、
  • USBの電力供給の関係で動作しないので、電源供給つきのUSB-HUBが必要。
    device descriptor read/64, error -71 が発生した場合は、電力の不足を疑う。
    (libedgetpu-stdの場合はHUBがなくてもいけるかもしれない)
  • 画像分類モデルはうまく動きそうだが、物体検出やセマンティクス・セグメンテーションのモデルはうまく動作しない。。。
    • 物体検出は結果がすべてNG。
    • セマンティクス・セグメンテーションはポツポツと点のように結果がおかしい。

2つ目の事象は現時点では解決できていない。。。
(なんだかUSBの通信の関係の気がするが、、、)
RISC-V特有でない気もしている。






最後に


ちょっと遅くなったけど、libedgetpuをYoctoのレシピにしてみた。
ラズパイ向けはうまく動いたが、LICHEE RV DOCK向けはおかしい部分がある。

RISC-VのSBCで動けば、おもしろくなってくると思う。
EdgeTPUに限らず、RISC-V+アクセラレーターの構成がEdge AIとしてはありえるんじゃないかな?

2022年7月9日土曜日

YoctoでSipeed Lichee RV Dock

 目的


前回のブログではYoctoのmeta-riscvmeta-tensorflow-liteをつかって、Sipeed Lichee RV DockでOSイメージのビルドとTensorFlow-Liteの動作確認を行った。
ただし、meta-riscvにLichee RV Dock向けの対応(DTSなど)がないためUSBは使えない。

今回は、meta-riscvをforkしてU-Bootやカーネルなどを追加してLichee RV Dock向けBSPを作成して、USBが動作するところまで確認する。


参照


もともと、meta-riscvにはnezha allwinner d1の対応が含まれている。
Yocto Project Summit 2022.05で詳細が発表されていた模様。

これをもとにlinux-sunxiの情報と、 Archlinux Image Builderの情報をもとにBSPを作成してみる。


レシピ(BSP)の作成


meta-riscvをforkして作成。

ブランチは「kirkstone_licheerv」。

コミットはこちら。

おおきくわけて
  • machine configuration
  • boot0
  • opensbi
  • u-boot
  • linux kernel
  • wis
のレシピを変更・追加している。


machine configuration


machine/nezha-allwinner-d1.conf を参考にLichee RV 向けに変更している。

machineは「licheerv」。


boot0


nezha-allwinner-d1向けのレシピに対して修正。
COMPATIBLE_MACHINEに「licheerv」を追加している。


OpenSBI


OpenSBIもnezha-allwinner-d1と同様のであるため、レシピにlicheerv向けの追加を行っているのみ。


U-Boot


こちらはlicheerv向けに作成。

U-Bootのコードはsmaeul/u-bootを利用(ブランチは「d1-wip」)。
他、uEnvやtoc.cfgはnezha-allwinner-d1と同じものを利用。


Linux kernel


こちらもsmaeul/linuxを利用(ブランチは「riscv/d1-wip」)。
defconfigはsehraf/riscv-arch-image-builderのものを利用した(スクリプトから生成)。


wis


nezha-allwinner-d1と同じものを利用。
ただし、いつも参考にしているブログにあるとおりnezha-allwinner-d1のwisではイメージのサイズが大きい(約14GB)。

なので、今回はイメージサイズを約8GB程度にした。

--fixed-size 8000の部分。


イメージ作成(Bitbake)


core-image-minimalでbitbakeしてみる。
まずは、必要なリポジトリをclone。
$ git clone -b kirkstone git://git.yoctoproject.org/poky.git
$ git clone -b kirkstone https://github.com/openembedded/openembedded-core.git
$ git clone -b kirkstone https://github.com/openembedded/meta-openembedded.git
$ git clone -b kirkstone_licheerv https://NobuoTsukamoto/riscv/meta-riscv.git
$ source poky/oe-init-build-env licheerv-build

$ bitbake-layers add-layer ../meta-openembedded/meta-oe/
$ bitbake-layers add-layer ../meta-openembedded/meta-python/
$ bitbake-layers add-layer ../meta-openembedded/meta-networking/
$ bitbake-layers add-layer ../meta-openembedded/meta-multimedia/
$ bitbake-layers add-layer ../meta-riscv/

あとは、bitbake。
MACHINE=licheerv bitbake core-image-minimal

成功したら、*.wic.gzファイルをSDカードに書き込んでブートさせてみる。


動作確認




core-image-westonもやってみる


bitbakeでcore-image-westonをビルドして動かしてみた。



最後に


今回はRISC-V SBCのSipeed Lichee RV Dock向けのBSPをmeta-riscvのnezha-allwinner-d1を参考にやってみた。


2022年6月11日土曜日

Sipeed Lichee RV DockのYoctoでTensorFlow Lite v2.9

 目的


いつも参考にさせていただいているブログでRISC-V CPUのSipeed Lichee RV DockがYoctoで動くことを知った。


meta-tensorflow-liteはいままでQEMUでしか動かしたことがなかった。
Sipeed Lichee RV Dockは案外お安いというのもあり、一つ購入して実際に動かしてみたくなった。

購入したのは
  • Sipeed Lichee RV Dock Allwinner D1 Development Board RISC-V Linux Starter Kit
    without wifi 512M


イメージの作成


Yoctoでビルドする。
  • BSPにはmeta-riscv、バージョンはkikstone。
  • TensorFlow Liteのレシピにはmeta-tensorflow-lite。
  • TensorFlow Liteのバージョンはv2.9。
    • XNNPACK delegateしたいのでkirkstoneではなくて、mainブランチを使用。
  • ほんとうはCROPSを使いたかったけど、Fedora 36のpodmanだとうまくいかなかった。

まずは、必要なリポジトリをclone。
$ git clone -b 2.0 https://github.com/openembedded/bitbake.git
$ git clone -b kirkstone https://github.com/openembedded/openembedded-core.git
$ git clone -b kirkstone https://github.com/openembedded/meta-openembedded.git
$ git clone -b kirkstone https://github.com/riscv/meta-riscv.git
$ git clone https://github.com/NobuoTsukamoto/meta-tensorflow-lite.git
$ cd meta-tensorflow-lite
$ git checkout a58e5f1efbf5de17580e1f9f65f70d76715003b2

oe-init-build-env
$ source openembedded-core/oe-init-build-env build

auto.confに必要な情報(MACHINEとIMAGE_INSTALL)を追加。
$ cat conf/auto.conf 
FORTRAN:forcevariable = ",fortran"
MACHINE = "nezha-allwinner-d1"
IMAGE_INSTALL:append = "\
  python3-tensorflow-lite \
  libtensorflow-lite \
  python3-tensorflow-lite-example \
  tensorflow-lite-label-image \
  tensorflow-lite-minimal \
  tensorflow-lite-benchmark \
"

後はbitbake!
$ bitbake core-image-full-cmdline

...

Build Configuration:
BB_VERSION           = "2.0.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "ubuntu-20.04"
TARGET_SYS           = "riscv64-oe-linux"
MACHINE              = "nezha-allwinner-d1"
DISTRO               = "nodistro"
DISTRO_VERSION       = "nodistro.0"
TUNE_FEATURES        = "riscv64"
meta                 = "kirkstone:4eb0b7468383a1d0314b3bfd43ea37c95de464d9"
meta-oe              
meta-python          
meta-networking      
meta-multimedia      = "kirkstone:0b78362654262145415df8211052442823b9ec9b"
meta-riscv           = "kirkstone:70e099d7ceca52a1dde2c978713012f6b20a9891"
meta-tensorflow-lite = "main:a58e5f1efbf5de17580e1f9f65f70d76715003b2"

出来上がったイメージ(tmp-glibc/deploy/images/nezha-allwinner-d1配下の*.wic.gz)をmicro sdカードに書き込む。

USBシリアル変換ケーブルを接続して、起動してみる。



補足:FORTRANの追加


meta-tensorflow-liteのレシピでTensorFlow Lite v2.9からビルド時にFortranコンパイラが必要となった模様。
おそらく、XNNPACKのビルドで必要。

YoctoではデフォルトでFortranコンパイラがないため、ビルドに失敗する。
このため、confに以下を追加する必要がある。
FORTRAN:forcevariable = ",fortran"


動作


起動した後、TensorFlow Liteが動作することを確認してみる。
meta-tensorflow-liteで追加できるサンプル・ツールは以下のとおり(kirkstone)。

TensorFlow Lite C++ image classification demo(label_image)のサンプルを動かしてみる。
# cd /usr/share/tensorflow/lite/examples/label_image/
# ./labe 
  --tflite_model ./mobilenet_v1_1.0_224.tflite \                              
  --labels ./labels.txt \                                                     
  --image ./grace_hopper.bmp \                                                
  --xnnpack_delegate 1 \                                                      
  --threads 1                                                                 
INFO: Loaded model ./mobilenet_v1_1.0_224.tflite                                
INFO: resolved reporter                                                         
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.                         
XNNPACK delegate created.                                                       
INFO: Applied XNNPACK delegate.                                                 
INFO: invoked                                                                   
INFO: average time: 3214.8 ms                                                   
INFO: 0.860175: 653 653:military uniform                                        
INFO: 0.0481016: 907 907:Windsor tie                                            
INFO: 0.00786705: 466 466:bulletproof vest                                      
INFO: 0.00644932: 514 514:cornet, horn, trumpet, trump                          
INFO: 0.0060802: 543 543:drumstick 

XNNPACK delegateしていることを確認。

なお、label_imageにはxnnpack_delegateの引数を指定するとAbortする問題がある。
このため、レシピでパッチをあてて修正している。


ベンチマーク


さて、Sipeed Lichee RV DockのRISC-V CPUで画像分類モデルのベンチマーク(推論処理時間)をやってみる。
MobileNet V1、V2、V3 Small、V3 Largeでどの程度なのかを確認する。

ベンチマークはTFLite Model Benchmark Tool with C++ Binary(benchmark_model)を使用。
詳細の結果は以下のリポジトリにアップ。

CPUの情報を確認。
# cat /proc/cpuinfo 
processor       : 0
hart            : 0
isa             : rv64imafdc
mmu             : sv39
uarch           : thead,c906

ベンチマークの結果:Inference (avg) 、単位はms。
まあ、CPUのスペックもあるし、最適化もこれからと思う(INT8は全然最適化されていなさそう?)。

Model name Input Kind Lichee RV Dock
XNNPACK delegate
Mobilenet V1 dm=1.0 224x224 FP32 2874.29
INT8 10091.20
Mobilenet V2 dm=1.0 224x224 FP32 978.40
INT8 6210.03
Mobilenet V3 Large dm=1.0 224x224 FP32 754.20
INT8 4853.66
Mobilenet V3 Small dm=1.0 224x224 FP32 241.70
INT8 1444.20

最後に


はじめて、RISC-V の実機でTensorFlow Liteを動かしてみた。

きっとRISC-V CPUベースのSoCだと、きっと、GPUやアクセラレーターを使う方が主流になるはず?CPUで推論はメインではないとは思うのだけど、かなりおもしろかった。

処理時間はラズパイなどとは比べようもないのだけど、はじめてラズパイでTensorFlow Liteを動かした時のような感覚をおもいだした気がする。

これからもRISC-Vがあつくなるといいなぁ!!

2022年6月5日日曜日

2022.6.4の釣行

お昼に時間をもらってちょっとだけ。


おうちから10分で行ける渓流です。


う〜ん...


ボウズです。チェイスあったけどなぁ。


2022.6.3の釣行

 きょうは近くの本流に。


お昼ぐらいから雨が降ったり、⛈だったりとあまり良くない天気。


その分、朝方は活性がたかかったのかも。


ニジマス、ヤマメ。ヤマメは久々だな〜。


写真とるのヘタすぎ😇(防水じゃないのもあるんだけどね、、、)


流れの中からガバって出てくると楽しいよね。



全然わからん、、、

2022年5月14日土曜日

Fedora 36 でTensorflow 2.9rc2(CUDA11.6 cuDNN8.4.0)をビルドする

 目的


Tensorflowの2.9rc2 + CUDAをFedora 36でソースビルドする。


環境


  • SW
    • Fedora 35 x86_64
    • Python 3.10.4
    • GCC 12.0.1 20220308
    • CUDA 11.6 + cuDNN v8.4.0
  • HW
    • CPU AMD Ryzen 7 1700
    • GPU GeForce GTX 1070


事前の準備


CUDA、cuDNNのインストール


これは、以前のブログと同様。
RPM Fusionを参考にCUDAを、NVIDIAよりcuDNNをそれぞれインストールする。


Bazelのソースビルド


TensorFlow v2.9はBazel 5.0.0以上でのビルドが必要。
FedoraのCOPR repositoryからインストール(公式の手順にもある)できるバージョンは4系でビルドできない。
このため、v5.1.1をソースビルドする。
$ sudo dnf install java-11-openjdk-devel
$ wget https://github.com/bazelbuild/bazel/releases/download/5.1.1/bazel-5.1.1-dist.zip
$ unzip -qq bazel-5.1.1-dist.zip
$ env EXTRA_BAZEL_ARGS="--host_javabase=@local_jdk//:jdk" bash ./compile.sh
$ sudo cp output/bazel /usr/local/bin/


GCC11.2のビルド


CUDA 11.6がサポートするGCCのバージョンは11.2で、Fedora 36のGCC12は対象外。
このため、GCC 11.2をソースビルドする。
ビルドについては、以前のブログを参照。


ソースダウンロード&ビルド


$ wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-11.2.0/gcc-11.2.0.tar.gz
$ tar xf gcc-11.2.0.tar.gz
$ gcc-11.2.0/
$ ./contrib/download_prerequisites
$ mkdir build && cd build
$ ../configure \
    --enable-bootstrap \
    --enable-languages=c,c++ \
    --prefix=/home/USER/gcc/11.2 \
    --enable-shared \
    --enable-threads=posix \
    --enable-checking=release \
    --disable-multilib \
    --with-system-zlib \
    --enable-__cxa_atexit \
    --disable-libunwind-exceptions \
    --enable-gnu-unique-object \
    --enable-linker-build-id \
    --with-gcc-major-version-only \
    --with-linker-hash-style=gnu \
    --enable-plugin \
    --enable-initfini-array \
    --with-isl \
    --enable-libmpx \
    --enable-gnu-indirect-function \
    --build=x86_64-redhat-linux
$ make -j$(nproc)
$ make install


specsファイルの作成&設定


コンパイルしたGCC11でビルドした際に、適切な動的リンクライブラリ(libstdc++.so)がリンクされるようにSPECEファイルを修正する。
$ /home/USER/gcc/11.2/bin/gcc -dumpspecs > specs
$ vi specs

# before
*link_libgcc:
%D

# after
*link_libgcc:
%{!static:%{!static-libgcc:-rpath /home/USER/gcc/11.2/lib64/}} %D

$ mv specs /home/USER/gcc/11.2/lib/gcc/x86_64-redhat-linux/11/


Tensorflowのビルド


さて、本題。TensorFlow 2.9-rc2をビルドする。


virtualenvの設定


まずはvirtualenv(virtualenvwapper)でTensorflow用の仮想Python環境を作成し、必要なモジュールをインストールする。
$ mkvirtualenv tf2.9rc2
$ pip install pip numpy wheel
$ pip install keras_preprocessing --no-deps
$ pip install packaging

今回、packagingモジュールも追加でインストールが必要だった。
(ビルド時にModuleNotFoundError: No module named 'packaging'エラーとなった)


ビルド


今までどおりconfigure&buildなのだが、今回は追加の手順が必要。
CUDA_HOST_COMPILERに使用するGCC11とGCC12でGLIBCXXのABIが異なってしまう。
ビルドは成功するが、import時に以下のエラーが発生してしまう。

$ python
Python 3.10.4 (main, Mar 25 2022, 00:00:00) [GCC 12.0.1 20220308 (Red Hat 12.0.1-0)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow as tf
Traceback (most recent call last):
  File "/home/USER/.virtualenvs/tf2.9rc2/lib64/python3.10/site-packages/tensorflow/python/pywrap_tensorflow.py", line 62, in <module>
    from tensorflow.python._pywrap_tensorflow_internal import *
ImportError: /home/USER/gcc/11.2/lib64/libstdc++.so.6: version `GLIBCXX_3.4.30' not found (required by /home/USER/.virtualenvs/tf2.9rc2/lib64/python3.10/site-packages/tensorflow/python/_pywrap_tensorflow_internal.so)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/USER/.virtualenvs/tf2.9rc2/lib64/python3.10/site-packages/tensorflow/__init__.py", line 37, in <module>
    from tensorflow.python.tools import module_util as _module_util
  File "/home/USER/.virtualenvs/tf2.9rc2/lib64/python3.10/site-packages/tensorflow/python/__init__.py", line 36, in <module>
    from tensorflow.python import pywrap_tensorflow as _pywrap_tensorflow
  File "/home/USER/.virtualenvs/tf2.9rc2/lib64/python3.10/site-packages/tensorflow/python/pywrap_tensorflow.py", line 77, in <module>
    raise ImportError(
ImportError: Traceback (most recent call last):
  File "/home/USER/.virtualenvs/tf2.9rc2/lib64/python3.10/site-packages/tensorflow/python/pywrap_tensorflow.py", line 62, in <module>
    from tensorflow.python._pywrap_tensorflow_internal import *
ImportError: /home/USER/gcc/11.2/lib64/libstdc++.so.6: version `GLIBCXX_3.4.30' not found (required by /home/USER/.virtualenvs/tf2.9rc2/lib64/python3.10/site-packages/tensorflow/python/_pywrap_tensorflow_internal.so)


Failed to load the native TensorFlow runtime.
See https://www.tensorflow.org/install/errors for some common causes and solutions.
If you need help, create an issue at https://github.com/tensorflow/tensorflow/issues and include the entire stack trace above this error message.

Fedora36のGCC12 libstdc++とビルドしたGCC11 libstdc++のGLIBCXXのABIの不一致。
これを回避するために、ビルド時のオプションに"-std=gnu++14"を付与する。

あとは、Githubからソースを取得し、configureスクリプト実行し、ビルドを行う。
  • CUDAのサポートを有効とする。
  • Host compilerにGCC11.2のgccのパスを指定してあげる。
  • ビルドオプションには"--config=v2"、"-std=gnu++14"、"--config=nonccl "を指定。

$ ./configure 
You have bazel 5.1.1- (@non-git) installed.
Please specify the location of python. [Default is /home/USER/.virtualenvs/tf2.9rc2/bin/python3]: 


Found possible Python library paths:
  /home/USER/.virtualenvs/tf2.9rc2/lib/python3.10/site-packages
  /home/USER/.virtualenvs/tf2.9rc2/lib64/python3.10/site-packages
Please input the desired Python library path to use.  Default is [/home/USER/.virtualenvs/tf2.9rc2/lib/python3.10/site-packages]

Do you wish to build TensorFlow with ROCm support? [y/N]: 
No ROCm support will be enabled for TensorFlow.

Do you wish to build TensorFlow with CUDA support? [y/N]: y
CUDA support will be enabled for TensorFlow.

Do you wish to build TensorFlow with TensorRT support? [y/N]: 
No TensorRT support will be enabled for TensorFlow.

Found CUDA 11.6 in:
    /usr/local/cuda-11.6/targets/x86_64-linux/lib
    /usr/local/cuda-11.6/targets/x86_64-linux/include
Found cuDNN 8 in:
    /usr/local/cuda-11.6/targets/x86_64-linux/lib
    /usr/local/cuda-11.6/targets/x86_64-linux/include


Please specify a list of comma-separated CUDA compute capabilities you want to build with.
You can find the compute capability of your device at: https://developer.nvidia.com/cuda-gpus. Each capability can be specified as "x.y" or "compute_xy" to include both virtual and binary GPU code, or as "sm_xy" to only include the binary code.
Please note that each additional compute capability significantly increases your build time and binary size, and that TensorFlow only supports compute capabilities >= 3.5 [Default is: 6.1]: 


Do you want to use clang as CUDA compiler? [y/N]: 
nvcc will be used as CUDA compiler.

Please specify which gcc should be used by nvcc as the host compiler. [Default is /usr/bin/gcc]: /home/USER/gcc/11.2/bin/gcc


Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -Wno-sign-compare]: 


Would you like to interactively configure ./WORKSPACE for Android builds? [y/N]: 
Not configuring the WORKSPACE for Android builds.

Preconfigured Bazel build configs. You can use any of the below by adding "--config=<>" to your build command. See .bazelrc for more details.
	--config=mkl         	# Build with MKL support.
	--config=mkl_aarch64 	# Build with oneDNN and Compute Library for the Arm Architecture (ACL).
	--config=monolithic  	# Config for mostly static monolithic build.
	--config=numa        	# Build with NUMA support.
	--config=dynamic_kernels	# (Experimental) Build kernels into separate shared objects.
	--config=v1          	# Build with TensorFlow 1 API instead of TF 2 API.
Preconfigured Bazel build configs to DISABLE default on features:
	--config=nogcp       	# Disable GCP support.
	--config=nonccl      	# Disable NVIDIA NCCL support.
Configuration finished
$ bazel build \
    --config=cuda \
    --config=v2 \
    --config=nonccl \
    --config=opt \
    --cxxopt="-std=gnu++14" \
    //tensorflow/tools/pip_package:build_pip_package
$ ./bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
$ cp /tmp/tensorflow_pkg/tensorflow-2.9.0rc2-cp310-cp310-linux_x86_64.whl ./
$ pip3 install tensorflow-2.9.0rc2-cp310-cp310-linux_x86_64.whl


インストールの確認


  • tf.__version__が2.9-rc2であること。
  • GPUデバイスを認識していること。


2022年5月7日土曜日

meta-tensorflow-liteをyocto kirkstoneに対応するときにつまずいた点

 目的


meta-tensorflow-liteをkikstoneに対応した際に行ったこと、つまずいたことを記録する。
また、今回もtiwtterでかなりアドバイスをいただいた。感謝。



meta-tensorflow-liteの対応


kikstoneはyoctoのメジャーバージョンがアップし、4.0になった。

かなり変更があり、自分のレシピにもかなりの影響があった。
  1. SRC_URIのgit url指定の変更
  2. SRCREVにコミットIDを指定
  3. do_fetch以外でのダウンロードの抑制
  4. CMAKE_SYSTEM_PROCESSORの制御を変更

なお、kirkstoneに対応したmeta-tensorflow-liteは以下で公開した。




SRC_URIのgit url指定の変更


SRC_URIにgit を指定している場合、
  • プロトコル(protocol=???)
  • ブランチ(branch=???)
を必ず指定することになった。
meta-tensorflow-liteはhonisterからどちらも指定していたので問題はなかった。

変換用のスクリプトも用意されている。
また、レシピの命名規則などを変換するスクリプト(convert-xxxxxxxx.py)も用意されている。これらは事前にかけておいた方がよい。
(いくつかoverride syntaxの"_"を":"に変更する必要があった箇所があった)


SRCREVのコミットIDの指定


honisterまでのレシピでbitbakeすると以下のエラーが発生した。

ERROR: python3-tensorflow-lite-2.8.0-r0 do_fetch: Bitbake Fetcher Error: FetchError("Recipe uses a floating tag/branch without a fixed SRCREV yet doesn't call bb.fetch2.get_srcrev() (use SRCPV in PV for OE).", None)

どうやら、kirkstoneではSRCREVにタグ名の指定はNGの模様。
コミットIDを指定する必要があった。リリースノートには記載が見当たらず、、、(もしかしたら見逃しているだけかも)

honisterまでのレシピは、以前にissueでいただいたやり方で${PV}をつかった自動化でもあった(レシピのファイル名のバージョンをあげるだけでよい)

次回以降はTensorFlowのバージョンアップの際にコミットIDの変更が必要になった...


do_fetch以外でモジュールをダウンロードする対応


これは影響の大きかった変更点。yocto 4.0のリリースノートにも記載がある。

TensorFlow LiteはCMakeのconfigureでサブモジュールをダウンロードするため、大きく影響を受けた。
どうすればよいのか悩んでいたところ、twitterでアドバイスをうけた(ほんとうにありがとうございます)。

Kirkstoneからはdo_fetch以外でダウンロードを行う場合は、該当タスクにフラグをたてる必要があるとのこと。
ただ、フラグをたてても状況が変わらずだった(サブモジュールのダウンロードができない)。
何が違うのか?ミニマムなサンプルを作成して事象を再現させて確認。

原因は、TensorFLow LiteのCMakeでExternalProject_Addではなく、FetchContent_Declare、FetchContent_PopulateなどのFetchContentを使用していることが原因だった。

cmake.bbclassでCMAKEのオプションにオプションにFETCHCONTENT_FULLY_DISCONNECTEDが追加されていた(kirkstoneより)。
FETCHCONTENT_FULLY_DISCONNECTEDオプションはFetchContentのダウンロードを抑制するオプションとのこと(知らなかった!)。
このFETCHCONTENT_FULLY_DISCONNECTEDはExternalProject_Addに影響しない模様。
これが動作の違いになっていた。

このため、レシピにはEXTRA_OECMAKEでFETCHCONTENT_FULLY_DISCONNECTEDを変更&do_configureでネットワークからのダウンロードを有効にするようにした。

EXTRA_OECMAKE:append = " -DFETCHCONTENT_FULLY_DISCONNECTED=OFF"
do_configure[network] = "1"


CMAKE_SYSTEM_PROCESSORの指定方法の変更


上記のレシピ修正でなんとかaarch64やriscv向けのターゲットでビルドできるようになった。
しかしながら、armv6やarmv7向けのビルドが失敗する。

レシピでHOST_ARCHを変更していたことが原因の模様(honisterまでは問題なかったが、kirkstoneではエラーとなってしまった)。

HOST_ARCHを設定していた理由は、cmake.bbclassのCMAKE_SYSTEM_PROCESSORオプションを制御したかったため。

TensorFlow Liteのサブモジュールでpytorch/cpuinfoはCMakeのCMAKE_SYSTEM_PROCESSORオプションを意識する。
このため、TensorFlow LiteのCMakeビルドの際にオプションを指定している。
具体的には、初代ラズパイ、ラズパイ0は"armv6"、その他ラズパイ32bitは"armv7"を期待している。

yoctoのcmake.bbclassでは、CMAKE_SYSTEM_PROCESSORオプションにHOST_OS(TARGET_OS)を指定している。
meta-raspberrypiでビルドする際、"raspberrypi"や"raspberrypi4"などのarm 32bitの場合、HOST_OS(TARGET_OS)には"arm"が設定されるため、TensorFlow Liteのビルドが失敗する。
このため、TARGET_OSをレシピより"armv6"や"armv7"など期待する値に上書きすることで対応していた。

kirkstoneからはこのやり方がエラーとなってしまうため、TARGET_OSは変更せず、TensorFlow LiteのCMakeLists.txtにパッチを当ててCMAKE_SYSTEM_PROCESSORオプションを設定するように変更した。
(EXTRA_OECMAKEで"-DCMAKE_SYSTEM_PROCESSORを指定してもうまくいかなかった)


最後に


今回もかなり助けられて対応することができた。ほんとに感謝。

まだ、Raspberry Piで動作確認できない(core-image-westonでブート時にディスプレイが表示されない)やTensorFlow Lite v2.9のリリースも近いのでまだまだ確認&対応していく予定。

2022年3月6日日曜日

meta-riscvでTensorFlow Lite(Yocto)

目的


meta-tensorflowliteをv2.8対応+公式サンプルとベンチマークツールのレシピを追加した。
これを使ってmeta-riscvでbitbakeする。qemuriscv64でTensorFlow Liteのサンプル、ベンチマークツールを動作させてみる。


meta-tensorflowliteの対応


meta-tensorflowliteのリポジトリは以下。

今回、TensorFlow Lite v2.8の対応を含めてレシピの整理・追加を行った。
  • ブランチをYoctoバージョンと合わせて管理。
    • 今後はTensorFlow Liteのバージョンもブランチで固定。
  • Python3 interpreterのレシピのv2.8対応。
    • RISC-Vのビルドは以前から対応済み。
  • C++ API shared library(libtensorflowflow-lite)のレシピのv2.8対応。
    • レシピ名をcpp-tensorflow-liteからlibtensorflow-liteに変更。
    • インストール時、ヘッダファイルの不足があったので修正。
  • TensorFlowのリポジトリにあるPython、C++のサンプルをレシピ化&簡単なドキュメントを整理。
    (リンクはmeta-tensorflow-liteのドキュメントのリンク)
  • 同じように、ベンチマークツール(benchmark_model)もレシピ化。
  • GitHub Actionsを導入して、コードの変更&週一でのビルドのCIを導入。


リポジトリのClone


さて、ここからは実際にビルドしてみる。まずは必要なリポジトリをclone。
  • Yoctoのバージョンはhonisterとする。
  • meta-tensorflow-liteはcommit idを指定(このあとkirkstoneに移行予定)。
$ git clone -b 1.52 https://github.com/openembedded/bitbake.git
$ git clone -b honister https://github.com/openembedded/openembedded-core.git
$ git clone -b honister https://github.com/openembedded/meta-openembedded.git
$ git clone -b honister https://github.com/riscv/meta-riscv.git
$ git clone https://github.com/NobuoTsukamoto/meta-tensorflow-lite.git
$ cd meta-tensorflow-lite
$ git checkout eae1cb93a12fcb1ade71197b99111c2f02f515ef
$ cd ..


ビルド環境の設定


ここではmeta-riscvのsetup.shを実行する。
$ . ./meta-riscv/setup.sh

その後、meta-tensorflow-liteを追加。
$ bitbake-layers add-layer ../meta-tensorflow-lite/

conf/auto.confを編集。2行追加する。
  • USER_CLASSES:remove = "image-prelink" を指定しないとbitbakeでエラーとなる。
    これは、setup.shで追加されちゃうので...
  • IMAGE_INSTALL:appendでtensorflow-liteのレシピを追加。
USER_CLASSES:remove = "image-prelink"
IMAGE_INSTALL:append = " python3-tensorflow-lite \
 libtensorflow-lite \
 python3-tensorflow-lite-example \
 tensorflow-lite-label-image \
 tensorflow-lite-minimal \
 tensorflow-lite-benchmark"

bitbake


bitbake!!!!!!
$ MACHINE=qemuriscv64 bitbake core-image-full-cmdline

このときの結果はこんな感じ。
$ MACHINE=qemuriscv64 bitbake core-image-full-cmdline
Loading cache: 100% |                                                                                                                                                                                                        | ETA:  --:--:--
Loaded 0 entries from dependency cache.
Parsing recipes: 100% |#######################################################################################################################################################################################################| Time: 0:00:36
Parsing of 2428 .bb files complete (0 cached, 2428 parsed). 3767 targets, 165 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION           = "1.52.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "fedora-35"
TARGET_SYS           = "riscv64-oe-linux"
MACHINE              = "qemuriscv64"
DISTRO               = "nodistro"
DISTRO_VERSION       = "nodistro.0"
TUNE_FEATURES        = "riscv64"
meta                 = "honister:eeae63c343c8ebd418679915ee20aa8c02fa0fdc"
meta-oe              
meta-python          
meta-multimedia      
meta-networking      = "honister:0fb490a08ce30b47a5ccd2fdc3448b08e0d9e4e9"
meta-riscv           = "honister:9561639c61663a10d8c9c23d26173db499f4c39b"
meta-tensorflow-lite = "main:eae1cb93a12fcb1ade71197b99111c2f02f515ef"

NOTE: Fetching uninative binary shim http://downloads.yoctoproject.org/releases/uninative/3.5/x86_64-nativesdk-libc-3.5.tar.xz;sha256sum=e8047a5748e6f266165da141eb6d08b23674f30e477b0e5505b6403d50fbc4b2 (will check PREMIRRORS first)
Initialising tasks: 100% |####################################################################################################################################################################################################| Time: 0:00:05
Sstate summary: Wanted 1403 Local 0 Network 0 Missed 1403 Current 0 (0% match, 0% complete)
NOTE: Executing Tasks
WARNING: mtools-native-4.0.35-r0 do_fetch: Failed to fetch URL https://ftp.gnu.org/gnu/mtools/mtools-4.0.35.tar.bz2, attempting MIRRORS if available
NOTE: Tasks Summary: Attempted 4090 tasks of which 0 didn't need to be rerun and all succeeded.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 79 seconds
NOTE: Build completion summary:
NOTE:   do_populate_sysroot: 0.0% sstate reuse(0 setscene, 267 scratch)
NOTE:   do_package_qa: 0.0% sstate reuse(0 setscene, 192 scratch)
NOTE:   do_package: 0.0% sstate reuse(0 setscene, 192 scratch)
NOTE:   do_packagedata: 0.0% sstate reuse(0 setscene, 192 scratch)
NOTE:   do_package_write_ipk: 0.0% sstate reuse(0 setscene, 192 scratch)
NOTE:   do_populate_lic: 0.0% sstate reuse(0 setscene, 360 scratch)

Summary: There was 1 WARNING message shown.


QEMUの実行


qemuを実行。
$ MACHINE=qemuriscv64 runqemu nographic

qemuriscv64が動いた!
OpenSBI v0.9
   ____                    _____ ____ _____
  / __ \                  / ____|  _ \_   _|
 | |  | |_ __   ___ _ __ | (___ | |_) || |
 | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
 | |__| | |_) |  __/ | | |____) | |_) || |_
  \____/| .__/ \___|_| |_|_____/|____/_____|
        | |
        |_|

Platform Name             : riscv-virtio,qemu
Platform Features         : timer,mfdeleg
Platform HART Count       : 4
Firmware Base             : 0x80000000
Firmware Size             : 124 KB
Runtime SBI Version       : 0.2

Domain0 Name              : root
Domain0 Boot HART         : 0
Domain0 HARTs             : 0*,1*,2*,3*
Domain0 Region00          : 0x0000000080000000-0x000000008001ffff ()
Domain0 Region01          : 0x0000000000000000-0xffffffffffffffff (R,W,X)
Domain0 Next Address      : 0x0000000080200000
Domain0 Next Arg1         : 0x0000000082200000
Domain0 Next Mode         : S-mode
Domain0 SysReset          : yes

Boot HART ID              : 0
Boot HART Domain          : root
Boot HART ISA             : rv64imafdcsu
Boot HART Features        : scounteren,mcounteren,time
Boot HART PMP Count       : 16
Boot HART PMP Granularity : 4
Boot HART PMP Address Bits: 54
Boot HART MHPM Count      : 0
Boot HART MHPM Count      : 0
Boot HART MIDELEG         : 0x0000000000000222
Boot HART MEDELEG         : 0x000000000000b109
[    0.000000] Linux version 5.14.21-yocto-standard (oe-user@oe-host) (riscv64-oe-linux-gcc (GCC) 11.2.0, GNU ld (GNU Binutils) 2.37.20210721) #1 SMP PREEMPT Wed Mar 2 12:59:31 UTC 2022
[    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
[    0.000000] Machine model: riscv-virtio,qemu
[    0.000000] Memory limited to 256MB
[    0.000000] efi: UEFI not found.
[    0.000000] Zone ranges:
[    0.000000]   DMA32    [mem 0x0000000080200000-0x000000008fffffff]
[    0.000000]   Normal   empty
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000080200000-0x000000008fffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x000000008fffffff]
[    0.000000] SBI specification v0.2 detected
[    0.000000] SBI implementation ID=0x1 Version=0x9
[    0.000000] SBI TIME extension detected
[    0.000000] SBI IPI extension detected
[    0.000000] SBI RFENCE extension detected
[    0.000000] SBI v0.2 HSM extension detected
[    0.000000] riscv: ISA extensions acdfimsu
[    0.000000] riscv: ELF capabilities acdfim

rootでログイン。
OpenEmbedded nodistro.0 qemuriscv64 ttyS0

qemuriscv64 login: root
root@qemuriscv64:~# 


TensorFlow Liteのサンプル&ツールの実行


実際にビルドしたTensorFlow Liteのサンプル&ツールを実行する。


python3-tensorflow-lite-example


Pythonのサンプル(label_image.py)。
TensorFlow Liteで動作するようにimportするパッケージ名を修正している。
テスト用のモデル、画像も公式と同じもの(mobilenet_v1_1.0_224.tflite & grace_hopper.bmp)をインストールするようレシピ化している。
# cd /usr/share/tensorflow/lite/examples/python/
# python3 label_image.py \
   --image ./grace_hopper.bmp \
   --model_file ./mobilenet_v1_1.0_224.tflite \
   --label_file ./labels.txt

しばらくすると、結果が出力される。
0.919720: 653:military uniform
0.017762: 907:Windsor tie
0.007507: 668:mortarboard
0.005419: 466:bulletproof vest
0.003828: 458:bow tie, bow-tie, bowtie
time: 4925.118ms

Top1スコアは公式結果と同様の「military uniform」。
(スコアの値が違うのは...XNNPACKと何か違うんだっけ?)


tensorflow-lite-label-image


C++のサンプル(label_image)。
こちらはlibtensorflow-liteのレシピでビルドした共有ライブラリ(libtensorflow-lite.so)をリンクするように変更。
テスト用のモデル、画像も公式と同じものを用意。
# cd /usr/share/tensorflow/lite/examples/label_image/
# ./label_image \
   --tflite_model ./mobilenet_v1_1.0_224.tflite \
   --labels ./labels.txt \
   --image ./grace_hopper.bmp 

こちらもしばらくすると結果が表示される。
INFO: Loaded model ./mobilenet_v1_1.0_224.tflite
INFO: resolved reporter
INFO: invoked
INFO: average time: 2973.11 ms
INFO: 0.860174: 653 653:military uniform
INFO: 0.0481021: 907 907:Windsor tie
INFO: 0.00786705: 466 466:bulletproof vest
INFO: 0.00644936: 514 514:cornet, horn, trumpet, trump
INFO: 0.00608029: 543 543:drumstick

スコアは一応、公式と一致。


tensorflow-lite-minimal


こちらもC++のサンプル(minimal)。
tensorflow-lite-label-imageと同じ。
# cd /usr/share/tensorflow/lite/examples/minimal/
# ./minimal ./mobilenet_v1_1.0_224.tflite

結果の表示(出力が多いので一部割愛)。
=== Pre-invoke Interpreter State ===
Interpreter has 1 subgraphs.

-----------Subgraph-0 has 103 tensors and 31 nodes------------
1 Inputs: [87] -> 602112B (0.57MB)
1 Outputs: [86] -> 4004B (0.00MB)

Tensor  ID Name                      Type            AllocType          Size (Bytes/MB)    Shape      MemAddr-Offset  
Tensor   0 MobilenetV1/Conv2d_0/w... kTfLiteFloat32  kTfLiteMmapRo      3456     / 0.00 [32,3,3,3] [16842720, 16846176)
Tensor   1 MobilenetV1/Conv2d_10_... kTfLiteFloat32  kTfLiteMmapRo      18432    / 0.02 [1,3,3,512] [6423008, 6441440)
Tensor   2 MobilenetV1/Conv2d_10_... kTfLiteFloat32  kTfLiteMmapRo      1048576  / 1.00 [512,1,1,512] [10624920, 11673496)

...

Execution plan as the list of 31 nodes invoked in-order: [0-30]
--------------Subgraph-0 dump has completed--------------


tensorflow-lite-benchmark


ベンチマークツールのbenchmark_model。
このツールは必須ですね!!
libtensorflow-liteのレシピでビルドした共有ライブラリをリンクするようにしたかったけど、色々と無理があったので、単体でビルドするようにした。
# cd /usr/share/tensorflow/lite/tools/benchmark/
# ./benchmark_model \
   --graph=./mobilenet_v1_1.0_224.tflite \
   --num_threads=4 \
   --enable_op_profiling=true

こちらも結果は一部省略。
STARTING!
Log parameter values verbosely: [0]
Num threads: [4]
Graph: [./mobilenet_v1_1.0_224.tflite]
Enable op profiling: [1]
#threads used for CPU inference: [4]
Loaded model ./mobilenet_v1_1.0_224.tflite
The input model file size (MB): 16.9008
Initialized session in 83.064ms.
Running benchmark for at least 1 iterations and at least 0.5 seconds but terminate if exceeding 150 seconds.
count=1 curr=3470145

...

Number of nodes executed: 31
============================== Summary by node type ==============================
	             [Node type]	  [count]	  [avg ms]	    [avg %]	    [cdf %]	  [mem KB]	[times called]
	                 CONV_2D	       15	  2554.810	    89.801%	    89.801%	     0.000	       15
	       DEPTHWISE_CONV_2D	       13	   289.070	    10.161%	    99.962%	     0.000	       13
	         AVERAGE_POOL_2D	        1	     0.846	     0.030%	    99.991%	     0.000	        1
	                 SOFTMAX	        1	     0.226	     0.008%	    99.999%	     0.000	        1
	                 SQUEEZE	        1	     0.019	     0.001%	   100.000%	     0.000	        1

Timings (microseconds): count=50 first=2936299 curr=2869577 min=2657264 max=3069766 avg=2.84499e+06 std=82794
Memory (bytes): count=0
31 nodes observed

最後に


2022年4月にはYoctoの次のバージョン(kirkstone)がリリースされる。
ようやくmeta-tensorflow-liteのレシピの追加・整理も終わってkirkstoneへの準備ができる状態になった。

また、TensorFlow LiteはXNNPACKがRISC-Vアーキテクチャをサポートしたみたい。
次のv2.9のリリースでは取り込まれると思われる。
meta-tensorflow-liteもRISC-VでXNNPACKを有効にできるようにしたい。

RISC-V CPUでTensorFlow Liteが動くと楽しくなってくるね。

2022年2月5日土曜日

YoctoでTensorFlow Lite v2.8.0(Microchip PolarFire SoC Yocto BSP + meta-tensorflow-lite)

目的


meta-tensorflow-lite(python3-tensorflow-lite)でTensorFlow Lite v2.8.0のビルドにRISC-Vを対応する。
先日、v2.8.0がリリースされたので対応することと、こちらのissue(RISC-Vでビルドできない)であったBSPでビルド確認を行う。


Microchip PolarFire SoCって?


RISC-V CPU + FPGAのSoCのよう。
開発元はMicrochip Technology。

CPUはSiFive U54を5コア(セキュアブート用が1つとアプリケーション用が4コアとある)。
メモリはLPDDR4 2GB。

なお、私は実機を所持していない。
どれぐらいなんだろうとのぞいてみたら...リードタイム...

※2022年1月末のつぶやきなので最新の状況はチェックしてください。


環境&準備


ホスト環境および、事前にインストールするパッケージ等は前回のブログと同様。
の該当部分を参照。


リポジトリ


meta-tensorflow-liteおよび、Microchip PolarFire SoC Yocto BSPのリポジトリは以下。

meta-tensorflow-lite




meta-polarfire-soc-yocto-bsp




ビルド


さてここからはビルド。

Microchip PolarFire SoC Yocto BSPをClone、必要なリポジトリを取得する。
なお、このときのリビジョンは"02cb81741a5e1b37f89318d04ebc6b2854bfe736"である。
$ mkdir yocto-dev
$ cd yocto-dev
$ repo init -u https://github.com/polarfire-soc/meta-polarfire-soc-yocto-bsp.git -b master -m tools/manifests/riscv-yocto.xml
$ repo sync
$ repo rebase

meta-tensorflow-liteのCloneする。
v2.8.0対応のリビジョンでチェックアウトする。
$ git clone  https://github.com/NobuoTsukamoto/meta-tensorflow-lite.git
$ cd meta-tensorflow-lite/
$ git checkout b20bc554a30933a65648ee4557ebb48aacd4db54
$ cd ..

polarfire-soc_yocto_setup.shを実行(bitbake-layersやoe-init-build-envなど実行)。
$ . ./meta-polarfire-soc-yocto-bsp/polarfire-soc_yocto_setup.sh

meta-tensorflow-liteを追加する。
$ bitbake-layers add-layer ../meta-tensorflow-lite/

auto.confにpython3-tensorflow-liteを追加する。
$ vi conf/auto.conf
# 最終行に以下を追加
IMAGE_INSTALL:append = " python3-tensorflow-lite"

最後にbitbake!
MACHINE=qemuriscv64を指定するとエラーで怒られてしまう、、、
このため、実機向け(MACHINE=icicle-kit-es)でビルド。
$ MACHINE=icicle-kit-es bitbake mpfs-dev-cli
Loading cache: 100% |#########################################################################################################| Time: 0:00:00
Loaded 3774 entries from dependency cache.
Parsing recipes: 100% |#######################################################################################################| Time: 0:00:01
Parsing of 2437 .bb files complete (2434 cached, 3 parsed). 3777 targets, 169 skipped, 1 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION           = "1.52.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "riscv64-oe-linux"
MACHINE              = "icicle-kit-es"
DISTRO               = "nodistro"
DISTRO_VERSION       = "nodistro.0"
TUNE_FEATURES        = "riscv64"
meta                 = "HEAD:63a235d86edb5ca628c8601ed06fb04da3186141"
meta-oe              
meta-python          
meta-multimedia      
meta-networking      = "HEAD:77718718cf0eec2c7119d101a353f343e2769b1b"
meta-riscv           = "HEAD:47faa008327abc388c52246b24a8a458b30b6f0d"
meta-polarfire-soc-yocto-bsp = "HEAD:02cb81741a5e1b37f89318d04ebc6b2854bfe736"
meta-tensorflow-lite = "HEAD:b20bc554a30933a65648ee4557ebb48aacd4db54"

Initialising tasks: 100% |####################################################################################################| Time: 0:00:05
Sstate summary: Wanted 1379 Local 0 Network 0 Missed 1379 Current 1506 (0% match, 52% complete)
NOTE: Executing Tasks
NOTE: Tasks Summary: Attempted 6955 tasks of which 4502 didn't need to be rerun and all succeeded.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 110 seconds
NOTE: Build completion summary:
NOTE:   do_populate_sysroot: 0.0% sstate reuse(0 setscene, 106 scratch)
NOTE:   do_package_qa: 0.0% sstate reuse(0 setscene, 351 scratch)
NOTE:   do_package: 0.0% sstate reuse(0 setscene, 281 scratch)
NOTE:   do_packagedata: 0.0% sstate reuse(0 setscene, 285 scratch)
NOTE:   do_package_write_ipk: 0.0% sstate reuse(0 setscene, 351 scratch)

ビルド完了!!!(実機がないのでここまで)


その他

auto.conf、site.conf


前回のブログあたりからYoctoの設定ファイルにauto.confがあることを知った。
いままではlocal.confを変更・修正だけ。
auto.confに設定すれば上書きされるので、複数のビルドとかに便利。

と、つぶやいたところ、site.confもあるということを教えていただいた。
なんと!Interface誌でYocto関連の「MyオリジナルLinuxの作り方」を連載されていたかた!!
(ありがとうございます!!)

site.confはProxyなど共通の設定を記載できるよう。
たしかにこれは便利である。

Yoctoまだまだ知らないことがありすぎる...


ビルドエラーについて


MACHINE=qemuriscv64を指定してビルドすると以下のビルドエラーが発生する。
OpenSBIのレシピがないように見えるけど、、、
今回はここまで。
$ MACHINE=qemuriscv64 bitbake mpfs-dev-cli
Loading cache: 100% |                                                                                                        | ETA:  --:--:--
Loaded 0 entries from dependency cache.
WARNING: /work/yocto-dev/openembedded-core/meta/recipes-bsp/u-boot/u-boot_2021.07.bb: Unable to get checksum for u-boot SRC_URI entry .txt: file could not be found
WARNING: /work/yocto-dev/meta-polarfire-soc-yocto-bsp/recipes-bsp/hss/hss.bb: Unable to get checksum for hss SRC_URI entry ${HSS_PAYLOAD}.yaml: file could not be found
Parsing recipes: 100% |#######################################################################################################| Time: 0:00:30
Parsing of 2437 .bb files complete (0 cached, 2437 parsed). 3777 targets, 168 skipped, 1 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
ERROR: Nothing PROVIDES 'opensbi'. Close matches:
  opensc
  openssh
  openssl
ERROR: Required build target 'mpfs-dev-cli' has no buildable providers.
Missing or unbuildable dependency chain was: ['mpfs-dev-cli', 'opensbi']

Summary: There were 2 WARNING messages shown.
Summary: There were 2 ERROR messages shown, returning a non-zero exit code.

以上!