diff --git a/meta-digi-arm/conf/machine/include/imx-digi-base.inc b/meta-digi-arm/conf/machine/include/imx-digi-base.inc index 660d384bf..af2830ce1 100644 --- a/meta-digi-arm/conf/machine/include/imx-digi-base.inc +++ b/meta-digi-arm/conf/machine/include/imx-digi-base.inc @@ -358,6 +358,19 @@ OPTEE_PKGS ??= "optee-client optee-os" PREFERRED_VERSION_opencv:mx8-nxp-bsp ??= "4.10.0.imx" PREFERRED_VERSION_opencv:mx9-nxp-bsp ??= "4.10.0.imx" +# ML on ccimx95 (backport from NXP's lf-6.12.49-2.2.0) +PREFERRED_VERSION_flatbuffers-native:mx95-nxp-bsp ??= "24.3.25" +PREFERRED_VERSION_flatbuffers:mx95-nxp-bsp ??= "24.3.25" +PREFERRED_VERSION_neutron:mx95-nxp-bsp ??= "2.2.1" +PREFERRED_VERSION_nnstreamer-edge:mx95-nxp-bsp ??= "0.2.6" +PREFERRED_VERSION_nnstreamer:mx95-nxp-bsp ??= "2.4.2" +PREFERRED_VERSION_onnxruntime:mx95-nxp-bsp ??= "1.22.0" +PREFERRED_VERSION_python3-flatbuffers:mx95-nxp-bsp ??= "24.3.25" +PREFERRED_VERSION_tensorflow-lite-host-tools-native:mx95-nxp-bsp ??= "2.19.0" +PREFERRED_VERSION_tensorflow-lite-host-tools:mx95-nxp-bsp ??= "2.19.0" +PREFERRED_VERSION_tensorflow-lite-neutron-delegate:mx95-nxp-bsp ??= "2.19.0" +PREFERRED_VERSION_tensorflow-lite:mx95-nxp-bsp ??= "2.19.0" + EXTRA_IMAGEDEPENDS += "u-boot" # Do not update fstab file when using wic images diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-devtools/flatbuffers/files/0001-Fixes-LICENSE-file-in-python.patch b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-devtools/flatbuffers/files/0001-Fixes-LICENSE-file-in-python.patch new file mode 100644 index 000000000..1ba7bf3d6 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-devtools/flatbuffers/files/0001-Fixes-LICENSE-file-in-python.patch @@ -0,0 +1,39 @@ +From 6cb4d671a88e054744ce3029df9e733dc724ee76 Mon Sep 17 00:00:00 2001 +From: Derek Bailey +Date: Mon, 19 Aug 2024 16:08:46 -0700 +Subject: [PATCH] Fixes LICENSE file in python + +Fixes: #8376 +Upstream-Status: Backport [https://github.com/google/flatbuffers/commit/6cb4d671a88e054744ce3029df9e733dc724ee76] +--- + python/setup.cfg | 2 +- + python/setup.py | 1 - + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/python/setup.cfg b/python/setup.cfg +index e3647037..0c43b1cf 100644 +--- a/python/setup.cfg ++++ b/python/setup.cfg +@@ -3,4 +3,4 @@ universal=1 + + [metadata] + license_files = +- ../license +\ No newline at end of file ++ ../LICENSE +\ No newline at end of file +diff --git a/python/setup.py b/python/setup.py +index 065b2754..21ddecb9 100644 +--- a/python/setup.py ++++ b/python/setup.py +@@ -18,7 +18,6 @@ setup( + name='flatbuffers', + version='24.3.25', + license='Apache 2.0', +- license_files='../LICENSE', + author='Derek Bailey', + author_email='derekbailey@google.com', + url='https://google.github.io/flatbuffers/', +-- +2.34.1 + diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-devtools/flatbuffers/files/flatbuffers.pc.in b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-devtools/flatbuffers/files/flatbuffers.pc.in new file mode 100644 index 000000000..3a0666c3e --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-devtools/flatbuffers/files/flatbuffers.pc.in @@ -0,0 +1,7 @@ +Name: flatbuffers +Description: memory efficient serialization library +Version: @version@ +Requires: +Libs: -L@libdir@ -lflatbuffers +Cflags: -I@includedir@ + diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-devtools/flatbuffers/flatbuffers_24.%.bbappend b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-devtools/flatbuffers/flatbuffers_24.%.bbappend new file mode 100644 index 000000000..30fbb24f1 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-devtools/flatbuffers/flatbuffers_24.%.bbappend @@ -0,0 +1,10 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" + +SRC_URI:append = " file://flatbuffers.pc.in" + +do_install:append() { + install -D -m 0644 ${WORKDIR}/flatbuffers.pc.in ${D}${libdir}/pkgconfig/flatbuffers.pc + sed -i 's:@version@:${PV}:g + s:@libdir@:${libdir}:g + s:@includedir@:${includedir}:g' ${D}${libdir}/pkgconfig/flatbuffers.pc +} diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-devtools/flatbuffers/flatbuffers_24.3.25.bb b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-devtools/flatbuffers/flatbuffers_24.3.25.bb new file mode 100644 index 000000000..71bfd6d56 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-devtools/flatbuffers/flatbuffers_24.3.25.bb @@ -0,0 +1,34 @@ +SUMMARY = "Memory Efficient Serialization Library" +HOMEPAGE = "https://github.com/google/flatbuffers" +SECTION = "console/tools" +LICENSE = "Apache-2.0" + +PACKAGE_BEFORE_PN = "${PN}-compiler" +DEPENDS = "flatbuffers-native" + +RDEPENDS:${PN}-compiler = "${PN}" +RDEPENDS:${PN}-${PYTHON_PN} = "${PN}" +RDEPENDS:${PN}-dev += "${PN}-compiler" + +LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +SRCREV = "e6463926479bd6b330cbcf673f7e917803fd5831" + +SRC_URI = "git://github.com/google/flatbuffers.git;branch=master;protocol=https" + +CVE_CHECK_IGNORE += "CVE-2020-35864" + +EXTRA_OECMAKE += "\ + -DFLATBUFFERS_BUILD_TESTS=OFF \ + -DFLATBUFFERS_BUILD_SHAREDLIB=ON \ +" + +EXTRA_OECMAKE:append:class-target = " -DFLATBUFFERS_FLATC_EXECUTABLE=${STAGING_BINDIR_NATIVE}/flatc" + +inherit cmake python3native + +S = "${WORKDIR}/git" + +FILES:${PN}-compiler = "${bindir}" + +BBCLASSEXTEND = "native nativesdk" diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-devtools/flatbuffers/python3-flatbuffers_24.3.25.bb b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-devtools/flatbuffers/python3-flatbuffers_24.3.25.bb new file mode 100644 index 000000000..f8c8c8256 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-devtools/flatbuffers/python3-flatbuffers_24.3.25.bb @@ -0,0 +1,16 @@ +SUMMARY = "Memory Efficient Serialization Library - Python3 Modules" +HOMEPAGE = "https://github.com/google/flatbuffers" +SECTION = "console/tools" +LICENSE = "Apache-2.0" + +LIC_FILES_CHKSUM = "file://../LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +SRCREV = "e6463926479bd6b330cbcf673f7e917803fd5831" +SRC_URI = "git://github.com/google/flatbuffers.git;branch=master;protocol=https \ + file://0001-Fixes-LICENSE-file-in-python.patch" +S = "${WORKDIR}/git/python" + +RDEPENDS:${PN} = "flatbuffers" +PATCHTOOL = "git" + +inherit setuptools3 diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/neutron/neutron_2.2.1.bb b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/neutron/neutron_2.2.1.bb new file mode 100644 index 000000000..f075599e8 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/neutron/neutron_2.2.1.bb @@ -0,0 +1,8 @@ +require recipes-libraries/neutron/neutron_1.0.0.bb + +LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=bc649096ad3928ec06a8713b8d787eac" + +SRC_URI = "${NEUTRON_SRC};branch=${SRCBRANCH}" +NEUTRON_SRC ?= "git://github.com/nxp-imx/neutron.git;protocol=https" +SRCBRANCH = "lf-6.12.49_2.2.0" +SRCREV = "a7d5f17a9210c45aef2bbc9dc09d637f41fd3a7c" diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/onnxruntime/onnxruntime_%.bbappend b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/onnxruntime/onnxruntime_1.17.%.bbappend similarity index 100% rename from meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/onnxruntime/onnxruntime_%.bbappend rename to meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/onnxruntime/onnxruntime_1.17.%.bbappend diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/onnxruntime/onnxruntime_1.22.0.bb b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/onnxruntime/onnxruntime_1.22.0.bb new file mode 100644 index 000000000..2e6eb4a43 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/onnxruntime/onnxruntime_1.22.0.bb @@ -0,0 +1,203 @@ +# Copyright 2020-2025 NXP +DESCRIPTION = "cross-platform, high performance scoring engine for ML models" +SECTION = "devel" +LICENSE = "MIT & Apache-2.0" +LIC_FILES_CHKSUM_runtime = "file://LICENSE;md5=0f7e3b1308cb5c00b372a6e78835732d" +LIC_FILES_CHKSUM_model = "file://${S}/example-models/squeezenet/LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" +LIC_FILES_CHKSUM = "${LIC_FILES_CHKSUM_runtime} ${LIC_FILES_CHKSUM_model}" + +DEPENDS = "libpng zlib" + +inherit setuptools3 + +SRC_URI = "${ONNXRUNTIME_SRC};branch=${SRCBRANCH}" +ONNXRUNTIME_SRC ?= "gitsm://github.com/nxp-imx/onnxruntime-imx.git;protocol=https" +SRCBRANCH = "lf-6.12.49_2.2.0" +SRCREV = "2ef0bb77e4b886c1d075b2bbc4ce0dc5b60c268b" + +S = "${WORKDIR}/git" + +inherit cmake python3native + +OECMAKE_SOURCEPATH = "${S}/cmake" +OECMAKE_GENERATOR = "Unix Makefiles" + +# Notes: +# Abseil: +# - FETCHCONTENT_FULLY_DISCONNECTED=OFF and do_configure:prepend() added to allow +# abseil build process (the issue was related to CMake not fetching sources) + +EXTRA_OECMAKE += "\ + -DFETCHCONTENT_FULLY_DISCONNECTED=OFF \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -Donnxruntime_BUILD_UNIT_TESTS=ON \ + -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ +" + +PYTHON_DEPENDS = "\ + ${PYTHON_PN} \ + ${PYTHON_PN}-pip-native \ + ${PYTHON_PN}-numpy \ + ${PYTHON_PN}-numpy-native \ + ${PYTHON_PN}-packaging-native\ + ${PYTHON_PN}-pybind11\ + ${PYTHON_PN}-pybind11-native\ +" + +PYTHON_RDEPENDS = "\ + ${PYTHON_PN} \ + ${PYTHON_PN}-numpy \ + ${PYTHON_PN}-protobuf \ + ${PYTHON_PN}-coloredlogs \ + ${PYTHON_PN}-flatbuffers \ + ${PYTHON_PN}-sympy \ +" + +PACKAGECONFIG ?= "crosscompiling sharedlib python kleidiai ${PACKAGECONFIG_NPU}" +PACKAGECONFIG_NPU = "" +PACKAGECONFIG_NPU:mx95-nxp-bsp = "neutron" +PACKAGECONFIG_NPU:mx943-nxp-bsp = "neutron" +PACKAGECONFIG_NPU:mx8-nxp-bsp:imxgpu = "vsinpu" +PACKAGECONFIG_NPU:mx8mm-nxp-bsp = "" + +PACKAGECONFIG[nsync] = "-Donnxruntime_USE_NSYNC=ON, -Donnxruntime_USE_NSYNC=OFF" +PACKAGECONFIG[prebuilt] = "-Donnxruntime_USE_PREBUILT_PB=ON, -Donnxruntime_USE_PREBUILT_PB=OFF" +PACKAGECONFIG[openmp] = "-Donnxruntime_USE_OPENMP=ON, -Donnxruntime_USE_OPENMP=OFF" +PACKAGECONFIG[trt] = "-Donnxruntime_USE_TRT=ON, -Donnxruntime_USE_TRT=OFF" +PACKAGECONFIG[nuphar] = "-Donnxruntime_USE_NUPHAR=ON, -Donnxruntime_USE_NUPHAR=OFF" +PACKAGECONFIG[brainslice] = "-Donnxruntime_USE_BRAINSLICE=ON, -Donnxruntime_USE_BRAINSLICE=OFF" +PACKAGECONFIG[python] = "-Donnxruntime_ENABLE_PYTHON=ON, -Donnxruntime_ENABLE_PYTHON=OFF, ${PYTHON_DEPENDS}, ${PYTHON_RDEPENDS}" +PACKAGECONFIG[sharedlib] = "-Donnxruntime_BUILD_SHARED_LIB=ON, -Donnxruntime_BUILD_SHARED_LIB=OFF" +PACKAGECONFIG[eigenblas] = "-Donnxruntime_USE_EIGEN_FOR_BLAS=ON, -Donnxruntime_USE_EIGEN_FOR_BLAS=OFF" +PACKAGECONFIG[openblas] = "-Donnxruntime_USE_OPENBLAS=ON, -Donnxruntime_USE_OPENBLAS=OFF" +PACKAGECONFIG[dnnl] = "-Donnxruntime_USE_DNNL=ON, -Donnxruntime_USE_DNNL=OFF" +PACKAGECONFIG[mklml] = "-Donnxruntime_USE_MKLML=ON, -Donnxruntime_USE_MKLML=OFF" +PACKAGECONFIG[gemmlowp] = "-Donnxruntime_USE_GEMMLOWP=ON, -Donnxruntime_USE_GEMMLOWP=OFF" +PACKAGECONFIG[ngraph] = "-Donnxruntime_USE_NGRAPH=ON, -Donnxruntime_USE_NGRAPH=OFF" +PACKAGECONFIG[openvino] = "-Donnxruntime_USE_OPENVINO=ON, -Donnxruntime_USE_OPENVINO=OFF" +PACKAGECONFIG[interop] = "-Donnxruntime_ENABLE_LANGUAGE_INTEROP_OPS=ON, -Donnxruntime_ENABLE_LANGUAGE_INTEROP_OPS=OFF" +PACKAGECONFIG[dml] = "-Donnxruntime_USE_DML=ON, -Donnxruntime_USE_DML=OFF" +PACKAGECONFIG[telemetry] = "-Donnxruntime_USE_TELEMETRY=ON, -Donnxruntime_USE_TELEMETRY=OFF" +PACKAGECONFIG[armnn-relu] = "-Donnxruntime_ARMNN_RELU_USE_CPU=ON, -Donnxruntime_ARMNN_RELU_USE_CPU=OFF" +PACKAGECONFIG[armnn-bn] = "-Donnxruntime_ARMNN_BN_USE_CPU=ON, -Donnxruntime_ARMNN_BN_USE_CPU=OFF" +PACKAGECONFIG[opschema] = "-Donnxruntime_PYBIND_EXPORT_OPSCHEMA=ON, -Donnxruntime_PYBIND_EXPORT_OPSCHEMA=OFF" +PACKAGECONFIG[nnapi] = "-Donnxruntime_USE_NNAPI_BUILTIN=ON, -Donnxruntime_USE_NNAPI_BUILTIN=OFF" +PACKAGECONFIG[tvm] = "-Donnxruntime_USE_TVM=ON, -Donnxruntime_USE_TVM=OFF" +PACKAGECONFIG[llvm] = "-Donnxruntime_USE_LLVM=ON, -Donnxruntime_USE_LLVM=OFF" +PACKAGECONFIG[microsoft] = "-Donnxruntime_ENABLE_MICROSOFT_INTERNAL=ON, -Donnxruntime_ENABLE_MICROSOFT_INTERNAL=OFF" +PACKAGECONFIG[eigenthreadpool] = "-Donnxruntime_USE_EIGEN_THREADPOOL=ON, -Donnxruntime_USE_EIGEN_THREADPOOL=OFF" +PACKAGECONFIG[tensorrt] = "-Donnxruntime_USE_TENSORRT=ON, -Donnxruntime_USE_TENSORRT=OFF" +PACKAGECONFIG[crosscompiling] = "-Donnxruntime_CROSS_COMPILING=ON, -Donnxruntime_CROSS_COMPILING=OFF " +PACKAGECONFIG[server] = "-Donnxruntime_BUILD_SERVER=ON, -Donnxruntime_BUILD_SERVER=OFF" +PACKAGECONFIG[x86] = "-Donnxruntime_BUILD:x86=ON, -Donnxruntime_BUILD:x86=OFF" +PACKAGECONFIG[fullprotobuf] = "-Donnxruntime_USE_FULL_PROTOBUF=ON, -Donnxruntime_USE_FULL_PROTOBUF=OFF" +PACKAGECONFIG[ops] = "-Donnxruntime_DISABLE_CONTRIB_OPS=ON, -Donnxruntime_DISABLE_CONTRIB_OPS=OFF" +PACKAGECONFIG[staticruntime] = "-Donnxruntime_MSVC_STATIC_RUNTIME=ON, -Donnxruntime_MSVC_STATIC_RUNTIME=OFF" +PACKAGECONFIG[runtests] = "-Donnxruntime_RUN_ONNX_TESTS=ON, -Donnxruntime_RUN_ONNX_TESTS=OFF" +PACKAGECONFIG[reports] = "-Donnxruntime_GENERATE_TEST_REPORTS=ON, -Donnxruntime_GENERATE_TEST_REPORTS=OFF" +PACKAGECONFIG[devmode] = "-Donnxruntime_DEV_MODE=ON, -Donnxruntime_DEV_MODE=OFF" +PACKAGECONFIG[cuda] = "-Donnxruntime_USE_CUDA=ON, -Donnxruntime_USE_CUDA=OFF" +PACKAGECONFIG[automl] = "-Donnxruntime_USE_AUTOML=ON, -Donnxruntime_USE_AUTOML=OFF" +PACKAGECONFIG[jemalloc] = "-Donnxruntime_USE_JEMALLOC=ON, -Donnxruntime_USE_JEMALLOC=OFF" +PACKAGECONFIG[mimalloc] = "-Donnxruntime_USE_MIMALLOC=ON, -Donnxruntime_USE_MIMALLOC=OFF" +PACKAGECONFIG[csharp] = "-Donnxruntime_BUILD_CSHARP=ON, -Donnxruntime_BUILD_CSHARP=OFF" +PACKAGECONFIG[java] = "-Donnxruntime_BUILD_JAVA=ON, -Donnxruntime_BUILD_JAVA=OFF" +PACKAGECONFIG[kleidiai] = "-Donnxruntime_USE_KLEIDIAI=ON, -Donnxruntime_USE_KLEIDIAI=OFF" +PACKAGECONFIG[neutron] = "-Donnxruntime_USE_NEUTRON=ON, -Donnxruntime_USE_NEUTRON=OFF, neutron nlohmann-json" +PACKAGECONFIG[vsinpu] = "-Donnxruntime_USE_VSINPU=ON, -Donnxruntime_USE_VSINPU=OFF, tim-vx" + +do_configure[network] = "1" +do_configure:prepend() { + export HTTP_PROXY=${http_proxy} + export HTTPS_PROXY=${https_proxy} + export http_proxy=${http_proxy} + export https_proxy=${https_proxy} +} + +do_compile[network] = "1" +do_compile:prepend() { + if ${@bb.utils.contains('PACKAGECONFIG', 'python', 'true', 'false', d)}; then + # required to pull pybind11 + export HTTP_PROXY=${http_proxy} + export HTTPS_PROXY=${https_proxy} + export http_proxy=${http_proxy} + export https_proxy=${https_proxy} + fi +} + +SETUPTOOLS_SETUP_PATH = "${B}" + +do_compile:append() { + if ${@bb.utils.contains('PACKAGECONFIG', 'python', 'true', 'false', d)}; then + # Copy 'setup.py' to build dir + cp ${S}/setup.py ${B} + + cp -r ${S}/onnxruntime/python ${B}/onnxruntime/ + + # Copy path file with path 'docs/python/README.rst' to build dir + mkdir -p ${B}/docs/python && cp ${S}/docs/python/README.rst ${B}/docs/python + + setuptools3_do_compile + + git config --global --add safe.directory ${WORKDIR}/build/pybind11/src/pybind11 + fi +} + +do_install:append() { + CP_ARGS="-Prf --preserve=mode,timestamps --no-preserve=ownership" + + # Ensure target dir exists + install -d ${D}${bindir}/${BP} + + # Copy squeezenet updated model from onnxruntime-imx repo + if [ -d ${S}/example-models/ ]; then + cp $CP_ARGS ${S}/example-models/squeezenet ${D}${bindir}/${BP}/ + fi + + # Copy label_image_onnx.py tool from onnxruntime-imx repo + cp ${S}/onnxruntime/core/providers/neutron/tools/label_image_onnx.py ${D}${bindir}/${BP}/ + + # If cmake installs 'onnx_test_runner' at bindir level, move to package + if [ -f ${D}${bindir}/onnx_test_runner ]; then + mv ${D}${bindir}/onnx_test_runner ${D}${bindir}/${BP}/ + fi + + # Install onnxruntime_perf_test in main package + install -m 0755 ${B}/onnxruntime_perf_test ${D}${bindir}/${BP} + + # Install test binaries and data in test package + install -d ${D}${bindir}/${BP}/tests + install -m 0744 ${B}/libcustom_op_library.so ${D}${bindir}/${BP}/tests + install -m 0744 ${B}/onnxruntime_global_thread_pools_test ${D}${bindir}/${BP}/tests + install -m 0744 ${B}/onnxruntime_mlas_test ${D}${bindir}/${BP}/tests + install -m 0744 ${B}/onnxruntime_shared_lib_test ${D}${bindir}/${BP}/tests + install -m 0744 ${B}/onnxruntime_test_all ${D}${bindir}/${BP}/tests + cp $CP_ARGS ${B}/testdata ${D}${bindir}/${BP}/tests + + if ${@bb.utils.contains('PACKAGECONFIG', 'python', 'true', 'false', d)}; then + setuptools3_do_install + find ${D}/${PYTHON_SITEPACKAGES_DIR} -type d -name "__pycache__" -exec rm -Rf {} + + git config --global --unset-all safe.directory ${TMPDIR}/.*/${PN}/.*/build/pybind11/src/pybind11 + fi + rm ${D}/${PYTHON_SITEPACKAGES_DIR}/${PN}/capi/libonnxruntime.so* +} + +# Make the package arch SOC-specific since the recipe now builds with SOC-specific configuration: +PACKAGE_ARCH = "${MACHINE_SOCARCH}" + +# Adjust the Python runtime dependency inherited from setuptools3-base.bbclass +# since Python support for this recipe is conditional +RDEPENDS:${PN}:remove:class-target = " \ + ${@bb.utils.contains('PACKAGECONFIG', 'python', '', '${PYTHON_PN}-core', d)}" + +# libonnxruntime_providers_shared.so is being packaged into -dev which is intended +INSANE_SKIP:${PN}-dev += "dev-elf" + +# A separate tests package for the test binaries not appearing in the main package +PACKAGE_BEFORE_PN = "${PN}-tests" +FILES:${PN}-tests = "${bindir}/${BP}/tests/*" + +# libcustom_op_library.so is in bindir, which is intended; +# onnxruntime_shared_lib_test requires the shlib to be in the same directory as testdata to run properly +INSANE_SKIP:${PN}-tests += "libdir" +INSANE_SKIP:${PN}-dbg += "libdir" diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/tensorflow-lite/tensorflow-lite-2.19.0.inc b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/tensorflow-lite/tensorflow-lite-2.19.0.inc new file mode 100644 index 000000000..17a933d0a --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/tensorflow-lite/tensorflow-lite-2.19.0.inc @@ -0,0 +1,5 @@ +# Copyright 2020-2025 NXP + +TENSORFLOW_LITE_SRC ?= "git://github.com/nxp-imx/tensorflow-imx.git;protocol=https" +SRCBRANCH_tf = "lf-6.12.49_2.2.0" +SRCREV_tf = "c6f244fe303bd5170fdd6b8d570fc0e3282fd38b" diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/tensorflow-lite/tensorflow-lite-host-tools_2.19.0.bb b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/tensorflow-lite/tensorflow-lite-host-tools_2.19.0.bb new file mode 100644 index 000000000..7af1fa604 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/tensorflow-lite/tensorflow-lite-host-tools_2.19.0.bb @@ -0,0 +1,29 @@ +# Copyright 2022-2025 NXP +DESCRIPTION = "Host tools required for build of TensorFlow Lite C++ Library unit tests and Evaluation Tools" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=4158a261ca7f2525513e31ba9c50ae98" + +require tensorflow-lite-${PV}.inc +SRC_URI = "${TENSORFLOW_LITE_SRC};branch=${SRCBRANCH_tf};name=tf" + +inherit cmake + +S = "${WORKDIR}/git" +OECMAKE_SOURCEPATH = "${S}/tensorflow/lite/tools/cmake/native_tools" + +BBCLASSEXTEND = "native nativesdk" + +EXTRA_OECMAKE = " \ + -DFETCHCONTENT_FULLY_DISCONNECTED=OFF \ + -DCMAKE_SYSROOT=${PKG_CONFIG_SYSROOT_DIR} \ +" + +CXXFLAGS += "-fPIC" + +do_configure[network] = "1" +do_configure:prepend() { + export HTTP_PROXY=${http_proxy} + export HTTPS_PROXY=${https_proxy} + export http_proxy=${http_proxy} + export https_proxy=${https_proxy} +} diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/tensorflow-lite/tensorflow-lite-neutron-delegate_2.19.0.bb b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/tensorflow-lite/tensorflow-lite-neutron-delegate_2.19.0.bb new file mode 100644 index 000000000..47c10f862 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/tensorflow-lite/tensorflow-lite-neutron-delegate_2.19.0.bb @@ -0,0 +1,65 @@ +# Copyright 2023-2025 NXP +DESCRIPTION = "TensorFlow Lite Neutron Delegate" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=86d3f3a95c324c9479bd8986968f4327" + +DEPENDS = "tensorflow-lite neutron tensorflow-lite-host-tools-native" + +require tensorflow-lite-${PV}.inc + +NEUTRON_DELEGATE_SRC ?= "git://github.com/nxp-imx/tflite-neutron-delegate.git;protocol=https" +SRCBRANCH_neutron = "lf-6.12.49_2.2.0" +SRCREV_neutron = "f24d08e5e1d461e669ece3c476c6dd340ce355cb" + +SRCREV_FORMAT = "neutron_tf" + +SRC_URI = "${NEUTRON_DELEGATE_SRC};branch=${SRCBRANCH_neutron};name=neutron \ + ${TENSORFLOW_LITE_SRC};branch=${SRCBRANCH_tf};name=tf;destsuffix=tfgit \ +" + +S = "${WORKDIR}/git" + +inherit python3native cmake + +EXTRA_OECMAKE = "-DCMAKE_SYSROOT=${PKG_CONFIG_SYSROOT_DIR}" +EXTRA_OECMAKE += " \ + -DFETCHCONTENT_FULLY_DISCONNECTED=OFF \ + -DTFLITE_HOST_TOOLS_DIR=${STAGING_BINDIR_NATIVE} \ + -DFETCHCONTENT_SOURCE_DIR_TENSORFLOW=${WORKDIR}/tfgit \ + -DTFLITE_LIB_LOC=${STAGING_DIR_HOST}${libdir}/libtensorflow-lite.so \ + ${S} \ +" + +CXXFLAGS += "-fPIC" + +do_configure[network] = "1" +do_configure:prepend() { + export HTTP_PROXY=${http_proxy} + export HTTPS_PROXY=${https_proxy} + export http_proxy=${http_proxy} + export https_proxy=${https_proxy} + + # There is no Fortran compiler in the toolchain, but bitbake sets this variable anyway + # with unavailable binary. + export FC="" +} + +do_install() { + # install libraries + install -d ${D}${libdir} + for lib in ${B}/lib*.so* + do + cp --no-preserve=ownership -d $lib ${D}${libdir} + done +} + +INHIBIT_PACKAGE_DEBUG_SPLIT = "1" + +# Output library is unversioned +SOLIBS = ".so" +FILES_SOLIBSDEV = "" + +# Work around do_package_qa error +INSANE_SKIP:${PN} += "buildpaths rpaths" + +COMPATIBLE_MACHINE = "(mx943-nxp-bsp|mx95-nxp-bsp)" diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/tensorflow-lite/tensorflow-lite_2.19.0.bb b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/tensorflow-lite/tensorflow-lite_2.19.0.bb new file mode 100644 index 000000000..dbd52b5f6 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-libraries/tensorflow-lite/tensorflow-lite_2.19.0.bb @@ -0,0 +1,150 @@ +# Copyright 2020-2025 NXP +DESCRIPTION = "TensorFlow Lite C++ Library" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=4158a261ca7f2525513e31ba9c50ae98" + + +DEPENDS = "flatbuffers python3-numpy-native python3-pip-native python3-pybind11-native python3-wheel-native unzip-native \ + python3 jpeg zlib ${BPN}-host-tools-native" + +require tensorflow-lite-${PV}.inc +SRC_URI = "${TENSORFLOW_LITE_SRC};branch=${SRCBRANCH_tf};name=tf" + +SRC_URI += "https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_1.0_224_quant.tgz;name=model-mobv1" +SRC_URI[model-mobv1.sha256sum] = "d32432d28673a936b2d6281ab0600c71cf7226dfe4cdcef3012555f691744166" + +S = "${WORKDIR}/git" + +inherit python3native cmake + +PACKAGECONFIG ??= "python-example ${PACKAGECONFIG_GPU_DELEGATE}" +PACKAGECONFIG_GPU_DELEGATE = "" +PACKAGECONFIG_GPU_DELEGATE:mx95-nxp-bsp = "gpu-delegate" + +PACKAGECONFIG[gpu-delegate] = "-DTFLITE_ENABLE_GPU=on,-DTFLITE_ENABLE_GPU=off" +PACKAGECONFIG[python-example] = ",,,python3-pillow" + +EXTRA_OECMAKE = " \ + -DCMAKE_SYSROOT=${PKG_CONFIG_SYSROOT_DIR} \ + -DFETCHCONTENT_FULLY_DISCONNECTED=OFF \ + -DTFLITE_EVAL_TOOLS=on \ + -DTFLITE_HOST_TOOLS_DIR=${STAGING_BINDIR_NATIVE} \ + -DTFLITE_BUILD_SHARED_LIB=on \ + -DTFLITE_ENABLE_NNAPI=off \ + -DTFLITE_ENABLE_NNAPI_VERBOSE_VALIDATION=on \ + -DTFLITE_ENABLE_RUY=on \ + -DTFLITE_ENABLE_XNNPACK=on \ + -DTFLITE_PYTHON_WRAPPER_BUILD_CMAKE2=on \ + -DTFLITE_ENABLE_EXTERNAL_DELEGATE=on \ + ${S}/tensorflow/lite/ \ +" +EXTRA_OECMAKE_BUILD = "benchmark_model label_image" + +CXXFLAGS += "-fPIC" + + +do_configure[network] = "1" +do_configure:prepend() { + export HTTP_PROXY=${http_proxy} + export HTTPS_PROXY=${https_proxy} + export http_proxy=${http_proxy} + export https_proxy=${https_proxy} + + # There is no Fortran compiler in the toolchain, but bitbake sets this variable anyway + # with unavailable binary. + export FC="" +} + + +do_compile:append () { + # build pip package + cd ${B} + CI_BUILD_PYTHON=${PYTHON} BUILD_NUM_JOBS=8 ${S}/tensorflow/lite/tools/pip_package/build_pip_package_with_cmake2.sh ${TARGET_ARCH} +} + +do_install() { + # install libraries + install -d ${D}${libdir} + for lib in ${B}/lib*.so* + do + cp --no-preserve=ownership -d $lib ${D}${libdir} + done + + # install header files + install -d ${D}${includedir}/tensorflow/lite + cd ${S}/tensorflow/lite + cp --parents \ + $(find . -name "*.h*") \ + ${D}${includedir}/tensorflow/lite + + install -d ${D}${includedir}/tensorflow/compiler/mlir/lite + cd ${S}/tensorflow/compiler/mlir/lite + cp --parents \ + $(find . -name "*.h*") \ + ${D}${includedir}/tensorflow/compiler/mlir/lite + + # install version.h from core + install -d ${D}${includedir}/tensorflow/core/public + cp ${S}/tensorflow/core/public/version.h ${D}${includedir}/tensorflow/core/public + + # install ctstring_internal.h from core + install -d ${D}${includedir}/tensorflow/core/platform + cp ${S}/tensorflow/core/platform/ctstring_internal.h ${D}${includedir}/tensorflow/core/platform + + # install ctstring_internal.h from tsl + install -d ${D}${includedir}/tsl/platform + cp ${S}/third_party/xla/third_party/tsl/tsl/platform/ctstring_internal.h ${D}${includedir}/tsl/platform + + # install examples + install -d ${D}${bindir}/${PN}-${PV}/examples + install -m 0555 ${B}/examples/label_image/label_image ${D}${bindir}/${PN}-${PV}/examples + install -m 0555 ${B}/tools/benchmark/benchmark_model ${D}${bindir}/${PN}-${PV}/examples + install -m 0555 ${B}/tools/evaluation/coco_object_detection_run_eval ${D}${bindir}/${PN}-${PV}/examples + install -m 0555 ${B}/tools/evaluation/imagenet_image_classification_run_eval ${D}${bindir}/${PN}-${PV}/examples + install -m 0555 ${B}/tools/evaluation/inference_diff_run_eval ${D}${bindir}/${PN}-${PV}/examples + + # install label_image data + cp ${S}/tensorflow/lite/examples/label_image/testdata/grace_hopper.bmp ${D}${bindir}/${PN}-${PV}/examples + cp ${S}/tensorflow/lite/java/ovic/src/testdata/labels.txt ${D}${bindir}/${PN}-${PV}/examples + + + # Install python example + if ${@bb.utils.contains('PACKAGECONFIG', 'python-example', 'true', 'false', d)}; then + cp ${S}/tensorflow/lite/examples/python/label_image.py ${D}${bindir}/${PN}-${PV}/examples + fi + + # Install mobilenet tflite file + cp ${WORKDIR}/mobilenet_*.tflite ${D}${bindir}/${PN}-${PV}/examples + + # Install pip package + install -d ${D}/${PYTHON_SITEPACKAGES_DIR} + ${STAGING_BINDIR_NATIVE}/pip3 install --disable-pip-version-check -vvv --platform linux_${TARGET_ARCH} \ + -t ${D}/${PYTHON_SITEPACKAGES_DIR} --no-cache-dir --no-deps \ + ${B}/tflite_pip/dist/tflite_runtime-*.whl +} + +PACKAGE_ARCH = "${MACHINE_SOCARCH}" + +RDEPENDS:${PN} = " \ + python3 \ + python3-numpy \ + ${RDEPENDS_OPENCL} \ +" +RDEPENDS_OPENCL = "opencl-icd-loader-dev" +RDEPENDS_OPENCL:mx8mm-nxp-bsp = "" + +INSANE_SKIP:${PN} += "dev-deps" + +# TensorFlow and TensorFlow Lite both exports few files, suppress the error +# SSTATE_ALLOW_OVERLAP_FILES = "${D}${includedir}" +SSTATE_ALLOW_OVERLAP_FILES = "/" + +INHIBIT_PACKAGE_DEBUG_SPLIT = "1" + +INSANE_SKIP:${PN} += " \ + already-stripped \ + staticdev \ + buildpaths \ +" + +FILES:${PN} += "${libdir}/python*" diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer-edge/nnstreamer-edge_0.2.6.bb b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer-edge/nnstreamer-edge_0.2.6.bb new file mode 100644 index 000000000..c42d5577a --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer-edge/nnstreamer-edge_0.2.6.bb @@ -0,0 +1,26 @@ +SUMMARY = "NNStreamer-Edge library" +DESCRIPTION = "Remote source nodes for NNStreamer pipelines without GStreamer dependencies" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=095e13fef457e259d3bc155d0ed859f1" + +DEPENDS = "\ + gtest \ +" + +NNS_EDGE_SRC ?= "git://github.com/nnstreamer/nnstreamer-edge.git;protocol=https" +SRCBRANCH = "prod/tizen-9.0" +SRCREV = "e73acb740dce3ecbf8a650f45fab790afb400a95" +SRC_URI = "${NNS_EDGE_SRC};branch=${SRCBRANCH}" + +S = "${WORKDIR}/git" + +inherit cmake pkgconfig + +EXTRA_OECMAKE = " \ + -DENABLE_TEST=ON \ +" + +# The build produces a mix of versioned and unversioned libs, so custom packaging is required +FILES_SOLIBSDEV:remove = "${libdir}/lib*${SOLIBSDEV}" +FILES:${PN} += "${libdir}/libnnstreamer-edge-custom-test${SOLIBSDEV}" +FILES:${PN}-dev += "${libdir}/libnnstreamer-edge${SOLIBSDEV}" diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer/0001-AIR-11938-tensor-filter-use-memcpy-ethosu-delegate.patch b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer/0001-AIR-11938-tensor-filter-use-memcpy-ethosu-delegate.patch new file mode 100644 index 000000000..8123b24d9 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer/0001-AIR-11938-tensor-filter-use-memcpy-ethosu-delegate.patch @@ -0,0 +1,63 @@ +From fd05c3f40c9ae1bdf2e05fc3581a00ec967fb9e3 Mon Sep 17 00:00:00 2001 +From: Nicolas Goueslain +Date: Wed, 23 Jul 2025 12:28:07 +0000 +Subject: [PATCH] AIR-11938: tensor-filter-use-memcpy-ethosu-delegate + +Upstream-Status: Inappropriate [i.MX specific] + +Signed-off-by: Nicolas Goueslain +--- + .../tensor_filter/tensor_filter_tensorflow_lite.cc | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.cc b/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.cc +index 95ab68c6..86879932 100644 +--- a/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.cc ++++ b/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.cc +@@ -244,6 +244,7 @@ class TFLiteInterpreter + char *model_path; + bool is_cached_after_first_invoke; /**< To cache again after first invoke */ + bool is_xnnpack_delegated; /**< To check if XNNPACK delegate is used */ ++ bool is_ethosu_delegated; + char *ext_delegate_path; /**< path to external delegate lib */ + GHashTable *ext_delegate_kv_table; /**< external delegate key values options */ + QNNBackendType qnn_backend_type; /**< QNN Delegate backend type */ +@@ -332,6 +333,7 @@ TFLiteInterpreter::TFLiteInterpreter () + + is_cached_after_first_invoke = false; + is_xnnpack_delegated = false; ++ is_ethosu_delegated = false; + } + + /** +@@ -366,7 +368,7 @@ TFLiteInterpreter::invoke (const GstTensorMemory *input, GstTensorMemory *output + * Therefore tensor data is to be manually copied from/to input/output + * GStreamer buffers memory whose address changes at every round. + */ +- if (is_xnnpack_delegated) { ++ if (is_xnnpack_delegated || is_ethosu_delegated) { + for (unsigned int i = 0; i < inputTensorMeta.num_tensors; ++i) { + tensor_ptr = inputTensorPtr[i]; + g_assert (tensor_ptr->bytes == input[i].size); +@@ -395,7 +397,7 @@ TFLiteInterpreter::invoke (const GstTensorMemory *input, GstTensorMemory *output + * After the very first invoke, the output buffer address may change. + * To handle the case, memcpy the output buffer directly. + */ +- if (is_xnnpack_delegated || !is_cached_after_first_invoke) { ++ if (is_xnnpack_delegated || is_ethosu_delegated || !is_cached_after_first_invoke) { + for (unsigned int i = 0; i < outputTensorMeta.num_tensors; ++i) { + tensor_ptr = outputTensorPtr[i]; + g_assert (tensor_ptr->bytes == output[i].size); +@@ -555,6 +557,9 @@ TFLiteInterpreter::loadModel (int num_threads, tflite_delegate_e delegate_e) + + options = TfLiteExternalDelegateOptionsDefault (ext_delegate_path); + ++ if (strcmp(ext_delegate_path, "libethosu_delegate.so") == 0){ ++ is_ethosu_delegated = true; ++ } + /* Add optional key values to delegate configuration */ + if (ext_delegate_kv_table) { + GHashTable *table = ext_delegate_kv_table; +-- +2.34.1 + diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer/0001-Fix-libnnstreamer_customfilter_passthrough.so-path.patch b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer/0001-Fix-libnnstreamer_customfilter_passthrough.so-path.patch new file mode 100644 index 000000000..30341c82f --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer/0001-Fix-libnnstreamer_customfilter_passthrough.so-path.patch @@ -0,0 +1,33 @@ +From 68ed0ca853338c9436d5047777f3f395c0f2c5b2 Mon Sep 17 00:00:00 2001 +From: Nolann Chobert +Date: Mon, 28 Jul 2025 16:00:19 +0000 +Subject: [PATCH] Fix libnnstreamer_customfilter_passthrough.so path + +Custom filter path is set to Yocto build path which will trigger an error on target. +The appropriate path is /usr/lib/nnstreamer/customfilters/libnnstreamer_customfilter_passthrough.so. + +Upstream-Status: Inappropriate [i.MX specific] + +Signed-off-by: Nolann Chobert +--- + tests/nnstreamer_filter_extensions_common/meson.build | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/tests/nnstreamer_filter_extensions_common/meson.build b/tests/nnstreamer_filter_extensions_common/meson.build +index ecd1878b..eba2cc83 100644 +--- a/tests/nnstreamer_filter_extensions_common/meson.build ++++ b/tests/nnstreamer_filter_extensions_common/meson.build +@@ -9,7 +9,9 @@ tizen_apptest_deps = [ + # Format for adding subplugin into extensions - + # [name, extension abbreviation, dependencies, model file name/folder path/file path, test name] + extensions = [] +-custom_filter_path = join_paths(meson.build_root(), 'tests', 'nnstreamer_example', ++nnst_prefix = get_option('prefix') ++nnst_libdir = join_paths(nnst_prefix, get_option('libdir')) ++custom_filter_path = join_paths(nnst_libdir, 'nnstreamer', 'customfilters', + 'libnnstreamer_customfilter_passthrough.' + so_ext) + extensions += [['custom', 'custom', nnstreamer_unittest_deps, custom_filter_path, 'custom']] + extensions += [['custom', 'custom', nnstreamer_unittest_deps, custom_filter_path, 'custom-set']] +-- +2.34.1 + diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer/0001-Fix-to-provide-default-delegates.patch b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer/0001-Fix-to-provide-default-delegates.patch new file mode 100644 index 000000000..78e73ab8f --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer/0001-Fix-to-provide-default-delegates.patch @@ -0,0 +1,125 @@ +From e7585fe374349fb6e022c7515271a2ca475015b2 Mon Sep 17 00:00:00 2001 +From: Nolann Chobert +Date: Thu, 16 Oct 2025 17:39:33 +0200 +Subject: [PATCH] [Filter/TFLite] Fix to provide default delegates + +Some external delegates might need to access default delegates such as +XNNPACK to accelerate unsupported operations. + +Upstream-Status: Pending +Signed-off-by: Nolann Chobert +--- + .../tensor_filter_tensorflow_lite.cc | 41 ++++++++++++------- + 1 file changed, 26 insertions(+), 15 deletions(-) + +diff --git a/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.cc b/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.cc +index 95ab68c6..d293e78c 100644 +--- a/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.cc ++++ b/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.cc +@@ -98,13 +98,6 @@ + #define TFLITE_SUBPLUGIN_NAME "tensorflow-lite" + #endif + +-/** +- * @brief prevent usage by TFLite of default delegates that may not be supported +- */ +-#if TFLITE_VERSION_MAJOR >= 2 && TFLITE_VERSION_MINOR >= 4 +-#define TFLITE_RESOLVER_WITHOUT_DEFAULT_DELEGATES +-#endif +- + /** + * @brief Macro for debug mode. + */ +@@ -157,6 +150,7 @@ typedef struct { + GHashTable *ext_delegate_kv_table; /**< external delegate key values options */ + QNNBackendType qnn_backend_type; /**< QNN Delegate backend type */ + QNNPerformanceMode qnn_performance_mode; /**< QNN Delegate performance mode */ ++ bool use_default_delegates; /**< whether to use default delegates in resolver */ + } tflite_option_s; + + /** +@@ -197,6 +191,10 @@ class TFLiteInterpreter + void setModelPath (const char *model_path); + void setExtDelegate (const char *lib_path, GHashTable *key_val); + void getExtDelegate (const char **lib_path, GHashTable **key_val); ++ void setUseDefaultDelegates (gboolean use_default) ++ { ++ use_default_delegates = use_default; ++ } + /** @brief get current model path */ + const char *getModelPath () + { +@@ -248,6 +246,7 @@ class TFLiteInterpreter + GHashTable *ext_delegate_kv_table; /**< external delegate key values options */ + QNNBackendType qnn_backend_type; /**< QNN Delegate backend type */ + QNNPerformanceMode qnn_performance_mode; /**< QNN Delegate performance mode */ ++ bool use_default_delegates; /**< whether to use default delegates in resolver */ + + std::unique_ptr interpreter; + std::unique_ptr model; +@@ -324,6 +323,7 @@ TFLiteInterpreter::TFLiteInterpreter () + ext_delegate_kv_table = nullptr; + qnn_backend_type = QNN_BACKEND_UNDEFINED; + qnn_performance_mode = QNN_PERFMODE_Default; ++ use_default_delegates = FALSE; + + g_mutex_init (&mutex); + +@@ -460,12 +460,14 @@ TFLiteInterpreter::loadModel (int num_threads, tflite_delegate_e delegate_e) + + interpreter = nullptr; + +-#ifdef TFLITE_RESOLVER_WITHOUT_DEFAULT_DELEGATES +- tflite::ops::builtin::BuiltinOpResolverWithoutDefaultDelegates resolver; +-#else +- tflite::ops::builtin::BuiltinOpResolver resolver; +-#endif +- tflite::InterpreterBuilder (*model, resolver) (&interpreter); ++ if (use_default_delegates) { ++ tflite::ops::builtin::BuiltinOpResolver resolver; ++ tflite::InterpreterBuilder (*model, resolver) (&interpreter); ++ } else { ++ tflite::ops::builtin::BuiltinOpResolverWithoutDefaultDelegates resolver; ++ tflite::InterpreterBuilder (*model, resolver) (&interpreter); ++ } ++ + if (!interpreter) { + ml_loge ("Failed to construct interpreter\n"); + return -2; +@@ -1075,6 +1077,7 @@ TFLiteCore::init (tflite_option_s *option) + { + interpreter->setModelPath (option->model_file); + interpreter->setExtDelegate (option->ext_delegate_path, option->ext_delegate_kv_table); ++ interpreter->setUseDefaultDelegates (option->use_default_delegates); + interpreter->qnn_backend_type = option->qnn_backend_type; + interpreter->qnn_performance_mode = option->qnn_performance_mode; + num_threads = option->num_threads; +@@ -1395,6 +1398,13 @@ tflite_parseCustomOption (const GstTensorFilterProperties *prop, tflite_option_s + + if (g_ascii_strcasecmp (pair[0], "NumThreads") == 0) { + option->num_threads = (int) g_ascii_strtoll (pair[1], NULL, 10); ++ } else if (g_ascii_strcasecmp (pair[0], "UseDefaultDelegates") == 0) { ++ if (g_ascii_strcasecmp (pair[1], "true") == 0 || g_ascii_strcasecmp (pair[1], "1") == 0) ++ option->use_default_delegates = TRUE; ++ else if (g_ascii_strcasecmp (pair[1], "false") == 0 || g_ascii_strcasecmp (pair[1], "0") == 0) ++ option->use_default_delegates = FALSE; ++ else ++ ml_logw ("Invalid value for UseDefaultDelegates (%s). Use 'true' or 'false'.", pair[1]); + } else if (g_ascii_strcasecmp (pair[0], "Delegate") == 0) { + if (g_ascii_strcasecmp (pair[1], "NNAPI") == 0) + option->delegate = TFLITE_DELEGATE_NNAPI; +@@ -1777,8 +1787,9 @@ _nns_filter_register_tflite (void) + { + nnstreamer_filter_probe (&NNS_support_tensorflow_lite); + nnstreamer_filter_set_custom_property_desc (NNS_support_tensorflow_lite.v0.name, +- "NumThreads", "Number of threads. Set 0 for default behaviors.", "Delegate", +- "TF-Lite delegation options: {'NNAPI', 'GPU', 'XNNPACK', 'External', 'QNN'}." ++ "NumThreads", "Number of threads. Set 0 for default behaviors.", ++ "UseDefaultDelegates", "Whether to use default delegates in resolver. Set 'true' or 'false'. Default is 'false'.", ++ "Delegate", "TF-Lite delegation options: {'NNAPI', 'GPU', 'XNNPACK', 'External', 'QNN'}." + " Do not specify to disable delegation.", + "ExtDelegateLib", "Path to external delegate shared library", "ExtDelegateKeyVal", + "key/values pairs optional parameters for delegate." +-- +2.34.1 + diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer/0001-gray8_padding_removal.patch b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer/0001-gray8_padding_removal.patch new file mode 100644 index 000000000..9acb56562 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer/0001-gray8_padding_removal.patch @@ -0,0 +1,179 @@ +From 686e0ece0aef4f1d4bb24c893106f8d595016a30 Mon Sep 17 00:00:00 2001 +From: Alexandru Firuti +Date: Tue, 18 Nov 2025 13:54:15 +0000 +Subject: [PATCH] tensor_converter: add frame padding removal for GRAY8 + +- gst_tensor_converter_parse_video: add a new function for checking i.MX-specific +padding (gst_tensor_converter_video_stride_imx); if detected, set self->remove_imx_padding flag +- gst_tensor_converter_chain: for video media type, remove the paddding when either of +self->remove_padding and self->remove_imx_padding flags are set; in case there is no metadata +attached to padding, ignore the i.MX padding removal as the buffer is not coming from i.MX plugins; +add also logic to skip frame padding if it exists + +Upstream-Status: Inappropriate [i.MX specific] + +Signed-off-by: Alexandru Firuti +--- + gst/nnstreamer/elements/gsttensor_converter.c | 50 ++++++++++++++++++- + gst/nnstreamer/elements/gsttensor_converter.h | 1 + + 2 files changed, 49 insertions(+), 2 deletions(-) + +diff --git a/gst/nnstreamer/elements/gsttensor_converter.c b/gst/nnstreamer/elements/gsttensor_converter.c +index 78f62247..b7a28a36 100644 +--- a/gst/nnstreamer/elements/gsttensor_converter.c ++++ b/gst/nnstreamer/elements/gsttensor_converter.c +@@ -359,6 +359,7 @@ gst_tensor_converter_init (GstTensorConverter * self) + self->in_media_type = _NNS_MEDIA_INVALID; + self->frame_size = 0; + self->remove_padding = FALSE; ++ self->remove_imx_padding = FALSE; + self->externalConverter = NULL; + self->priv_data = NULL; + self->mode = _CONVERTER_MODE_NONE; +@@ -1032,7 +1033,7 @@ gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) + GstTensorsConfig new_config; + GstTensorInfo *_info; + GstBuffer *inbuf; +- gsize buf_size, frame_size; ++ gsize buf_size, frame_size, frame_padding; + guint frames_in, frames_out; + UNUSED (pad); + +@@ -1073,7 +1074,7 @@ gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) + /** supposed 1 frame in buffer */ + g_assert ((buf_size / self->frame_size) == 1); + +- if (self->remove_padding) { ++ if (self->remove_padding || self->remove_imx_padding) { + GstMapInfo src_info, dest_info; + guint d0, d1; + unsigned int src_idx = 0, dest_idx = 0; +@@ -1104,6 +1105,13 @@ gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) + GstVideoMeta *video_meta = gst_buffer_get_video_meta (buf); + if (video_meta) { + offset = video_meta->stride[0]; ++ } else if (self->remove_imx_padding && !self->remove_padding) { ++ /** ++ * If GstVideoMeta is missing, the buffer comes from a generic GStreamer plugin. ++ * Only the default 4-bytes alignment correction should be done, the i.MX specific ++ * one should be skipped. ++ */ ++ break; + } else { + g_assert (offset % 4); /** Internal logic error! */ + if (offset % 4) { +@@ -1111,12 +1119,22 @@ gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) + } + } + ++ /* Calculate frame padding (padding at the end of entire frame) */ ++ frame_padding = 0; ++ if (buf_size > frame_size) { ++ frame_padding = buf_size - frame_size; ++ } ++ + for (d0 = 0; d0 < frames_in; d0++) { + for (d1 = 0; d1 < height; d1++) { + memcpy (dest_info.data + dest_idx, src_info.data + src_idx, size); + dest_idx += size; + src_idx += offset; + } ++ /* Skip frame padding if it exists (after all rows of current frame) */ ++ if (frame_padding > 0 && d0 < (frames_in - 1)) { ++ src_idx += frame_padding; ++ } + } + + gst_buffer_unmap (buf, &src_info); +@@ -1438,6 +1456,26 @@ gst_tensor_converter_video_stride (GstVideoFormat format, gint width) + return FALSE; + } + ++/** ++ * @brief Determine if we need i.MX-specific zero-padding ++ * @return TRUE if we need to add (or remove) stride per row from the stream data. ++ */ ++static gboolean ++gst_tensor_converter_video_stride_imx (GstVideoFormat format, gint width, gint height, gsize frame_size) ++{ ++ switch (format) { ++ case GST_VIDEO_FORMAT_GRAY8: ++ if ((width % 16) || (height % 16) || (frame_size % 4096)) { ++ return TRUE; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ return FALSE; ++} ++ + /** + * @brief Set the tensors config structure from video info (internal static function) + * @param self this pointer to GstTensorConverter +@@ -1459,6 +1497,7 @@ gst_tensor_converter_parse_video (GstTensorConverter * self, + GstVideoFormat format; + gint width, height, views; + guint i; ++ gsize size = 0; // Frame size + + g_return_val_if_fail (config != NULL, FALSE); + +@@ -1494,6 +1533,7 @@ gst_tensor_converter_parse_video (GstTensorConverter * self, + config->info.info[0].dimension[0] = 1; + config->info.info[0].dimension[1] = width; + config->info.info[0].dimension[2] = height; ++ size = 1 * width * height; // 1 byte per pixel + break; + case GST_VIDEO_FORMAT_GRAY16_BE: + case GST_VIDEO_FORMAT_GRAY16_LE: +@@ -1501,6 +1541,7 @@ gst_tensor_converter_parse_video (GstTensorConverter * self, + config->info.info[0].dimension[0] = 1; + config->info.info[0].dimension[1] = width; + config->info.info[0].dimension[2] = height; ++ size = 2 * 1 * width * height; // 2 bytes per pixel + break; + case GST_VIDEO_FORMAT_RGB: + case GST_VIDEO_FORMAT_BGR: +@@ -1508,6 +1549,7 @@ gst_tensor_converter_parse_video (GstTensorConverter * self, + config->info.info[0].dimension[0] = 3; + config->info.info[0].dimension[1] = width; + config->info.info[0].dimension[2] = height; ++ size = 1 * 3 * width * height; // 1 byte per channel, 3 channels + break; + case GST_VIDEO_FORMAT_RGBx: + case GST_VIDEO_FORMAT_BGRx: +@@ -1521,6 +1563,7 @@ gst_tensor_converter_parse_video (GstTensorConverter * self, + config->info.info[0].dimension[0] = 4; + config->info.info[0].dimension[1] = width; + config->info.info[0].dimension[2] = height; ++ size = 1 * 4 * width * height; // 1 byte per channel, 4 channels + break; + #if GST_CHECK_VERSION(1, 20, 0) + case GST_VIDEO_FORMAT_RGBP: +@@ -1571,6 +1614,9 @@ gst_tensor_converter_parse_video (GstTensorConverter * self, + "Please use 4 x n as image width for inputs; the width of your input is %d.\n", + width); + } ++ if (gst_tensor_converter_video_stride_imx (format, width, height, size)) { ++ self->remove_imx_padding = TRUE; ++ } + + self->frame_size = GST_VIDEO_INFO_SIZE (&vinfo); + return (config->info.info[0].type != _NNS_END); +diff --git a/gst/nnstreamer/elements/gsttensor_converter.h b/gst/nnstreamer/elements/gsttensor_converter.h +index b1328bb6..75589540 100644 +--- a/gst/nnstreamer/elements/gsttensor_converter.h ++++ b/gst/nnstreamer/elements/gsttensor_converter.h +@@ -92,6 +92,7 @@ struct _GstTensorConverter + + gsize frame_size; /**< size of one frame */ + gboolean remove_padding; /**< If true, zero-padding must be removed */ ++ gboolean remove_imx_padding; /**< If true, i.MX-specific zero-padding must be removed */ + gboolean tensors_configured; /**< True if already successfully configured tensors metadata */ + GstTensorsConfig tensors_config; /**< output tensors info */ + +-- +2.34.1 + diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer/0001-rgb888_support_nnstreamer.patch b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer/0001-rgb888_support_nnstreamer.patch new file mode 100644 index 000000000..397dd3c00 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer/0001-rgb888_support_nnstreamer.patch @@ -0,0 +1,45 @@ +From ccf4eea69e320d23013e5ec526d8b4f52a89192c Mon Sep 17 00:00:00 2001 +From: Elliot Chen +Date: Wed, 23 Jul 2025 12:55:32 +0000 +Subject: [PATCH] tensor_converter: calculate the offset by video meta when + removing padding + +Changes for imxvideoconvert_g2d RGB888 support introduced 4-bytes alignment [MMFMWK-9523]. +Padding is used for dimensions that are not multiple of 4. +NNStreamer tensor_converter padding removal is done using a padding size calculated on the 4-bytes alignment of width value in bytes. +The attached patch fixes the mismatch by adjusting the offset used for padding removal in NNStreamer to the actual stride value coming in video meta from the GStreamer plugins. + +Upstream-Status: Inappropriate [i.MX specific] + +Signed-off-by: Elliot Chen +Signed-off-by: Nicolas Goueslain +--- + gst/nnstreamer/elements/gsttensor_converter.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/gst/nnstreamer/elements/gsttensor_converter.c b/gst/nnstreamer/elements/gsttensor_converter.c +index c03fe87e..78f62247 100644 +--- a/gst/nnstreamer/elements/gsttensor_converter.c ++++ b/gst/nnstreamer/elements/gsttensor_converter.c +@@ -1100,9 +1100,15 @@ gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) + */ + size = offset = type * color * width; + +- g_assert (offset % 4); /** Internal logic error! */ +- if (offset % 4) { +- offset += 4 - (offset % 4); ++ /* Calculate the offset by video meta if is exist */ ++ GstVideoMeta *video_meta = gst_buffer_get_video_meta (buf); ++ if (video_meta) { ++ offset = video_meta->stride[0]; ++ } else { ++ g_assert (offset % 4); /** Internal logic error! */ ++ if (offset % 4) { ++ offset += 4 - (offset % 4); ++ } + } + + for (d0 = 0; d0 < frames_in; d0++) { +-- +2.34.1 + diff --git a/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer_2.4.2.bb b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer_2.4.2.bb new file mode 100644 index 000000000..fa2d41d7c --- /dev/null +++ b/meta-digi-dey/dynamic-layers/imx-machine-learning/recipes-nnstreamer/nnstreamer/nnstreamer_2.4.2.bb @@ -0,0 +1,224 @@ +SUMMARY = "NNStreamer, Stream Pipeline Paradigm for Neural Network Applications" +DESCRIPTION = "NNStreamer is a GStreamer plugin allowing to construct neural network applications with stream pipeline paradigm." +SECTION = "AI" +LICENSE = "LGPL-2.0-or-later" +LIC_FILES_CHKSUM = "\ + file://LICENSE;md5=c25e5c1949624d71896127788f1ba590 \ + file://debian/copyright;md5=0462ef8fa89a1f53f2e65e74940519ef \ +" + +DEPENDS = "\ + bison-native \ + flex-native \ + orc-native \ + glib-2.0 \ + gstreamer1.0 \ + gstreamer1.0-plugins-base \ + gtest \ + libpng \ +" + +SRCREV = "9cf11e0768892636622480fe1b5fc042b5a224ad" +SRC_URI = "git://github.com/nnstreamer/nnstreamer.git;branch=prod/tizen-9.0;protocol=https \ + file://0001-AIR-11938-tensor-filter-use-memcpy-ethosu-delegate.patch \ + file://0001-rgb888_support_nnstreamer.patch \ + file://0001-Fix-libnnstreamer_customfilter_passthrough.so-path.patch \ + file://0001-gray8_padding_removal.patch \ + file://0001-Fix-to-provide-default-delegates.patch \ +" + +# Use git instead of quilt as patch tool to support patches with binary content +PATCHTOOL = "git" + +S = "${WORKDIR}/git" + +inherit meson pkgconfig + +PACKAGECONFIG ??= "protobuf python3 query ${PACKAGECONFIG_SOC}" +PACKAGECONFIG_SOC ??= "" + + +PACKAGECONFIG_SOC:mx8-nxp-bsp:imxgpu ??= "tensorflow-lite" +PACKAGECONFIG_SOC:mx8mp-nxp-bsp ??= "tensorflow-lite tvm" +PACKAGECONFIG_SOC:mx9-nxp-bsp ??= "tensorflow-lite" + +PACKAGECONFIG[flatbuf] = "\ + -Dflatbuf-support=enabled, \ + -Dflatbuf-support=disabled, \ + flatbuffers-native flatbuffers, \ + ,,\ +" + +PACKAGECONFIG[grpc] = "\ + -Dgrpc-support=enabled, \ + -Dgrpc-support=disabled, \ + grpc-native grpc, \ + ,,\ +" + +PACKAGECONFIG[protobuf] = "\ + -Dprotobuf-support=enabled, \ + -Dprotobuf-support=disabled, \ + protobuf-native protobuf, \ + ,,\ +" + +PACKAGECONFIG[python3] = "\ + -Dpython3-support=enabled, \ + -Dpython3-support=disabled, \ + python3 python3-numpy-native, \ + ,,\ +" + +PACKAGECONFIG[query] = "\ + -Dnnstreamer-edge-support=enabled, \ + -Dnnstreamer-edge-support=disabled, \ + nnstreamer-edge, \ + ,,\ +" + +PACKAGECONFIG[tensorflow-lite] = "\ + -Dtflite2-support=enabled, \ + -Dtflite2-support=disabled, \ + tensorflow-lite flatbuffers, \ + ,,\ +" + +PACKAGECONFIG[tvm] = "\ + -Dtvm-support=enabled, \ + -Dtvm-support=disabled, \ + tvm, \ + ,,\ +" + +EXTRA_OEMESON += "\ + -Denable-float16=true \ + -Denable-test=true \ + -Dinstall-test=true \ +" + +# FIXME: Remove this when the source warnings are fixed +CFLAGS += "-Wno-error" + +do_install:append() { + rm -f ${D}/${bindir}/unittest-nnstreamer/tests/test_models/models/tvm_add_one.so_ +} + +PACKAGES =+ "\ + ${PN}-unittest \ + ${@bb.utils.contains('PACKAGECONFIG', 'flatbuf','${PN}-flatbuf', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'flatbuf grpc','${PN}-grpc-flatbuf', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'grpc','${PN}-grpc', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'protobuf','${PN}-protobuf', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'protobuf grpc','${PN}-grpc-protobuf', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'python3','${PN}-python3', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'query','${PN}-query', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'tensorflow-lite','${PN}-tensorflow-lite', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'tvm','${PN}-tvm', '', d)} \ +" + +RDEPENDS:${PN} = "\ + gstreamer1.0-plugins-base \ +" + +RDEPENDS:${PN}-unittest = "gstreamer1.0-plugins-good nnstreamer ssat \ + ${@bb.utils.contains('PACKAGECONFIG', 'flatbuf','${PN}-flatbuf', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'flatbuf grpc','${PN}-grpc-flatbuf', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'grpc','${PN}-grpc', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'protobuf','${PN}-protobuf', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'protobuf grpc','${PN}-grpc-protobuf', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'python3','${PN}-python3', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'query','${PN}-query', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'tensorflow-lite','${PN}-tensorflow-lite', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'tvm','${PN}-tvm', '', d)} \ +" + +# The libraries are unversioned +SOLIBS = ".so" +FILES_SOLIBSDEV = "" + +FILES:${PN} += "\ + ${libdir}/gstreamer-1.0/lib*${SOLIBS} \ +" + +FILES:${PN}-flatbuf = "\ + ${libdir}/nnstreamer/converters/libnnstreamer_converter_flatbuf.so \ + ${libdir}/nnstreamer/converters/libnnstreamer_converter_flexbuf.so \ + ${libdir}/nnstreamer/decoders/libnnstreamer_decoder_flatbuf.so \ + ${libdir}/nnstreamer/decoders/libnnstreamer_decoder_flexbuf.so \ +" + +FILES:${PN}-grpc = "\ + ${libdir}/gstreamer-1.0/libnnstreamer-grpc.so \ +" + +FILES:${PN}-grpc-flatbuf = "\ + ${libdir}/libnnstreamer_grpc_flatbuf.so \ +" + +FILES:${PN}-grpc-protobuf = "\ + ${libdir}/libnnstreamer_grpc_protobuf.so \ +" + +FILES:${PN}-protobuf = "\ + ${libdir}/nnstreamer/converters/libnnstreamer_converter_protobuf.so \ + ${libdir}/nnstreamer/decoders/libnnstreamer_decoder_protobuf.so \ + ${libdir}/libnnstreamer_protobuf.so \ +" + +FILES:${PN}-python3 = "\ + ${libdir}/nnstreamer/converters/libnnstreamer_converter_python3.so \ + ${libdir}/nnstreamer/decoders/libnnstreamer_decoder_python3.so \ + ${libdir}/nnstreamer/filters/libnnstreamer_filter_python3.so \ + ${libdir}/nnstreamer_python3.so \ + ${PYTHON_SITEPACKAGES_DIR}/nnstreamer_python.so \ +" + +FILES:${PN}-query = "\ + ${libdir}/gstreamer-1.0/libgstedge.so \ +" + +FILES:${PN}-tensorflow-lite = "\ + ${libdir}/nnstreamer/filters/libnnstreamer_filter_tensorflow2-lite.so \ +" + +FILES:${PN}-tvm = "\ + ${libdir}/nnstreamer/filters/libnnstreamer_filter_tvm.so \ +" + +FILES:${PN}-unittest = "\ + ${bindir}/unittest-nnstreamer/* \ + ${libdir}/libnnstreamer_unittest_util.so \ + ${libdir}/libcppfilter_test.so \ + ${libdir}/nnstreamer/customfilters/* \ + ${libdir}/nnstreamer/unittest/* \ +" + +# Libraries are unversioned, and the main package requires the symlink +# /usr/lib/libnnstreamer.so -> /usr/lib64/gstreamer-1.0/libnnstreamer.so, +# so disable QA dev-so +INSANE_SKIP:${PN} = "dev-so" +# The python3 package requires the symlink /usr/lib/python3.13/site-packages/nnstreamer_python.so, +# so disable QA dev-so +INSANE_SKIP:${PN}-python3 = "dev-so" +# The unittest package /usr/bin/unittest-nnstreamer/tests/libnnstreamer-edge-custom-test.so is correct, +# so silence the QA error +INSANE_SKIP:${PN}-unittest = "libdir" +# The dbg package requires /usr/bin/unittest-nnstreamer/tests/.debug/libnnstreamer-edge-custom-test.so, +# so silence the QA error +INSANE_SKIP:${PN}-dbg = "libdir" + +do_install:append() { + # Fixes: 076a78ea [TVM/test] Add models for more architectures + bash -c "shopt -s extglob; + rm -f ${D}/${bindir}/unittest-nnstreamer/tests/test_models/models/tvm_add_one_!(${HOST_ARCH}).so_; + shopt -u extglob;" + + # Check if python3 is enabled then install python module + if ${@bb.utils.contains('PACKAGECONFIG', 'python3', 'true', 'false', d)}; then + install -d ${D}${PYTHON_SITEPACKAGES_DIR}/ + ln -sf ${libdir}/nnstreamer_python3.so ${D}${PYTHON_SITEPACKAGES_DIR}/nnstreamer_python.so + fi +} + +PACKAGE_ARCH = "${MACHINE_SOCARCH}"