Compile DeepStream

I’d like to compile DeepStream, a Nvidia’s set of Gstreamer plugins, from sources as a Nix derivation.
There are sources in a Docker image nvcr.io/nvidia/deepstream:6.3-triton-multiarch, for example. Directory structure is following:

ls sources/gst-plugins/gst-nvinfer sources/includes/
root@433526ce47e4:/opt/nvidia/deepstream/deepstream-6.3# ls /opt/nvidia/deepstream/deepstream-6.3/sources/
SONYCAudioClassifier   TritonOnnxYolo  gst-plugins  libs                       objectDetector_Yolo  tracker_ReID
TritonBackendEnsemble  apps            includes     objectDetector_FasterRCNN  tools
root@433526ce47e4:/opt/nvidia/deepstream/deepstream-6.3# ls /opt/nvidia/deepstream/deepstream-6.3/sources/gst-plugins/
gst-dsexample      gst-nvdsaudiotemplate  gst-nvdspostprocess  gst-nvdstexttospeech   gst-nvinferserver  gst-nvmultistream2    gst-nvvideotestsrc
gst-nvdewarper     gst-nvdsmetautils      gst-nvdspreprocess   gst-nvdsvideotemplate  gst-nvmsgbroker    gst-nvmultiurisrcbin
gst-nvdsanalytics  gst-nvdsosd            gst-nvdsspeech       gst-nvinfer            gst-nvmsgconv      gst-nvtracker
root@433526ce47e4:/opt/nvidia/deepstream/deepstream-6.3# ls /opt/nvidia/deepstream/deepstream-6.3/sources/gst-plugins/gst-nvinfer
Makefile        gstnvinfer.h              gstnvinfer_impl.cpp        gstnvinfer_meta_utils.h         gstnvinfer_yaml_parser.cpp
README          gstnvinfer_allocator.cpp  gstnvinfer_impl.h          gstnvinfer_property_parser.cpp  gstnvinfer_yaml_parser.h
gstnvinfer.cpp  gstnvinfer_allocator.h    gstnvinfer_meta_utils.cpp  gstnvinfer_property_parser.h

root@433526ce47e4:/opt/nvidia/deepstream/deepstream-6.3# ls /opt/nvidia/deepstream/deepstream-6.3/sources/includes/
CivetServer.h            gst-nvmessage.h                nvds_analytics_meta.h         nvds_yml_parser.h             nvdsmeta.h
INvDsAllocator.h         gst-nvmultiurisrcbincreator.h  nvds_appctx_server.h          nvdscustomusermeta.h          nvdsmeta_schema.h
NVWarp360.h              gst-nvquery-internal.h         nvds_audio_meta.h             nvdsdummyusermeta.h           nvdsnmos.h
NvDsMemoryAllocator.h    gst-nvquery.h                  nvds_dewarper_meta.h          nvdsgstutils.h                nvdspreprocess_interface.h
civetweb.h               gst_nvdsaudio.h                nvds_latency_meta.h           nvdsinfer.h                   nvdspreprocess_meta.h
config.h                 gstnvdsbufferpool.h            nvds_latency_meta_internal.h  nvdsinfer_context.h           nvdstracker.h
cvcore_headers           gstnvdsinfer.h                 nvds_logger.h                 nvdsinfer_custom_impl.h       nvll_osd_api.h
ds3d                     gstnvdsmeta.h                  nvds_mask_utils.h             nvdsinfer_dbscan.h            nvll_osd_struct.h
gst-nvcommon.h           gstnvdsseimeta.h               nvds_msgapi.h                 nvdsinfer_logger.h            nvmsgbroker.h
gst-nvcustomevent.h      gstnvvideotestsrc.h            nvds_obj_encode.h             nvdsinfer_tlt.h               nvtx_helper.h
gst-nvdscommonconfig.h   nv_aisle_csvparser.hpp         nvds_opticalflow_meta.h       nvdsinfer_utils.h             patterns.h
gst-nvdscustomevent.h    nv_spot_csvparser.hpp          nvds_rest_server.h            nvdsinferserver
gst-nvdscustommessage.h  nvbufaudio.h                   nvds_roi_meta.h               nvdsinferserver_common.proto
gst-nvdssr.h             nvbufsurface.h                 nvds_tracker_meta.h           nvdsinferserver_config.proto
gst-nvevent.h            nvbufsurftransform.h           nvds_version.h                nvdsinferserver_plugin.proto

I’ve tried a flake like the following one:

{
  inputs.nixpkgs.url = "nixpkgs/nixos-24.05";
  outputs = {self, nixpkgs, ...}: {
    packages.x86_64-linux.gst-nv-infer =
      let pkgs = import nixpkgs { system = "x86_64-linux"; config.allowUnfree = true; }; in
      pkgs.stdenv.mkDerivation (_: {
        pname = "gst-plugin-nvinfer";
	version = "6.3";
	outputs = [ "out" "dev" ];
        src = ./.;
        CUDA_VER = "11.8";
        preBuild = "cd ./gst-plugins/gst-nvinfer; export CPATH=$CPATH:${./includes} pwd\n";
        nativeBuildInputs = with pkgs; [ pkg-config gcc ] ++ (with pkgs.cudaPackages_11; [ cuda_nvcc ]);
	buildInputs = with pkgs.gst_all_1; [ gstreamer gstreamermm gst-plugins-base ] ++ (with pkgs.cudaPackages_11; [ cudatoolkit autoAddOpenGLRunpathHook ]);
      });
  };
}

But nix build .#gst-nv-infer fails with a message:

Running phase: buildPhase
build flags: SHELL=/nix/store/306znyj77fv49kwnkpxmb0j2znqpa8bj-bash-5.2p26/bin/bash
g++ -c -o gstnvinfer.o -fPIC -std=c++11 -DDS_VERSION=\"6.3.0\" -I /usr/local/cuda-11.8/include -I ../../includes -I ../gst-nvdspreprocess/include -I ../../libs/nvdsinfer -DNDEBUG -I/nix/store/gm6qzrb5m1vrdaavivvsnrqp0c66gnxb-gstreamer-1.24.2-dev/include/gstreamer-1.0 -I/nix/store/gdr1ghkakyjfdj8bc6n0virwllm4zpwz-glib-2.80.2-dev/include -I/nix/store/gdr1ghkakyjfdj8bc6n0virwllm4zpwz-glib-2.80.2-dev/include/glib-2.0 -I/nix/store/c2v6ycn0sjcpx9ww8x7j4ima6xnpssry-glib-2.80.2/lib/glib-2.0/include -I/nix/store/p587p3wir9g65x3gynf9318dgcz4f499-gst-plugins-base-1.24.2-dev/include/gstreamer-1.0 gstnvinfer.cpp
In file included from gstnvinfer_allocator.h:18,
                 from gstnvinfer.cpp:31:
/nix/store/wwv1hfby5lzp2hkvws1krq4426yjg934-cuda-merged-11.8/include/cudaEGL.h:54:10: fatal error: EGL/egl.h: No such file or directory
   54 | #include "EGL/egl.h"
      |          ^~~~~~~~~~~
compilation terminated.
make: *** [Makefile:49: gstnvinfer.o] Error 1

The only egl.h I could find is /nix/store/*-gst-plugins-base-1.24.2-dev/include/gstreamer-1.0/gst/gl/egl/egl.h (with a lower-case directory name).

I am a bit missed on how to move further, and any suggestions are welcome…

1 Like

You can add libglvnd to your buildInputs. I think that will do it.

1 Like

Thank you! Indeed, egl.h is found now. I continue iteratively to add missing dependencies and try to build.

I’ve made some progress and need some help.

In a flake https://gist.github.com/le-chat/46731da439b8a9765651db53eb11b1f6 there is .#deepstream, where I unpack a deb with DeepStream and try to recompile gst-plugins (patching Makefiles which contain many hard-coded paths). Several plugins fail to build, but I ignore them. nix develop .#gst gives a shell, where rm -r ~/.cache/gstreamer-1.0; gst-inspect-1.0 nvinfer sees a plugin.

There is also nix run .#ds-yolo-run -- ./yolov5.onnx ./video.mp4 who, being run inside devshell, tries to run a full pipeline.

However, an attempt to do this produces error messages like these:

log
GLib (gthread-posix.c): Unexpected error from C library during 'pthread_setspecific': Invalid argument.  Aborting.
GLib (gthread-posix.c): Unexpected error from C library during 'pthread_setspecific': Invalid argument.  Aborting.

(gst-plugin-scanner:3878334): GLib-GObject-CRITICAL **: 15:43:23.935: object GstNvInfer 0xd7df80 finalized while still in-construction
(gst-plugin-scanner:3878334): GLib-GObject-CRITICAL **: 15:43:23.935: object GstNvInfer 0xd7fe70 finalized while still in-construction
(gst-plugin-scanner:3878334): GLib-GObject-CRITICAL **: 15:43:23.935: object GstNvDsOsd 0xda57b0 finalized while still in-construction
...
(gst-plugin-scanner:3878334): GLib-GObject-CRITICAL **: 15:43:23.936: object GstNvMsgBroker 0xdbf5d0 finalized while still in-construction
(gst-plugin-scanner:3878334): GStreamer-WARNING **: 15:43:23.938: Failed to load plugin '/nix/store/qd4qy89axpd2siq6x5pjl7ga17b8fzpa-deepstream-7.1/lib/gstreamer-1.0/libnvdsgst_eglglessink.so': libnvidia-ml.so.1: cannot open shared object file: No such file or directory
(gst-plugin-scanner:3878334): GStreamer-WARNING **: 15:43:23.941: Failed to load plugin '/nix/store/qd4qy89axpd2siq6x5pjl7ga17b8fzpa-deepstream-7.1/lib/gstreamer-1.0/libnvdsgst_inferserver.so': libtritonserver.so: cannot open shared object file: No such file or directory

(gst-plugin-scanner:3878334): GStreamer-WARNING **: 15:43:24.007: Failed to load plugin '/nix/store/qd4qy89axpd2siq6x5pjl7ga17b8fzpa-deepstream-7.1/lib/gstreamer-1.0/libnvdsgst_udp.so': librivermax.so.1: cannot open shared object file: No such file or directory
Error: Could not get cuda device count (cudaErrorStubLibrary)
Failed to parse group property
** ERROR: <gst_nvinfer_parse_config_file:1392>: failed
WARNING: erroneous pipeline: no element "nvv4l2decoder"

Clearly there many problems.
First, from strace it looks like it loads a stub library libcuda.so.1 from cudatoolkit instead of true one from /run/opengl-driver/lib. Let’s start here.

Could someone to get advice how to avoid this?

I’m really not sure. I hope someone else can step in.

Could it be a CUDA version incompatibility with your hardware?

I’ve updated the gist with some fixes. The main one is that auto-path hooks should go to nativeBuildInputs (were misplaced to buildInputs); and also make install didn’t seem to actually replace already existing libraries. I’m also try to use nvh264{dec,enc} instead of v4l2- versions (who doesn’t compile yet).

Now it warns only about nvh264enc, although it comes from gst-plugins-bad and moreover, it has been seen in an environment without deepstream, iirc.

Logs with GST_DEBUG=3 states it doesn’t see libnvidia-encode.so.1, libnvcuvid.so.1, but they both exist in /run/opengl-driver/lib. Gstreamer has a special patch to find them for https://github.com/NixOS/nixpkgs/issues/189217.

GST_DEBUG=3 nix develop .#gst -c nix run .#ds-yolo-run -- ~/Gst/yolov5n.onnx ~/Gst/video.mp4
/tmp/nix-shell.ngIF3B/tmp.WY31TrQQYp
Using pipeline:
----
nvstreammux name=mux live-source=true width=1920 height=1080 batch-size=1
filesrc location=./video.mp4 ! qtdemux ! h264parse ! nvh264dec !
  nvvideoconvert ! mux.sink_0
mux. !
nvinfer config-file-path=./infer.txt !
nvtracker
   ll-lib-file=./deepstream/lib/libnvds_nvmultiobjecttracker.so
   ll-config-file=./NvSORT.yml !
nvstreamdemux name=demux
demux.src_0 ! nvvideoconvert !
  nvdsosd display-text=1 process-mode=1 display-bbox=true ! nvvideoconvert !
  nvh264enc ! h264parse ! qtmux ! filesink location=./result.mp4
^^^^
0:00:00.030666281 1176038       0x70c8a0 WARN                 default gstjackloader.c:187:gst_jack_load_library: Could not open library libjack.so.0, libjack.so.0: cannot open shared object file: No such file or directory
0:00:00.030681861 1176038       0x70c8a0 WARN                 default gstjack.c:108:plugin_init: Failed to load jack library
0:00:00.112943290 1176038       0x70c8a0 WARN                  ladspa gstladspa.c:509:plugin_init:<plugin227> no LADSPA plugins found, check LADSPA_PATH
0:00:00.121344162 1176038       0x70c8a0 WARN                   nvenc gstnvenc.c:928:gst_nvenc_load_library: Could not open library libnvidia-encode.so.1, libnvcuvid.so.1: cannot open shared object file: No such file or directory
0:00:00.593088540 1176038       0x70c8a0 WARN               cudanvrtc gstcudanvrtc.cpp:152:gst_cuda_nvrtc_load_library_once: Could not open nvrtc library libnvrtc.so: cannot open shared object file: No such file or directory
0:00:00.920784097 1176038       0x70c8a0 WARN               vadisplay gstvadisplay_drm.c:142:gst_va_display_drm_create_va_display:<vadisplaydrm0> Failed to open /dev/dri/renderD128: Permission denied
0:00:00.920821461 1176038       0x70c8a0 WARN               vadisplay gstvadisplay_drm.c:142:gst_va_display_drm_create_va_display:<vadisplaydrm1> Failed to open /dev/dri/renderD129: Permission denied
0:00:00.920833437 1176038       0x70c8a0 WARN               vadisplay gstvadisplay_drm.c:142:gst_va_display_drm_create_va_display:<vadisplaydrm2> Failed to open /dev/dri/renderD130: Permission denied
0:00:00.927530495 1176038       0x70c8a0 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x120000: 'AVR (Audio Visual Research)' is not mapped
0:00:00.927542665 1176038       0x70c8a0 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x180000: 'CAF (Apple Core Audio File)' is not mapped
0:00:00.927563261 1176038       0x70c8a0 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x100000: 'HTK (HMM Tool Kit)' is not mapped
0:00:00.927569592 1176038       0x70c8a0 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0xc0000: 'MAT4 (GNU Octave 2.0 / Matlab 4.2)' is not mapped
0:00:00.927574557 1176038       0x70c8a0 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0xd0000: 'MAT5 (GNU Octave 2.1 / Matlab 5.0)' is not mapped
0:00:00.927579543 1176038       0x70c8a0 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x210000: 'MPC (Akai MPC 2k)' is not mapped
0:00:00.927585126 1176038       0x70c8a0 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x230000: 'MPEG-1/2 Audio' is not mapped
0:00:00.927591102 1176038       0x70c8a0 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0xe0000: 'PVF (Portable Voice Format)' is not mapped
0:00:00.927596868 1176038       0x70c8a0 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x160000: 'SD2 (Sound Designer II)' is not mapped
0:00:00.927603493 1176038       0x70c8a0 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x190000: 'WVE (Psion Series 3)' is not mapped
0:00:00.940651804 1176038       0x70c8a0 WARN               vadisplay gstvadisplay_drm.c:142:gst_va_display_drm_create_va_display:<vadisplaydrm3> Failed to open /dev/dri/renderD128: Permission denied
0:00:00.940670710 1176038       0x70c8a0 WARN               vadisplay gstvadisplay_drm.c:142:gst_va_display_drm_create_va_display:<vadisplaydrm4> Failed to open /dev/dri/renderD129: Permission denied
0:00:00.940696826 1176038       0x70c8a0 WARN               vadisplay gstvadisplay_drm.c:142:gst_va_display_drm_create_va_display:<vadisplaydrm5> Failed to open /dev/dri/renderD130: Permission denied
0:00:01.233419242 1176036       0x6fbdf0 WARN                   nvenc gstnvenc.c:928:gst_nvenc_load_library: Could not open library libnvidia-encode.so.1, libnvcuvid.so.1: cannot open shared object file: No such file or directory
0:00:01.729702696 1176036       0x6fbdf0 WARN               cudanvrtc gstcudanvrtc.cpp:152:gst_cuda_nvrtc_load_library_once: Could not open nvrtc library libnvrtc.so: cannot open shared object file: No such file or directory
0:00:02.360230893 1176036       0x6fbdf0 ERROR           GST_PIPELINE gst/parse/grammar.y:630:gst_parse_element_make: no element "nvh264enc"
0:00:02.360346878 1176036       0x6fbdf0 ERROR           GST_PIPELINE gst/parse/grammar.y:1327:priv_gst_parse_yyparse: link has no sink [source=@0xff3410]
0:00:02.360626378 1176036       0x6fbdf0 ERROR           GST_PIPELINE gst/parse/grammar.y:1327:priv_gst_parse_yyparse: link has no source [sink=@0xff4a10]
WARNING: erroneous pipeline: no element "nvh264enc"

It may be a discrepancy of Nix on ubuntu. I’ve re-run on nixos host, and it fails with another message, when loading a model:

0:00:03.650543604 2258889       0x6fcad0 WARN                 nvinfer gstnvinfer.cpp:681:gst_nvinfer_logger:<nvinfer0> NvDsInferContext[UID 1]: Warning from NvDsInferContextImpl::generateBackendContext() <nvdsinfer_context_impl.cpp:2185> [UID = 1]: deserialize backend context from engine from file :/tmp/nix-shell.S1NjWG/tmp.1dd9FYlK0n/model_b1_gpu0_fp32.engine failed, try rebuild
0:00:03.650773476 2258889       0x6fcad0 INFO                 nvinfer gstnvinfer.cpp:684:gst_nvinfer_logger:<nvinfer0> NvDsInferContext[UID 1]: Info from NvDsInferContextImpl::buildModel() <nvdsinfer_context_impl.cpp:2106> [UID = 1]: Trying to create engine from model files
gst-launch-1.0: ../nvdsinfer/nvdsinfer_model_builder.cpp:339: nvdsinfer::TrtModelBuilder::TrtModelBuilder(int, nvinfer1::ILogger&, const std::shared_ptr<nvdsinfer::DlLibHandle>&, bool): Assertion `m_BuilderConfig' failed.
/nix/store/5hvvngvryx5g915qlm46q0syh0756ylh-ds-yolo-run/bin/ds-yolo-run: line 26: 2258886 Aborted

nvdsinfer is not recompiled because of an error:

g++ -c -o nvdsinfer_func_utils.o -fPIC -Wno-deprecated-declarations -std=c++14 -I /usr/local/cuda-12.2/include -I ../../includes -DNDEBUG nvdsinfer_func_utils.cpp
nvdsinfer_func_utils.cpp: In function 'std::string nvdsinfer::dataType2Str(nvinfer1::DataType)':
nvdsinfer_func_utils.cpp:164:34: error: 'kINT64' is not a member of 'nvinfer1::DataType'; did you mean 'kINT8'?
  164 |         case nvinfer1::DataType::kINT64:
      |                                  ^~~~~~
      |                                  kINT8
make: *** [Makefile:62: nvdsinfer_func_utils.o] Error 1
FAILED on /build/root/opt/nvidia/deepstream/deepstream-7.1/sources/libs/nvdsinfer

Probably this should be fixed to nvinfer to work.

kINT64 comes from a newer TensorRT 10. So with a nixos-unstable channel the latest version of my gist a number of compiling plugins is enough to run a pipeline, perform some inference and draw bounding boxes on a video. These boxes look randomly, probably some format or postprocessing issues.

By the way, I haven’t managed out the problem with boxes. I gave it an ONNX model which just reshapes input and added printing results; it looks like input for a model is messed somehow.

Before going to debug their code it would be nice to compile with supported version of CUDA (12.6 instead of 12.3). When I have more time, hopefully I give a try to https://nixos.org/manual/nixpkgs/stable/#cuda for upgrading. But it begins to look too cumbersome…

It may also be an incompatibility with a newer Gstreamer, in this case I completely lost.

1 Like