NXPチームの皆様、こんにちは。
私はMCXN947のためにTensorFlow Lite MicroモデルをMCUXpressoプロジェクトに統合しています。私のアプリケーションはCで書かれていますが、TensorFlow LiteのMicro推論コードと生成モデルはC++で書かれています。
C言語とC++のソースファイルを結合する際に、コンパイルとリンクに関する問題が発生しています。既に「extern C」を試してみましたが、問題は解決しません。
以下の点についてアドバイスいただけますか?
MCUXpressoプロジェクトでC言語とC++のソースファイルを混在させることは推奨されますか?
C++ TensorFlow Lite MicroモデルをCベースのアプリケーションに統合する際の推奨されるアプローチは何ですか?
この統合に必要なコンパイラ/リンカの設定や参考例はありますか?
何かご助言いただければ大変ありがたいです。ありがとう。
こんにちは、 @sivamankomb さん、
投稿ありがとうございます。
もちろん、MCUXpressoプロジェクトではCとC++のソースファイルを混ぜることも可能です。実際、これは私たちのSDKデモでも使われているアプローチです。参考までに、SDKに含まれるいくつかのeIQ関連の例プロジェクトを確認できます。SDKはSelect Board |MCUXpresso SDK Builder。
Celeste_Liu_0-1784012914332.png
要点は以下のとおりです。
- .cファイルはC言語コードとしてコンパイルされます。
- .cppファイルはC++コードとしてコンパイルされます。
- 最終リンクステージでは、C++ランタイムおよびC++シンボル解決をサポートするツールチェーンを使用しなければなりません。
- Cコードは外部の「C」ラッパーを通じて公開された関数のみを呼び出し、TFLM C++のクラス、テンプレート、名前空間を直接含めたり使用したりしてはいけません。
したがって、推奨されるアプローチは、TFLM推論の実装を.cppファイルにカプセル化することです。ファイルを作成し、C アプリケーションに対しては C ABI 互換のラッパーインターフェースのみを公開します。
例えば、SDKのtflm_label_imageデモでは、コアとなるTFLM推論ロジックがcommon/tflm/model.cppで実装されています。このファイルはTFLM C++ APIを使用します。
#include "tensorflow/lite/micro/micro_interpreter.h"
#include "tensorflow/lite/micro/micro_op_resolver.h"
static const tflite::Model* s_model = nullptr;
static tflite::MicroInterpreter* s_interpreter = nullptr;
extern tflite::MicroOpResolver &MODEL_GetOpsResolver();
次に、tflite::MicroInterpreter インスタンスを作成し、MODEL_Init() 内で AllocateTensors() を呼び出して初期化を実行します。
外部に露出したモデル.h、Cに優しいインターフェースを提供します。
#if defined(__cplusplus)
extern "C" {
#endif
status_t MODEL_Init(void);
uint8_t* MODEL_GetInputTensorData(tensor_dims_t* dims, tensor_type_t* type);
uint8_t* MODEL_GetOutputTensorData(tensor_dims_t* dims, tensor_type_t* type);
void MODEL_ConvertInput(uint8_t* data, tensor_dims_t* dims, tensor_type_t type);
status_t MODEL_RunInference(void);
const char* MODEL_GetModelName(void);
#if defined(__cplusplus)
}
#endif
関数宣言は外部「C」を通じてエクスポートされるため、Cのソースファイルは単に「model.h」#include できます。また、tflite::MicroInterpreterやMicroMutableOpResolverのようなC++型の知識を必要とせずに、MODEL_Init()やMODEL_RunInference()などの関数を呼び出すことができます。
このアーキテクチャは当社のSDK例でも採用されており、CベースのアプリケーションにTFLMを統合する際に一般的に推奨されます。なぜなら、C++の実装の詳細をクリーンに分離しつつ、アプリケーション層の純粋なCインターフェースを保持できるからです。
顧客のMLモデルをSDKデモに統合したい場合は、AN14241を参照してください。
お役に立てば幸いです。
BR
セレステ