Tensorflow-lite custom bin support: Plan B implemented
authorMyungJoo Ham <myungjoo.ham@samsung.com>
Thu, 14 Apr 2022 11:29:13 +0000 (20:29 +0900)
committerMyungJoo Ham <myungjoo.ham@samsung.com>
Fri, 10 Jun 2022 05:49:33 +0000 (14:49 +0900)
This addresses plan B of #3713

$ ldd build/ext/nnstreamer/tensor_filter/libnnstreamer_filter_tensorflow2-lite-custom.so
linux-vdso.so.1 (0x00007fffe21f2000)
libnnstreamer-single.so => /source/AutoDrv/NNStreamer/build/ext/nnstreamer/tensor_filter/../../../gst/nnstreamer/libnnstreamer-single.so (0x00007f08b5bba000)
/source/AutoDrv/NNStreamer/ext/nnstreamer/tensor_filter/libtensorflow2-lite-custom.so (0x00007f08b50a5000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f08b4ea1000)
libglib-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f08b4b8a000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f08b477d000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f08b4565000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f08b4174000)
libgmodule-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0 (0x00007f08b3f70000)
libgobject-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 (0x00007f08b3d1c000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f08b3afd000)
/lib64/ld-linux-x86-64.so.2 (0x00007f08b5ff8000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f08b388b000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f08b34ed000)
libffi.so.6 => /usr/lib/x86_64-linux-gnu/libffi.so.6 (0x00007f08b32e5000)

After this, we need the following commits.
1. a manual how to use tflite2-custom. (at /ext/nnstreamer/tensor-filter?)
2. a test case for tflite2-custom.

Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
debian/nnstreamer-tensorflow2-lite.install
ext/nnstreamer/tensor_filter/meson.build
meson_options.txt
packaging/nnstreamer.spec

index c582c19..da03364 100644 (file)
@@ -1 +1,2 @@
 /usr/lib/nnstreamer/filters/libnnstreamer_filter_tensorflow2-lite.so
+/usr/lib/nnstreamer/filters/libnnstreamer_filter_tensorflow2-lite-custom.so
index eff3f14..ecc25c0 100644 (file)
@@ -213,7 +213,7 @@ if tflite2_support_is_available
 
   nnstreamer_filter_tflite2_deps = tflite2_support_deps + [thread_dep, libdl_dep, nnstreamer_single_dep]
 
-  tflite2_compile_args = ['-DTFLITE_SUBPLUGIN_NAME="tensorflow2-lite"']
+  tflite2_compile_args = []
   tflite2_compile_args += '-DTFLITE_INT8=1'
   tflite2_compile_args += '-DTFLITE_INT16=1'
   tflite2_compile_args += '-DTFLITE_FLOAT16=1'
@@ -260,6 +260,9 @@ if tflite2_support_is_available
     tflite2_compile_args += '-DTFLITE_EXTERNAL_DELEGATE_SUPPORTED'
   endif
 
+  tflite2_custom_compile_args = tflite2_compile_args
+  tflite2_compile_args += '-DTFLITE_SUBPLUGIN_NAME="tensorflow2-lite"'
+
   tflite2_extra_dep = declare_dependency(
     compile_args : tflite2_compile_args
   )
@@ -280,6 +283,90 @@ if tflite2_support_is_available
     install: true,
     install_dir: nnstreamer_libdir
   )
+
+
+  if get_option('tflite2-custom-support').enabled() or get_option('tflite2-custom-support').auto()
+    ## Create libtensorflow2-lite-custom.so support.
+
+    ## @todo This assumes the same tflite version with the above.
+    ##       If the user has downloaded libtensorflow-lite manually, it may incur inconsistency.
+    ## @todo This does not use pkgconfig or find_library/meson-dep info
+    ##       because it does not allow querying libpath and static/shared of a dependency object.
+    ## @todo If we are allowed to use meson > 0.53, use "FS" module!
+
+    filepaths = [
+        join_paths(meson.current_source_dir(), 'libtensorflow2-lite.so',),
+        join_paths(meson.current_build_dir(), 'libtensorflow2-lite.so',),
+        join_paths(nnstreamer_libdir, 'libtensorflow2-lite.so'),
+        '/usr/lib/libtensorflow2-lite.so',
+        '/usr/lib64/libtensorflow2-lite.so',
+        './libtensorflow2-lite.so',
+    ]
+    filepath = ''
+    foreach file : filepaths
+      if run_command('bash', '-c', '[ -f "' + file + '" ]').returncode() == 0
+        message('Found: ' + file)
+        filepath = file
+        configure_file (
+          input: file,
+          output: 'libtensorflow2-lite-custom.so',
+          copy: true
+        )
+        break
+      endif
+    endforeach
+
+    if filepath == ''
+      ## No shared tfl lib found. Get static lib and convert it
+
+      filepaths = [join_paths(nnstreamer_libdir, 'libtensorflow2-lite.a'),
+          '/usr/lib/libtensorflow2-lite.a',
+          '/usr/lib64/libtensorflow2-lite.a',
+          './libtensorflow2-lite.a',
+          join_paths(meson.current_build_dir(), 'libtensorflow2-lite.a',),
+          join_paths(meson.current_source_dir(), 'libtensorflow2-lite.a',)]
+
+      foreach file : filepaths
+        if run_command('bash', '-c', '[ -f "'+ file + '" ]').returncode() == 0
+          somake = run_command('gcc', '-shared', '-o', 'libtensorflow2-lite-custom.so', '-Wl,--whole-archive', file, '-Wl,--no-whole-archive')
+          if somake.returncode() == 0
+            message('Successfully created libtensorflow2-lite-custom.so from archive: ' + file)
+            configure_file (
+              input: join_paths(meson.current_source_dir(), 'libtensorflow2-lite-custom.so'),
+              output: 'libtensorflow2-lite-custom.so',
+              copy: true
+            )
+            filepath = file
+            break
+          else
+            error('Cannot create .so from: ' + file)
+          endif
+        endif
+      endforeach
+    endif
+
+    if filepath != ''
+      tflite2_custom_compile_args += '-DTFLITE_SUBPLUGIN_NAME="tensorflow2-lite-custom"'
+      tflite2_custom_extra_dep = declare_dependency( compile_args : tflite2_custom_compile_args )
+      tflc_dep = declare_dependency (
+        link_args: ['-L' + meson.current_build_dir(), '-ltensorflow2-lite-custom']
+      )
+      shared_library('nnstreamer_filter_tensorflow2-lite-custom',
+        nnstreamer_filter_tflite2_sources,
+        dependencies: [tflc_dep, thread_dep, libdl_dep, nnstreamer_single_dep, tflite2_ver_dep, tflite2_custom_extra_dep],
+        install: true,
+        install_dir:filter_subplugin_install_dir
+      )
+    else # no custom mode built
+      if get_option('tflite2-custom-support').enabled()
+        error('Cannot create tflite2-custom tensor-filter subplugin. No valid .so/.a of tensorflow2-lite found.')
+      endif
+    endif
+  endif
+else # no tflite2
+  if get_option('tflite2-custom-support').enabled()
+    error('tflite2-custom-support requires tflite2-support')
+  endif
 endif
 
 if pytorch_support_is_available
index 8ca7f8b..ec1356e 100644 (file)
@@ -4,6 +4,7 @@ option('audio-support', type: 'feature', value: 'enabled')
 option('tf-support', type: 'feature', value: 'auto')
 option('tflite-support', type: 'feature', value: 'auto')
 option('tflite2-support', type: 'feature', value: 'auto')
+option('tflite2-custom-support', type: 'feature', value: 'auto') # requires tflite2-support!
 option('pytorch-support', type: 'feature', value: 'auto')
 option('caffe2-support', type: 'feature', value: 'auto')
 option('deepview-rt-support', type: 'feature', value: 'auto')
index 4c4b1f8..2b3bd19 100644 (file)
@@ -701,9 +701,9 @@ Provides additional gstreamer plugins for nnstreamer pipelines
 
 # Support tensorflow2-lite
 %if 0%{?tensorflow2_lite_support}
-%define enable_tf2_lite -Dtflite2-support=enabled
+%define enable_tf2_lite -Dtflite2-support=enabled -Dtflite2-custom-support=enabled
 %else
-%define enable_tf2_lite -Dtflite2-support=disabled
+%define enable_tf2_lite -Dtflite2-support=disabled -Dtflite2-custom-support=disabled
 %endif
 
 # Support pytorch
@@ -980,6 +980,7 @@ cp -r result %{buildroot}%{_datadir}/nnstreamer/unittest/
 %manifest nnstreamer.manifest
 %defattr(-,root,root,-)
 %{_prefix}/lib/nnstreamer/filters/libnnstreamer_filter_tensorflow2-lite.so
+%{_prefix}/lib/nnstreamer/filters/libnnstreamer_filter_tensorflow2-lite-custom.so
 %endif
 
 %if 0%{?python3_support}