CoralのEdge TPU USB AcceleratorをROCK64で動かす

# 概要
GoogleのEdge TPUのUSB版、[Edge TPU USB Accelerator](https://coral.withgoogle.com/products/accelerator)を[ROCK64(RAM 1GBモデル)](http://akizukidenshi.com/catalog/g/gM-12380/)に接続して、デモを動作させた。

2019年4月12日のアップデートにより、64bit ARMデバイスでの動作が可能になったが、公式のインストールドキュメントの手順に加えて、ライブラリのコピーが必要だった。


# セットアップ
まずは公式ドキュメントの通りにセットアップする。

```
wget https://dl.google.com/coral/edgetpu_api/edgetpu_api_latest.tar.gz -O edgetpu_api.tar.gz --trust-server-names
tar xzf edgetpu_api.tar.gz
cd edgetpu_api
bash ./install.sh
```

セットアップは普通にできるが、このままだと下記のようなエラーが出てデモが実行できない。

```
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/edgetpu/swig/edgetpu_cpp_wrapper.py", line 18, in swig_import_helper
    fp, pathname, description = imp.find_module('_edgetpu_cpp_wrapper', [dirname(__file__)])
  File "/usr/lib/python3.6/imp.py", line 297, in find_module
    raise ImportError(_ERR_MSG.format(name), name=name)
ImportError: No module named '_edgetpu_cpp_wrapper'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "classify_image.py", line 19, in <module>
    from edgetpu.classification.engine import ClassificationEngine
  File "/usr/local/lib/python3.6/dist-packages/edgetpu/classification/engine.py", line 17, in <module>
    from edgetpu.basic.basic_engine import BasicEngine
  File "/usr/local/lib/python3.6/dist-packages/edgetpu/basic/basic_engine.py", line 15, in <module>
    from edgetpu.swig.edgetpu_cpp_wrapper import BasicEngine
  File "/usr/local/lib/python3.6/dist-packages/edgetpu/swig/edgetpu_cpp_wrapper.py", line 28, in <module>
    _edgetpu_cpp_wrapper = swig_import_helper()
  File "/usr/local/lib/python3.6/dist-packages/edgetpu/swig/edgetpu_cpp_wrapper.py", line 20, in swig_import_helper
    import _edgetpu_cpp_wrapper
ModuleNotFoundError: No module named '_edgetpu_cpp_wrapper'
```

どうやら、install.shが`_edgetpu_cpp_wrapper.so`のファイル名を正しく設定してくれないらしい。
手動でファイル名を変更してコピーしておく

```
$ cd /usr/local/lib/python3.6/dist-packages/edgetpu/swig/
$ sudo cp _edgetpu_cpp_wrapper.cpython-35m-aarch64-linux-gnu.so _edgetpu_cpp_wrapper.so
```

# デモ実行
まずは必要なサンプルファイルをダウンロード。
鳥を分類するサンプルらしい。

```
$ cd ~/Downloads/
$ wget https://storage.googleapis.com/cloud-iot-edge-pretrained-models/canned_models/mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite \
http://storage.googleapis.com/cloud-iot-edge-pretrained-models/canned_models/inat_bird_labels.txt \
https://coral.withgoogle.com/static/images/parrot.jpg
```

公式ドキュメントを参考に、デモ実行

```
$ python3 /usr/local/lib/python3.6/dist-packages/edgetpu/demo/classify_image.py --model ~/Downloads/mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite --label ~/Downloads/inat_bird_labels.txt --image ~/Downloads/parrot.jpg
W0412 13:02:03.809260   16731 package_registry.cc:65] Minimum runtime version required by package (5) is lower than expected (10).
---------------------------
Ara macao (Scarlet Macaw)
Score :  0.761719
```

なんかWarningが出たけど、動作した。

# 所感

最初に公開されたインストールスクリプトではラズパイのみを想定したスクリプトになっていて、aarch64用のライブラリもなかったため試行錯誤していたが、ライブラリコピーだけでできた。
USB3.0が載っているシングルボードコンピュータは基本的にaarch64環境なので、これで通信のボトルネックが解消しそう。

試しに、デモスクリプトに処理時間計測を追加し、ROCK64のUSB2.0ポートまたはUSB3.0ポートにTPUを繋いで実行してみた。

||USB2.0|USB3.0|
|:-:|:-:|:-:|
|処理時間|約160msec|約28msec|

ということで、ラズパイではやっぱり通信がボトルネックになっていたっぽい。