TensorFlow Lite の事前調査その 1(各種 MCU コンパイラの C++ の対応状況)

投稿者: | 2019年6月19日

Preliminarily surveying TensorFlow Lite for Microcontrollers (still experimental) not to become Urashima-Taro.

とある事情で、TensorFlow Lite for MCU(まだ experimental らしいです)の勉強をしています。私は基本的にマイコン屋ですし、しかし AI(機械学習)の分野から置いてきぼりを食いたくないですからね。

TensorFlow Lite for MCU(長いなぁ)のサイトを見ていると、いろんなマイコンに TensorFlow モデル(Keras モデルも可らしい)をポーティングするお話が出ています。まだまだ experimental らしく情報が荒削りですが、それでも必要十分な情報に思えます。Make をガリガリ使ってプロジェクトを生成する makefile を読むと頭が痛くなりますが、それはさておき。

こちらの説明を読んでいくと、マイコン上で動かす上での一番のネックになりそうなのが、コンパイラが C++11 に対応していないといけない、というところのようです。私は C++ には詳しくないので(組込系の仕事では、必要性が薄かった。言い訳終わり)、ISO C++ の標準(C++98, C++11 等)の相違はチンプンカンプンです。再度「説明」を読むと、

We only use a small, sane, subset of C++ though, so don’t worry about having to deal with template metaprogramming or similar challenges!

とかありますが、既にメゲています。

昔の話をしようよ(TL; DR)

ちなみに、ISO C++ 標準の変遷についてはこちらが詳しいです。私が学生時代に C++ を囓ったのが、せいぜい 1993年頃。ISO C++ の標準委員会が設立(?)されて間もない頃のようですね。本棚を覗いたら、こんなのが出てきました。

本当は古い訳書(ANSI 前?)も持っていたのですが、ANSI C++(ISO C++)に付いていこうという小さな意志があって、買ったものと思われます。しかし…、ほとんど読んだ形跡がありません。

続いてこれ。真ん中の本です。この本だけ引き抜くと本の山が崩れそうだったので(以下略)

どうやら諦めずに、C++11 を猛追しようという無謀な気持ちも少しはあったようです。

でも、この本の厚さを見てください。。。本職で C++ を使おうという人以外、全貌を理解するのは無理じゃないですか?(← 初めから諦めてる。) 若い頃、K&R と ANSI 後の K&R を読み、C99 くらいまではなんとかついて行けてますが、それでも intermingled declarations and code(コードの好きなところで変数宣言できるやつ)を見ると、未だにオジサン(私のこと)イラっとします。

最近はもっぱら Python に傾倒していますが、最初の Python 1.5 の頃は良かったのですが、2.x で置いてかれかけて、3.x はもはや浦島太郎です。(そんなのがプログラマするなって?)

話戻して

何が言いたいかというと、できるだけ若い頃にプログラミング言語の仕様を頭に叩き込んでおきましょう、という話ではなく、私が得意としているプロセッサで TensorFlow Lite が動きますかね?  という話です。

私が社会に出て、一番長く付き合ったのが Texas Instruments の C6000 という Digital Signal Processor(DSP)です。DSP は、信号処理を高速に実現するのが一番の目的だったので、C 言語が使えたとしても、標準 C と違う部分が多かったりしたものです。(なんか、昔話から抜けられなくなっている。) 最近はなくなりましたが、未だに「C6000 は long 型が 40ビットとか変態的な仕様なので嫌だ」とおっしゃる方もあります。(EABI データ型を使えば 32ビットになるので心配御無用。)

話を戻します。C6000 のコンパイラというと、今でも 7.4.x 系を使っていらっしゃる方が多いのではないかと思います。何を隠そう、私もそうです。実はこのバージョンのコンパイラは C++11 をサポートしていないんです。

という訳で、私は C6000 で TensorFlow Lite を使うの諦めました、、、と言えれば簡単で良いのですが、実は問題は複雑でした。なんと、最新のバージョン 8.3.x では、C++14 までサポートされているんだそうです。でも実際問題として、既に 7.4.x 系で実装してしまったお客様プロジェクトを 8.3.x 系に移行させるのはリスキーなので、ま、やめておきましょうか。とこれだけでは「ここまで読ませておいて、なんやねん!」と叱られそうなので、私の調べて範囲で、各種コンパイラの C++ 標準対応状況をまとめておきましょう。

C6000 コンパイラ編

まとめます。

  • 7.4.x 系: 基本的に C++98 のようです。ただし、いろいろと制限があるようなので、C++98 のサブセットとお考えください。詳しくは、SPRU187 の 6.2節 Characteristics of TMS320C6000 C++ を御参照ください。
  • 8.1.x 系: 分かりません。調べてません、ごめんなさい。
  • 8.2.x 系: C++03 のようです。
  • 8.3.x 系: ようやく C++14 になりました!

という訳で、新しい C++ を使いたい方(DSP では少数派なんですけどね)は、8.3.x 系がよろしいようです。

GCC コンパイラ編

前述までの内容だけだと、お客様に見せる顔がありませんので、「まあ、最近は STM32 も ESP32 もありますから、そっちはどうですか?」と言えるよう、ちょっと調べてみました。

まず STMicroelectronics 社の STM32 マイコンですが、私の好きな開発ツールは Ac6 System Workbench OpenSTM32 というものです。最新の v2.9 を調べてみましたが、同梱のコンパイラは GCC 7.2.1 20170904 のようでした。ここのサイトを見ると、C++14 は大丈夫そう、C++17 もおそらくカバーできているようです。

しかしまた話題が逸れますが、C++ っていつまで仕様変更が続くのでしょう。ま、同じことは Python にも言えますが。。。Python なんて、同じ 3.x なのに、3.5, 3.6, 3.7 と、どんどん言語仕様が追加されていくので、もはや付いていけません。(もう、細かいところ弄らないで〜)

閑話休題。次に、最近話題の Espressif ESP32 です。Tensilica Xtensa コアを 2つ搭載した Wi-Fi 内蔵マイコンで、試作に便利なんですよね。Arduino 環境もありますし、MicroPython も動きますし、製品化の暁には、もちろんネイティブの開発環境を使うこともできます。

いま、手元の Arduino for ESP32(1.0.0)を調べたら、同梱のコンパイラは GCC 5.2.0 のようです。こいつも、C++14 なら大丈夫そうです。なお、最新の Arduino for ESP32 は 1.0.2 だそうですので、状況は変わっているかもです。

という訳で、STM32 か ESP32 で、TensorFlow Lite の評価を続けようと思います!  今日、言いたかったのはそこです! (ちなみに、STM32 は TensorFlow Lite で正式(?)にサポートされているぽいので、心配はなさそうですね。)

ところで X-CUBE-AI って何?

ここでブログを終わらせようと思ったのですが、こんなの見つけました。

熱い、この分野はホットすぎます!!  今度、これも覗いてみたいと思います。

今日はここまで。