From ea388239959c33728ed029e5cc8e3badf3214b49 Mon Sep 17 00:00:00 2001 From: Emily Date: Fri, 8 Aug 2025 21:49:56 +0100 Subject: [PATCH] dcgm: 3.3.9 -> 4.3.1 --- pkgs/by-name/dc/dcgm/fix-includes.patch | 110 ----------- pkgs/by-name/dc/dcgm/fix-paths.patch | 252 ++++++++++++++++++++++++ pkgs/by-name/dc/dcgm/package.nix | 85 +++++--- 3 files changed, 307 insertions(+), 140 deletions(-) delete mode 100644 pkgs/by-name/dc/dcgm/fix-includes.patch create mode 100644 pkgs/by-name/dc/dcgm/fix-paths.patch diff --git a/pkgs/by-name/dc/dcgm/fix-includes.patch b/pkgs/by-name/dc/dcgm/fix-includes.patch deleted file mode 100644 index 2f15ddca1f7e..000000000000 --- a/pkgs/by-name/dc/dcgm/fix-includes.patch +++ /dev/null @@ -1,110 +0,0 @@ -diff --git a/common/CudaWorker/DcgmDgemm.cpp b/common/CudaWorker/DcgmDgemm.cpp -index 8d33a3256e..6b3284258d 100644 ---- a/common/CudaWorker/DcgmDgemm.cpp -+++ b/common/CudaWorker/DcgmDgemm.cpp -@@ -17,6 +17,7 @@ - - #include - #include -+#include - - #define CU_CHK(op) \ - if (auto const status = op; status != CUBLAS_STATUS_SUCCESS) \ -@@ -122,4 +123,4 @@ - return CUBLAS_STATUS_SUCCESS; - } - --} // namespace DcgmNs -\ No newline at end of file -+} // namespace DcgmNs -diff --git a/common/DcgmError.h b/common/DcgmError.h -index 8638cdceb1..e8d817c0d4 100644 ---- a/common/DcgmError.h -+++ b/common/DcgmError.h -@@ -17,6 +17,7 @@ - - #include - #include -+#include - - #include - #include -diff --git a/common/DcgmStringHelpers.cpp b/common/DcgmStringHelpers.cpp -index b41917e3b7..1fe63980c7 100644 ---- a/common/DcgmStringHelpers.cpp -+++ b/common/DcgmStringHelpers.cpp -@@ -17,6 +17,7 @@ - - #include - #include -+#include - - /*****************************************************************************/ - void dcgmTokenizeString(const std::string &src, const std::string &delimiter, std::vector &tokens) -diff --git a/dcgmi/CommandOutputController.cpp b/dcgmi/CommandOutputController.cpp -index 5057205564..8520171efa 100644 ---- a/dcgmi/CommandOutputController.cpp -+++ b/dcgmi/CommandOutputController.cpp -@@ -24,6 +24,7 @@ - #include "dcgm_agent.h" - #include - #include -+#include - #include - #include - #include -diff --git a/dcgmi/Diag.h b/dcgmi/Diag.h -index a326f7b949..563fb3c9c0 100755 ---- a/dcgmi/Diag.h -+++ b/dcgmi/Diag.h -@@ -24,6 +24,7 @@ - #define DIAG_H_ - - #include -+#include - - #include "Command.h" - #include "CommandOutputController.h" -diff --git a/hostengine/src/HostEngineOutput.cpp b/hostengine/src/HostEngineOutput.cpp -index 23c6ca9f54..798b83b3e4 100644 ---- a/hostengine/src/HostEngineOutput.cpp -+++ b/hostengine/src/HostEngineOutput.cpp -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - - namespace - { -@@ -365,4 +366,4 @@ - } - } - os << std::endl; --} -\ No newline at end of file -+} -diff --git a/nvvs/src/NvvsCommon.cpp b/nvvs/src/NvvsCommon.cpp -index 8f7888649b..1604d9dabe 100644 ---- a/nvvs/src/NvvsCommon.cpp -+++ b/nvvs/src/NvvsCommon.cpp -@@ -15,6 +15,7 @@ - */ - #include - #include -+#include - #include - #include - -diff --git a/sdk/nvidia/nvml/nvml_loader/nvml_loader.cpp b/sdk/nvidia/nvml/nvml_loader/nvml_loader.cpp -index 9eebeaf1c4..6e21201229 100644 ---- a/sdk/nvidia/nvml/nvml_loader/nvml_loader.cpp -+++ b/sdk/nvidia/nvml/nvml_loader/nvml_loader.cpp -@@ -20,6 +20,7 @@ - - #include - #include -+#include - - static void *g_nvmlLib = 0; - static std::atomic_uint32_t g_nvmlStaticLibResetHooksCount = 1; diff --git a/pkgs/by-name/dc/dcgm/fix-paths.patch b/pkgs/by-name/dc/dcgm/fix-paths.patch new file mode 100644 index 000000000000..86581f406986 --- /dev/null +++ b/pkgs/by-name/dc/dcgm/fix-paths.patch @@ -0,0 +1,252 @@ +diff --git a/common/LsHw.cpp b/common/LsHw.cpp +index 8d0f35cd89..12fe26957f 100644 +--- a/common/LsHw.cpp ++++ b/common/LsHw.cpp +@@ -145,7 +145,7 @@ + { + static std::string const cmd = "lshw -json"; + std::string cmdOutput; +- static std::array const cmdPathPrefix { "/usr/bin/", "/usr/sbin/" }; ++ static std::array const cmdPathPrefix { "@lshw@/bin/" }; + + dcgmReturn_t result = DCGM_ST_OK; + for (auto const &prefix : cmdPathPrefix) +@@ -162,4 +162,4 @@ + } + + return cmdOutput; +-} +\ No newline at end of file ++} +diff --git a/common/tests/LsHwTests.cpp b/common/tests/LsHwTests.cpp +index edb65e599e..5950fb8d9e 100644 +--- a/common/tests/LsHwTests.cpp ++++ b/common/tests/LsHwTests.cpp +@@ -609,7 +609,7 @@ + std::unique_ptr checker = std::make_unique(); + checker->MockIsRoot(true); + std::unique_ptr runCmdHelper = std::make_unique(); +- runCmdHelper->MockCmdOutput("/usr/bin/lshw -json", DCGM_ST_OK, lshwMultipleCpusAbridgedValidJson); ++ runCmdHelper->MockCmdOutput("@lshw@/bin/lshw -json", DCGM_ST_OK, lshwMultipleCpusAbridgedValidJson); + + LsHw lshw; + lshw.SetChecker(std::move(checker)); +@@ -626,7 +626,7 @@ + std::unique_ptr checker = std::make_unique(); + checker->MockIsRoot(true); + std::unique_ptr runCmdHelper = std::make_unique(); +- runCmdHelper->MockCmdOutput("/usr/bin/lshw -json", DCGM_ST_OK, lshwSingleCpuAbridgedValidJson); ++ runCmdHelper->MockCmdOutput("@lshw@/bin/lshw -json", DCGM_ST_OK, lshwSingleCpuAbridgedValidJson); + + LsHw lshw; + lshw.SetChecker(std::move(checker)); +@@ -642,7 +642,7 @@ + std::unique_ptr checker = std::make_unique(); + checker->MockIsRoot(true); + std::unique_ptr runCmdHelper = std::make_unique(); +- runCmdHelper->MockCmdOutput("/usr/bin/lshw -json", DCGM_ST_OK, lshwSingleCpuNoSerialNumberAbridgedValidJson); ++ runCmdHelper->MockCmdOutput("@lshw@/bin/lshw -json", DCGM_ST_OK, lshwSingleCpuNoSerialNumberAbridgedValidJson); + + LsHw lshw; + lshw.SetChecker(std::move(checker)); +@@ -658,7 +658,7 @@ + std::unique_ptr checker = std::make_unique(); + checker->MockIsRoot(true); + std::unique_ptr runCmdHelper = std::make_unique(); +- runCmdHelper->MockCmdOutput("/usr/bin/lshw -json", DCGM_ST_OK, lshwSingleNonNvidiaCpuAbridgedValidJson); ++ runCmdHelper->MockCmdOutput("@lshw@/bin/lshw -json", DCGM_ST_OK, lshwSingleNonNvidiaCpuAbridgedValidJson); + + LsHw lshw; + lshw.SetChecker(std::move(checker)); +@@ -673,7 +673,7 @@ + std::unique_ptr checker = std::make_unique(); + checker->MockIsRoot(true); + std::unique_ptr runCmdHelper = std::make_unique(); +- runCmdHelper->MockCmdOutput("/usr/bin/lshw -json", DCGM_ST_OK, lshwIncorrectIdValueTypeJson); ++ runCmdHelper->MockCmdOutput("@lshw@/bin/lshw -json", DCGM_ST_OK, lshwIncorrectIdValueTypeJson); + + LsHw lshw; + lshw.SetChecker(std::move(checker)); +@@ -687,7 +687,7 @@ + std::unique_ptr checker = std::make_unique(); + checker->MockIsRoot(true); + std::unique_ptr runCmdHelper = std::make_unique(); +- runCmdHelper->MockCmdOutput("/usr/bin/lshw -json", DCGM_ST_OK, lshwMissingCpuJson); ++ runCmdHelper->MockCmdOutput("@lshw@/bin/lshw -json", DCGM_ST_OK, lshwMissingCpuJson); + + LsHw lshw; + lshw.SetChecker(std::move(checker)); +@@ -702,7 +702,7 @@ + std::unique_ptr checker = std::make_unique(); + checker->MockIsRoot(true); + std::unique_ptr runCmdHelper = std::make_unique(); +- runCmdHelper->MockCmdOutput("/usr/bin/lshw -json", DCGM_ST_OK, lshwBadSyntaxJson); ++ runCmdHelper->MockCmdOutput("@lshw@/bin/lshw -json", DCGM_ST_OK, lshwBadSyntaxJson); + + LsHw lshw; + lshw.SetChecker(std::move(checker)); +@@ -716,6 +716,7 @@ + { + SECTION("Will try /usr/sbin/") + { ++ SKIP("Nixpkgs patches this out"); + std::unique_ptr checker = std::make_unique(); + checker->MockIsRoot(true); + std::unique_ptr runCmdHelper = std::make_unique(); +@@ -730,4 +731,4 @@ + REQUIRE(cpuSerials.value()[0] == "0x000000017820B1C80400000015FF81C0"); + REQUIRE(cpuSerials.value()[1] == "0x000000017820B1C8040000000A0200C0"); + } +-} +\ No newline at end of file ++} +diff --git a/modules/diag/DcgmDiagManager.cpp b/modules/diag/DcgmDiagManager.cpp +index d0a75dcede..ccd4347719 100644 +--- a/modules/diag/DcgmDiagManager.cpp ++++ b/modules/diag/DcgmDiagManager.cpp +@@ -253,7 +253,7 @@ + int result; + + // Default NVVS binary path +- cmd = "/usr/libexec/datacenter-gpu-manager-4/nvvs"; ++ cmd = "@dcgm_out@/libexec/datacenter-gpu-manager-4/nvvs"; + + // Check for NVVS binary path enviroment variable + value = std::getenv("NVVS_BIN_PATH"); +diff --git a/modules/mndiag/dcgm_mndiag_structs.hpp b/modules/mndiag/dcgm_mndiag_structs.hpp +index 40e61a8fd0..7e43ce8bed 100644 +--- a/modules/mndiag/dcgm_mndiag_structs.hpp ++++ b/modules/mndiag/dcgm_mndiag_structs.hpp +@@ -33,8 +33,8 @@ + constexpr std::string_view ENV_ALLOW_RUN_AS_ROOT = "DCGM_MPIRUN_ALLOW_RUN_AS_ROOT"; + + // Default paths +-constexpr std::string_view DEFAULT_MPIRUN_PATH = "/usr/bin/mpirun"; +-constexpr std::string_view DEFAULT_MNUBERGEMM_PATH = "/usr/libexec/datacenter-gpu-manager-4/plugins/cuda12/mnubergemm"; ++constexpr std::string_view DEFAULT_MPIRUN_PATH = "@mpi@/bin/mpirun"; ++constexpr std::string_view DEFAULT_MNUBERGEMM_PATH = "@dcgm_out@/libexec/datacenter-gpu-manager-4/plugins/cuda12/mnubergemm"; + } //namespace MnDiagConstants + + // Message types +diff --git a/modules/mndiag/tests/MnDiagManagerTests.cpp b/modules/mndiag/tests/MnDiagManagerTests.cpp +index 40dbda3b72..5ec8dafa1c 100644 +--- a/modules/mndiag/tests/MnDiagManagerTests.cpp ++++ b/modules/mndiag/tests/MnDiagManagerTests.cpp +@@ -2228,7 +2228,7 @@ + mockStateMachine->SetMnubergemmPathCallback([&capturedPath](std::string const &path) { capturedPath = path; }); + + // Set env to custom path +- std::string customPath = "/bin/true"; ++ std::string customPath = "@coreutils@/bin/true"; + setenv(MnDiagConstants::ENV_MNUBERGEMM_PATH.data(), customPath.c_str(), 1); + + auto mockCoreProxy = std::make_unique(); +@@ -3112,7 +3112,7 @@ + { + // Save current environment state + auto savedPath = saveEnvVar(MnDiagConstants::ENV_MNUBERGEMM_PATH.data()); +- std::string customPath = "/bin/true"; ++ std::string customPath = "@coreutils@/bin/true"; + setenv(MnDiagConstants::ENV_MNUBERGEMM_PATH.data(), customPath.c_str(), 1); + + // Setup mock DCGM API with callback to inspect request +@@ -3251,7 +3251,7 @@ + auto savedPath = saveEnvVar(MnDiagConstants::ENV_MNUBERGEMM_PATH.data()); + + // Use a known executable that exists +- std::string customPath = "/bin/true"; ++ std::string customPath = "@coreutils@/bin/true"; + setenv(MnDiagConstants::ENV_MNUBERGEMM_PATH.data(), customPath.c_str(), 1); + + // Call the method and verify path +diff --git a/modules/mndiag/tests/MnDiagProcessUtilsTests.cpp b/modules/mndiag/tests/MnDiagProcessUtilsTests.cpp +index 633e327c42..168ed91db2 100644 +--- a/modules/mndiag/tests/MnDiagProcessUtilsTests.cpp ++++ b/modules/mndiag/tests/MnDiagProcessUtilsTests.cpp +@@ -71,7 +71,7 @@ + { + // Start a long-running process + DcgmNs::Common::Subprocess::ChildProcessBuilder builder; +- builder.SetExecutable("/bin/sleep").AddArg("0.5"); ++ builder.SetExecutable("@coreutils@/bin/sleep").AddArg("0.5"); + + IoContext ioContext {}; + auto process = std::make_unique(builder.Build(ioContext)); +@@ -155,4 +155,4 @@ + + REQUIRE(result.empty()); + } +-} +\ No newline at end of file ++} +diff --git a/modules/mndiag/tests/MpiRunnerTests.cpp b/modules/mndiag/tests/MpiRunnerTests.cpp +index 526c80fd47..1e8596d3b7 100755 +--- a/modules/mndiag/tests/MpiRunnerTests.cpp ++++ b/modules/mndiag/tests/MpiRunnerTests.cpp +@@ -60,7 +60,7 @@ + + std::string GetMpiBinPath() const override + { +- return "/bin/bash"; ++ return "@shell@"; + } + + private: +@@ -138,9 +138,9 @@ + runner.ConstructMpiCommand(&config); + + // Verify command construction +- REQUIRE(runner.GetMpiBinPath() == "/bin/bash"); ++ REQUIRE(runner.GetMpiBinPath() == "@shell@"); + std::string fullCommand = runner.GetLastCommand(); +- REQUIRE(fullCommand.find("/bin/bash -c") != std::string::npos); ++ REQUIRE(fullCommand.find("@shell@ -c") != std::string::npos); + REQUIRE(fullCommand.find("sleep 1") != std::string::npos); + REQUIRE(fullCommand.find("Output from sleep process") != std::string::npos); + +@@ -244,4 +244,4 @@ + // Test with invalid parameter (null pointer) + REQUIRE(runner.PopulateResponse(nullptr, nodeInfoMap_t()) == DCGM_ST_BADPARAM); + } +-} +\ No newline at end of file ++} +diff --git a/modules/sysmon/DcgmCpuTopology.cpp b/modules/sysmon/DcgmCpuTopology.cpp +index 786d3877fc..ccbeccc81d 100644 +--- a/modules/sysmon/DcgmCpuTopology.cpp ++++ b/modules/sysmon/DcgmCpuTopology.cpp +@@ -136,7 +136,7 @@ + { + static std::string cmd = "lscpu --json"; + std::string cmdOutput; +- static std::array cmdPathPrefix = { "/usr/bin/", "/usr/sbin/" }; ++ static std::array cmdPathPrefix = { "@util-linux@/bin/" }; + + dcgmReturn_t result = DCGM_ST_OK; + for (auto const &prefix : cmdPathPrefix) +diff --git a/nvvs/plugin_src/nvbandwidth/NVBandwidthPlugin.cpp b/nvvs/plugin_src/nvbandwidth/NVBandwidthPlugin.cpp +index 261bba4490..4d439ad452 100644 +--- a/nvvs/plugin_src/nvbandwidth/NVBandwidthPlugin.cpp ++++ b/nvvs/plugin_src/nvbandwidth/NVBandwidthPlugin.cpp +@@ -238,7 +238,7 @@ + std::vector const search_paths + = { GetCurrentModuleLocation(), + fmt::format("./apps/nvvs/plugins/cuda{}", m_cudaDriverMajorVersion), +- fmt::format("/usr/libexec/datacenter-gpu-manager-4/plugins/cuda{}", m_cudaDriverMajorVersion), ++ fmt::format("@dcgm_out@/libexec/datacenter-gpu-manager-4/plugins/cuda{}", m_cudaDriverMajorVersion), + GetNvvsBinCheckPath(m_cudaDriverMajorVersion) }; + std::stringstream path_buf; + +diff --git a/testing/TestDiagManager.cpp b/testing/TestDiagManager.cpp +index 8087123a49..a6333b3a3d 100644 +--- a/testing/TestDiagManager.cpp ++++ b/testing/TestDiagManager.cpp +@@ -236,7 +236,7 @@ + if (nvvsPathEnv) + nvvsBinPath = std::string(nvvsPathEnv) + "/nvvs"; + else +- nvvsBinPath = "/usr/libexec/datacenter-gpu-manager-4/nvvs"; ++ nvvsBinPath = "@dcgm_out@/libexec/datacenter-gpu-manager-4/nvvs"; + + std::string diagResponseVersionArg = fmt::format("--response-version {}", dcgmDiagResponse_version12); + expected.push_back(nvvsBinPath + " --channel-fd 3 " + diagResponseVersionArg diff --git a/pkgs/by-name/dc/dcgm/package.nix b/pkgs/by-name/dc/dcgm/package.nix index 396d243bb61c..140cf98257c1 100644 --- a/pkgs/by-name/dc/dcgm/package.nix +++ b/pkgs/by-name/dc/dcgm/package.nix @@ -3,20 +3,27 @@ stdenv, fetchFromGitHub, autoAddDriverRunpath, - catch2, + catch2_3, cmake, + ctestCheckHook, + coreutils, + mpi, + mpiCheckPhaseHook, ninja, cudaPackages_11, cudaPackages_12, - boost, - fmt_9, + boost186, + fmt_10, git, jsoncpp, libevent, + lshw, plog, python3, + replaceVars, symlinkJoin, tclap_1_4, + util-linux, yaml-cpp, }: let @@ -67,18 +74,27 @@ let in stdenv.mkDerivation rec { pname = "dcgm"; - version = "3.3.9"; # N.B: If you change this, be sure prometheus-dcgm-exporter supports this version. + version = "4.3.1"; # N.B: If you change this, be sure prometheus-dcgm-exporter supports this version. src = fetchFromGitHub { owner = "NVIDIA"; repo = "DCGM"; - tag = "v${version}"; - hash = "sha256-PysxuN5WT7GB0oOvT5ezYeOau6AMVDDWE5HOAcmqw/Y="; + # No tag for 4.3.1 yet. + #tag = "v${version}"; + rev = "1477d8785e899ab3450fdff2b486102e9bed096b"; + hash = "sha256-FebqG28aodENGLNBBbiGpckzzeuP+y44dCALtYnN1yU="; }; patches = [ - ./fix-includes.patch ./dynamic-libs.patch + (replaceVars ./fix-paths.patch { + inherit coreutils; + inherit util-linux; + inherit lshw; + inherit mpi; + inherit (stdenv) shell; + dcgm_out = null; + }) ]; hardeningDisable = [ "all" ]; @@ -99,17 +115,39 @@ stdenv.mkDerivation rec { buildInputs = [ # Header-only - boost - catch2 + boost186 + catch2_3 plog.dev tclap_1_4 - fmt_9 + fmt_10 yaml-cpp jsoncpp libevent ]; + nativeCheckInputs = [ + mpi + ctestCheckHook + mpiCheckPhaseHook + ]; + + disabledTests = [ + # Fail due to lack of `/sys` in the sandbox. + "DcgmModuleSysmon::PauseResume Module resumed after initialization" + "DcgmModuleSysmon PauseResume Module rejects invalid messages" + "DcgmModuleSysmon PauseResume Module accepts valid messages" + "DcgmModuleSysmon Watches" + "DcgmModuleSysmon maxSampleAge" + "DcgmModuleSysmon::CalculateCoreUtilization" + "DcgmModuleSysmon::ParseProcStatCpuLine" + "DcgmModuleSysmon::ParseThermalFileContentsAndStore" + "DcgmModuleSysmon::PopulateTemperatureFileMap" + "DcgmModuleSysmon::ReadCoreSpeed" + "DcgmModuleSysmon::ReadTemperature" + "Sysmon: initialize module" + ]; + # Add our paths to the CMake flags so FindCuda.cmake can find them. cmakeFlags = lib.concatMap mkCudaFlags cudaPackageSets; @@ -117,31 +155,18 @@ stdenv.mkDerivation rec { env.NIX_CFLAGS_COMPILE = "-Wno-error"; doCheck = true; + dontUseNinjaCheck = true; - checkPhase = '' - runHook preCheck - - ctest -j $NIX_BUILD_CORES --output-on-failure --exclude-regex ${ - lib.escapeShellArg ( - lib.concatMapStringsSep "|" (test: "^${lib.escapeRegex test}$") [ - "DcgmModuleSysmon Watches" - "DcgmModuleSysmon maxSampleAge" - "DcgmModuleSysmon::CalculateCoreUtilization" - "DcgmModuleSysmon::ParseProcStatCpuLine" - "DcgmModuleSysmon::ParseThermalFileContentsAndStore" - "DcgmModuleSysmon::PopulateTemperatureFileMap" - "DcgmModuleSysmon::ReadCoreSpeed" - "DcgmModuleSysmon::ReadTemperature" - "Sysmon: initialize module" - ] - ) - } - - runHook postCheck + postPatch = '' + while read -r -d "" file; do + substituteInPlace "$file" --replace-quiet @dcgm_out@ "$out" + done < <(find . '(' -name '*.h' -or -name '*.cpp' ')' -print0) ''; disallowedReferences = lib.concatMap getCudaPackages cudaPackageSets; + __structuredAttrs = true; + meta = with lib; { description = "Data Center GPU Manager (DCGM) is a daemon that allows users to monitor NVIDIA data-center GPUs"; homepage = "https://developer.nvidia.com/dcgm";