I am a bit unhappy with the current approach how the backend implementations are handles in MCUonMCU.
Some examples:
The TFLMCBackend backend is only a wrapper around the previously installed tflmc dependency (invoked in a subprocess) Multiple versions of the tool can easily used pointing the tflmc.exe property to the according path.
tflmi wrapper-generation utils on the other side are written in Python and just called from within the TFLMIBackend. As the wrappers are generated without any external dependency this works out great like it is
The TVM backends are quite different. All of them are written in Python code which heavily depends on the tvm python lib of a specific TVM installation. The required version of TVM stored in the property tvm.src_dir might change during the MLonMCU flow which can not be handle properly by Python.
For the last problem there exist multiple solutions:
Use multiprocessing.Process() to invoke the TVM backends in a new process which can use a different PYTHONPATH. The two main issues of this approach are:
Inconsistency between frameworks: While on the TFLM side, this should not be required, both frameworks should be handled in a similar way. We could simply use the same approach on the TFLM side, but this would result in more nested processed (as tflmc internally calls tflite_micro_compiler)
Logging module is not multiprocessing-safe -> unable to properly control (mute, redirect) stdout of backend implementation
Like 1. But using subprocess.Popen instead -> allows to decouple backend-stdout from rest of MLonMCU
Only implement the wrapper generation (without TVM dependencies) in the Backend itself an define the actual script somewhere else (like other dependencies)
Preferable approach because isolation on the same level as on TFLM backends
Reuse TVMC command line utility? -> How to integrate custom features (See Issue #9)
Should we create a new repository for TVM-specific features or Include them in TVM codebase? (In my opinion they do not belong to mlonmcu/flow/tvm as the are useful without mlonmcu -> Make them an external dependency instead)
I am a bit unhappy with the current approach how the backend implementations are handles in MCUonMCU.
Some examples:
TFLMCBackend
backend is only a wrapper around the previously installedtflmc
dependency (invoked in a subprocess) Multiple versions of the tool can easily used pointing thetflmc.exe
property to the according path.tflmi
wrapper-generation utils on the other side are written in Python and just called from within theTFLMIBackend
. As the wrappers are generated without any external dependency this works out great like it istvm
python lib of a specific TVM installation. The required version of TVM stored in the propertytvm.src_dir
might change during the MLonMCU flow which can not be handle properly by Python.For the last problem there exist multiple solutions:
multiprocessing.Process()
to invoke the TVM backends in a new process which can use a differentPYTHONPATH
. The two main issues of this approach are:tflmc
internally callstflite_micro_compiler
)using subprocess.Popen
instead -> allows to decouple backend-stdout from rest of MLonMCUmlonmcu/flow/tvm
as the are useful withoutmlonmcu
-> Make them an external dependency instead)