Graph Composer Sample Extensions

I am trying to build a set of extensions for Graph Composer… The Documentation refers to several samples but I can’t find that code?

Where can we get these examples?

Referenced:
NvDsSampleExt
NvDsSampleProbeMessageMetaCreation
NvDsSampleSourceManipulator
NvDsSampleAudioTemplateLib
NvDsSampleVideoTemplateLib

I would really like to take a look at the sample extensions, but the biggest issue for me right now is the Bazel and Graph Composer build structure… I’m having a heck of a time figuring out how to structure the code directories so I can build the examples from the documentation and the includes from the registry import commands (from This Topic). How am I supposed to structure the directories and build files to build the examples without changing the include pathing (such that it’ll break in future updates).

class NvDsSimpleComponent : INvDsComponent contains
#include “extensions/nvdsinterface/interfaces.hpp”

but nvds_probe_connector.hpp contains
#include “nvdsinterface/interfaces.hpp”

and even if I change NvDsSimpleComponent to use #include “nvdsinterface/interfaces.hpp” and include those files in my project, I get errors compiling nvds_probe_connector.hpp…

Do you mean you want the source code for NvDsSampleExt?

For extension development, there is document Development Workflow — DeepStream 6.1 Release documentation (nvidia.com)

The extensions source code is not open source.

@Fiona.Chen
From your documentation:
“The component NvDsSampleProbeMessageMetaCreation provided as part of the sample extension is a complete sample implementation of INvDsInPlaceDataHandler interface.”
“The component NvDsSampleSourceManipulator provided as part of the sample extension is a complete sample implementation demonstrating this.”
NvDsSampleAudioTemplateLib and NvDsSampleVideoTemplateLib are other examples of components acting as configuration providers. These components are part of the sample extension.

I am asking for the “sample extension”/“complete sample implementation” that your documentation calls out to demonstrate how to build a Graph Composer extension. I am mostly running into BAZEL issues trying to get all the libraries included and pathed correctly, but there are other issues that a functional/compilable sample would empower.

1 Like

Please just start with the boiler plate generator provided in /opt/nvidia/graph-composer/extension-dev/. This is the complete sample of “how to build a Graph Composer extension”.

@Fiona.Chen I have followed the instructions in the documentation and I actually have an extension running with 3 components. However, to get the DeepStream/GST side of the extensions running required took some editing of your supplied templates because it doesn’t seem clear how the sources need to be organized nor how the Bazel file needs to be configured to end up with the build environment in the configuration as intended by NVIDIA. It is also not clear how NVIDIA intended DeepStream related libraries like GST and NVDS to be included in the files… Again, I got it working but I don’t think it’s the way intended by NVIDIA and therefore may require extensive rework in the future as NVIDIA release more complete tools. As I noted above, your documentation indicates that there is a:

Look at the bottom of this section:
https://docs.nvidia.com/metropolis/deepstream/dev-guide/text/DS_Zero_Coding_Developing_Extension.html#implementation-of-invdsinplacedatahandler

All I am asking is for that sample implementation so I can see how the source files are organized and how the Includes are intended to be used. I am not a student or an inexperienced developer…

1 Like

I have found several important things with Bazel and the GS registry that I thought that I should share here. There’s still a lot that I haven’t figured out and some that I am not sure of yet, but it’s better than I have found so far. Using this and GST/NVDS based code I’ve been able to create some very functional components for Graph Composer.
/opt/nvidia/graph-composer/extension-dev and specifically /opt/nvidia/graph-composer/extension-dev/build have pretty significant readmes, comments, and code structures that allowed me to figure this out… This is the first time that I have worked with bazel and I’m old, so don’t flame me too bad… :)

  1. Add a section to the WORKSPACE like below to downloads and include the extension headers directly.:
graph_nvidia_extension(
    name = "NvDsInterfaceExt",
    version = "1.0.0",
)

and to the BUILD file

graph_cc_extension(
  ...
    srcs = [
        "**ExtensionName**.cpp",
        "**ComponentName1**.cpp",
        "**ComponentName2**.cpp",
        ...
    ],
    hdrs = [
        "**ComponentName1**.hpp",
        "**ComponentName2**.hpp",
        ...
    ],
    deps = [
        ...
        "@NvDsInterfaceExt",
        ...
    ],
    ...
)
...
register_extension(
   ...
    ngc_dependencies = {
         ...
        "NvDsInterfaceExt": "1.0.0",
         ...
    },
    ...
)
  1. To add external libraries add a section to WORKSPACE like:
new_local_repository(
    name = "gstreamer",
    path = "/usr/include/gstreamer-1.0/",
    build_file = "third_party/gstreamer.BUILD",
)

Then add a file like gstreamer.BUILD (or whatever) to a third_party directory directly under the directory containing the WORKSPACE:

cc_library(
    name = "gstreamer",
    hdrs = glob(["**/*.h"]),
    deps = [],
    includes = ["",],
    visibility = ["//visibility:public"],
)

(**extension_root**/third_party/gstreamer.BUILD where **extension root** is the directory with the WORKSPACE file)

and to the BUILD file

...
register_extension(
   ...
    ngc_dependencies = {
         ...
        "@gstreamer",
         ...
    },
    ...
)
  1. To include deepstream add a section to WORKSPACE like:
new_local_repository(
    name = "DeepStream",
    path = "/opt/nvidia/deepstream/deepstream-6.1/sources/",
    build_file = "third_party/DeepStream.BUILD",
)

and create a **extension_root**/third_party/DeepStream.BUILD with content like:

cc_library(
    name = "DeepStream",
    hdrs = glob(["**/*.h"]),
    deps = [],
    includes = ["includes/",],
    visibility = ["//visibility:public"],
)
  1. To add a platform shared library: (the best way that I can figure out) first create a local repository for the headers and each platform type in the WORKSPACE (glib-2.0/include/glibconfig.h is different for the different platforms and the libglib-2.0.so ships with the platform image):
new_local_repository(
    name = "glib",
    path = "/usr/include/glib-2.0/",
    build_file = "third_party/glib.BUILD",
)

new_local_repository(
    name = "x86_64",
    path = "/usr/lib/x86_64-linux-gnu/",
    build_file = "third_party/config.BUILD",
)

new_local_repository(
    name = "aarch64",
    path = "/home/***Your User***/nvidia/nvidia_sdk/JetPack_5.0.1_DP_Linux_JETSON_XAVIER_NX_TARGETS/Linux_for_Tegra/rootfs/usr/lib/aarch64-linux-gnu/",
    build_file = "third_party/config.BUILD",
)

then create a something like this as a config.BUILD:

cc_library(
    name = "config",
    hdrs = glob(["**/*.h"]),
    deps = [":glibso"],
    includes = ["glib-2.0/include/",],
    visibility = ["//visibility:public"],
)

cc_import(
    name = "glibso",
    interface_library = "libglib-2.0.so",
    system_provided = 1,
)

and something like this for the glib.BUILD:

cc_library(
    name = "glib",
    hdrs = glob(["**/*.h"]),
    deps = select({
        "@com_extension_dev//build:platform_x86_64": ["@x86_64//:config",],
        "@com_extension_dev//build:platform_jetson": ["@aarch64//:config",],
    }),
    includes = [""],
    visibility = ["//visibility:public"],
)
  1. Sample Directory Structure:
    Directory Structure for above examples:
[ExtensionName]
  extensions
    [ExtensionName]
      BUILD
      [ExtensionName].cpp
      [ComponentName1].h
      [ComponentName1].c
      [ComponentName2].h
      [ComponentName2].c
  third_party
    config.BUILD
    DeepStream.BUILD
    glib.BUILD
    gstreamer.BUILD
  1. Sample WORKSPACE (redacted):

_workspace_name = "**YourExtensionName**"
workspace(name = _workspace_name)

local_repository(
    name = "com_extension_dev",
    path = "/opt/nvidia/graph-composer/extension-dev"
)

load(
    "@com_extension_dev//build:graph_extension.bzl",
    "graph_nvidia_extension",
)

load("@com_extension_dev//build/toolchain:toolchain.bzl", "toolchain_configure")
load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

toolchain_configure(name = "toolchain")

new_git_repository(
    name = "yaml-cpp",
    build_file = "@com_extension_dev//build:third_party/yaml-cpp.BUILD",
    commit = "9a3624205e8774953ef18f57067b3426c1c5ada6",
    remote = "https://github.com/jbeder/yaml-cpp.git",
    shallow_since = "1569430560 -0700",
)

http_archive(
    name = "rules_python",
    url = "https://github.com/bazelbuild/rules_python/releases/download/0.1.0/rules_python-0.1.0.tar.gz",
    sha256 = "b6d46438523a3ec0f3cead544190ee13223a52f6a6765a29eae7b7cc24cc83a0",
)

graph_nvidia_extension(
    name = "StandardExtension",
    version = "2.0.0",
)

graph_nvidia_extension(
    name = "MultimediaExtension",
    version = "2.0.0",
)

graph_nvidia_extension(
    name = "NvDsBaseExt",
    version = "1.0.0",
)

graph_nvidia_extension(
    name = "NvDsInterfaceExt",
    version = "1.0.0",
)

new_local_repository(
    name = "gstreamer",
    path = "/usr/include/gstreamer-1.0/",
    build_file = "third_party/gstreamer.BUILD",
)

new_local_repository(
    name = "glib",
    path = "/usr/include/glib-2.0/",
    build_file = "third_party/glib.BUILD",
)

new_local_repository(
    name = "x86_64",
    path = "/usr/lib/x86_64-linux-gnu/",
    build_file = "third_party/config.BUILD",
)

new_local_repository(
    name = "aarch64",
    path = "/home/**your user**/nvidia/nvidia_sdk/JetPack_5.0.1_DP_Linux_JETSON_XAVIER_NX_TARGETS/Linux_for_Tegra/rootfs/usr/lib/aarch64-linux-gnu/",
    build_file = "third_party/config.BUILD",
)

new_local_repository(
    name = "DeepStream",
    path = "/opt/nvidia/deepstream/deepstream-6.1/sources/",
    build_file = "third_party/DeepStream.BUILD",
)
  1. Sample BUILD File (redacted):
load("@com_extension_dev//build:graph_extension.bzl", "graph_cc_extension")
load("@com_extension_dev//build:registry.bzl", "register_extension")

exports_files(["LICENSE"])

graph_cc_extension(
    name = "**YourExtensionName**",
    srcs = [
        "**ExtensionName**.cpp",
        "**ComponentName1**.cpp",
        "**ComponentName2**.cpp",
        ...
    ],
    hdrs = [
        "**ComponentName1**.hpp",
        "**ComponentName2**.hpp",
        ...
    ],
    deps = [
        "@StandardExtension",
        "@NvDsBaseExt",
        "@NvDsInterfaceExt",
        "@DeepStream",
        "@glib",
        "@gstreamer",
    ] ,
    copts = [
        ],
)

register_extension(
    name = "register_**YourExtensionName**_ext",
    badges = [""],
    extension = "PmsiDsInsightExt",
    labels = [
        "something",
        "something else",
    ],
    license = "LICENSE",
    license_file = ":LICENSE",
    ngc_dependencies = {
        "StandardExtension": "2.0.0",
        "MultimediaExtension": "2.0.0",
        "NvDsBaseExt": "1.0.0",
        "NvDsInterfaceExt": "1.0.0",
    },
    priority = "1",
    git_repository = "",
    url = "www.example.com",
    uuid = "**YourUUID**",
    version = "1.0.0",
    visibility = ["//visibility:public"],
)
2 Likes

No answers?

There are bazel document for reference: Concepts and terminology - Bazel main

Bazel Tutorial: Build a C++ Project

@Fiona.Chen I did go through Bazel documentation, but that didn’t help determine how the NVIDIA GXF plugin system expected things to work… I finally dug through the .bzl files and figured that part out…

I am still waiting for the examples promised in the documentation.

1 Like

One year later, same problems when trying to build a custom GXF extension. I’m facing the exact same issues as @Nerdx86 and I found this post very helpful. Thank you, @Nerdx86.

With all due respect, Nvidia team, the documentation is incomplete on this specific topic and has to be reworked/tuned.