编写 CUDA 系统信息查询工具)
cuda-samples 实战使用 cuda.core.systemNVML编写 CUDA 系统信息查询工具【免费下载链接】cuda-samplesSamples for CUDA Developers which demonstrates features in CUDA Toolkit项目地址: https://gitcode.com/GitHub_Trending/cu/cuda-samples本篇文章基于 NVIDIA cuda-samples 仓库中的python/1_GettingStarted/systemInfo示例深入讲解如何通过cuda.core.system模块在不初始化 CUDA 上下文的情况下查询驱动版本、NVML 版本、每块 GPU 的元数据算力、显存、PCI、温度、性能状态以及多卡间的拓扑与 P2P 能力。读完本文你将掌握一套可直接复用、适合作为 CUDA 程序运行前体检的轻量级系统探测方案。示例定位为什么需要一套无上下文的系统查询方案在常规 CUDA 开发中获取设备信息通常依赖cudaGetDeviceProperties等 Runtime API而调用这些 API 的前提是 CUDA 驱动已经就绪、环境能够成功初始化。但在实际部署场景中我们往往希望在真正创建 CUDA 上下文之前就确认驱动是否安装、版本是否满足要求系统中有多少块 GPU 可见每块 GPU 的算力、显存、温度等健康状态多卡环境下卡与卡之间的拓扑连接和 P2Ppeer-to-peer读写能力。cuda.core.system正是为这类场景设计的它封装了 NVIDIA Management LibraryNVML可以在没有安装或初始化 CUDA 的前提下直接导入使用天然适合作为轻量级的前置检查pre-flight check工具。本示例的目标很明确——把上述信息一次性打印出来供脚本化巡检、环境验证或调试诊断使用。从仓库结构看本示例位于 python/1_GettingStarted/systemInfo 目录与同目录下的deviceQuery等示例共同构成 CUDA Python 入门系列仓库根 README.md 将其归类为 Introductory scripts 中的一员。核心依赖cuda.core.system 与 NVML 的关系本示例的全部功能都建立在cuda.core之上。cuda.core是 NVIDIA 提供的 Python 包其system子模块对 NVML 做了面向对象的封装让开发者无需直接面对 NVML 的 C API 就能枚举设备、读取传感器数据。从 systemInfo.py 的导入代码可以看到关键事实from cuda.core import system from cuda.core.system import CUDA_BINDINGS_NVML_IS_COMPATIBLE from cuda.core.system.typing import GpuP2PCapsIndex这里有三个值得注意的点导入路径README 明确指出应从顶层cuda.core包导入稳定符号即cuda.core.system而不是cuda.core.experimental下的实验性模块——这是 API 稳定性的保证。兼容性标志CUDA_BINDINGS_NVML_IS_COMPATIBLE是一个布尔常量用于判断当前驱动与 NVML 绑定是否兼容。示例中多处用它做分支不兼容时跳过 NVML 相关查询仅输出用户态驱动版本详见下文源码解析。类型枚举GpuP2PCapsIndex等类型定义在cuda.core.system.typing中用于 P2P 能力查询的索引参数。示例还对导入失败做了友好处理若cuda.core未安装会打印提示并引导用户先执行pip install -r requirements.txt见 systemInfo.py。环境需求与安装软硬件要求README 中列出的需求分为三层类别要求说明硬件一块或多块支持 CUDA 的 NVIDIA GPU查询结果随硬件而异硬件与cuda-python13.x 兼容的驱动驱动决定 NVML 绑定的兼容性软件CUDA Toolkit 13.0 或更新与cuda-python13.x 版本配套软件Python 3.10 或更新仓库工具模块也声明了同样的下限见 cuda_samples_utils.py软件cuda-python13.0.0、cuda-core1.0.0通过requirements.txt安装注意 README 中出现了两种 Python 版本表述Python 3.12 or newer 出现在 Requirements 列表而 Software 小节写的是 Python 3.10 or newer。两者并存的表述说明示例运行的最低要求可以追溯到 3.10而 3.12 是更稳妥的推荐基线。实际以你环境的 Python 版本为准即可。安装步骤cd /path/to/cuda-samples/python/1_GettingStarted/systemInfo pip install -r requirements.txt该目录下的 requirements.txt 内容非常精简仅两个依赖cuda-python13.0.0 cuda-core1.0.0值得注意的是仓库顶层的 python/requirements.txt 还额外声明了cupy-cuda13x14.0.0与numpy2.3.2但那是 Python 示例共用的基础依赖本示例自身只需要cuda-python与cuda-core两个包体现了示例的按需取用设计——不需要 CuPy/NumPy就不引入额外依赖。运行方式基本用法与常用参数进入示例目录后直接运行即可cd cuda-samples/python/1_GettingStarted/systemInfo python systemInfo.py脚本会依次打印驱动/NVML 信息、设备列表与每卡详情并在检测到多于一块 GPU 时输出拓扑与 P2P 信息。跳过拓扑查询单卡机器上或希望精简输出时可以加--no-topology参数python systemInfo.py --no-topology从 systemInfo.py 的参数解析代码可以看到这是一个store_true布尔开关其效果在main()末尾体现仅当该开关未设置时才调用print_topology(devices)systemInfo.py。而print_topology内部还有一个自我保护逻辑设备数量少于 2 时直接返回systemInfo.py所以单卡机器上即使不加参数也不会报错。源码级解析脚本的三个核心信息模块systemInfo.py 是一个单文件、函数式组织的脚本由print_driver_info、print_device_info、print_topology三个打印函数加一个main()入口组成。下面按模块拆解其实现逻辑。1. 驱动 / NVML 版本与进程名print_driver_infomajor, minor system.get_user_mode_driver_version() print(fCUDA driver version (user-mode): {major}.{minor}) if CUDA_BINDINGS_NVML_IS_COMPATIBLE: kmd system.get_kernel_mode_driver_version() print(fCUDA driver version (kernel-mode): {..join(str(x) for x in kmd)}) print(fNVML version: {system.get_nvml_version()}) try: print(fDriver branch: {system.get_driver_branch()}) except Exception as e: print(fDriver branch: unavailable ({e})) else: print(NVML bindings are not compatible with this driver; device info will be limited.) print(fCurrent process: {system.get_process_name(os.getpid())})这段代码systemInfo.py透露了几个 README 未展开的实现细节驱动版本被拆分为**用户态user-mode与内核态kernel-mode**两个概念。get_user_mode_driver_version()返回(major, minor)元组get_kernel_mode_driver_version()返回完整的版本分量用点号拼接后形如13.2.0。这是 NVML 绑定下相对底层的信息粒度README 中的get_driver_version()/get_driver_version_full()属于同一家族 API 的不同封装。NVML 兼容性分支是健壮性的关键当CUDA_BINDINGS_NVML_IS_COMPATIBLE为假时脚本不会崩溃而是明确告知设备信息将受限并在main()中提前退出设备枚举systemInfo.py。get_driver_branch()这类纯信息性调用被包在try/except中即使驱动不提供分支字符串也只打印unavailable (...)而不会中断整个脚本——这种防御式写法值得在巡检类工具中借鉴。进程名通过system.get_process_name(os.getpid())获取直接把当前 Python 进程的 PID 传进去即可。2. 单卡元数据print_device_infoprint_device_infosystemInfo.py接收一个system.Device对象逐项打印字段API 调用输出示例名称device.nameYour GPU NameUUIDdevice.uuid...算力device.cuda_compute_capability8.9架构device.arch.nameADA品牌device.brandBRAND_GEFORCE显存device.memory_infototal/used/freetotal23.99 GiB, used960.00 KiB, free23.52 GiBPCIdevice.pci_infodomain/bus/device/bus_iddomain0000 bus41 device00 id00000000:41:00.0温度device.temperature.get_sensor()47 C性能状态device.performance_statePstates.PSTATE_8: 8实现上有三个细节值得关注字节格式化显存原始值以字节为单位返回脚本用format_bytes()systemInfo.py按 1024 进制转换为 KiB/MiB/GiB/TiB 的人类可读字符串。该函数逻辑清晰依次除以 1024直到数值小于 1024 时选定单位并保留两位小数。PCI 地址的十六进制格式化pci.domain:04x、pci.bus:02x、pci.device:02x用 Python 格式化语法输出 4/2/2 位十六进制最终拼出bus_id那样的标准 PCI 地址串。温度传感器接口README 中写的是temperature.sensor(TemperatureSensors.TEMPERATURE_GPU)而当前源码实际调用的是device.temperature.get_sensor()systemInfo.py。这说明cuda.core的温度 API 存在不同层级的封装示例选用的是更简洁的get_sensor()形式两者都对应 NVML 的 GPU 温度传感器读数单位摄氏度。此外算力、架构、品牌、显存、PCI、温度、性能状态每一项都被独立包裹在try/except中见 systemInfo.py任何一个字段查询失败都不会影响其余字段的输出。这是针对异构硬件差异如某些设备不暴露温度传感器的稳健处理。3. 多卡拓扑与 P2Pprint_topologyfor i, d0 in enumerate(devices): for d1 in devices[i 1:]: level system.get_topology_common_ancestor(d0, d1) read system.get_p2p_status(d0, d1, GpuP2PCapsIndex.READ) write system.get_p2p_status(d0, d1, GpuP2PCapsIndex.WRITE) print(fDevice {d0.index} - Device {d1.index}: ftopology{level_name}, p2p_read{read_name}, p2p_write{write_name})这段逻辑systemInfo.py用双重循环遍历所有无序设备对i与i1:组合避免重复配对对每对设备查询共同祖先拓扑层级get_topology_common_ancestor(d0, d1)返回GpuTopologyLevel枚举输出如TOPOLOGY_HOSTBRIDGE。该值代表两块 GPU 在系统拓扑树上的最近共同连接点是判断互联带宽潜力的重要参考。P2P 读/写能力get_p2p_status(d0, d1, GpuP2PCapsIndex.READ/WRITE)分别查询两个方向的 peer-access 能力README 中的GpuP2PCapsIndex.P2P_CAPS_INDEX_READ与源码中的GpuP2PCapsIndex.READ是同一枚举的两种引用方式。与设备信息一样拓扑和 P2P 查询也被try/except保护失败时以unavailable (...)占位systemInfo.py保证在多卡异构环境下脚本始终能跑完。主流程与命令行入口mainmain()systemInfo.py的组织顺序即脚本的执行顺序用argparse解析--no-topology参数调用print_driver_info()输出驱动/NVML 段调用system.get_num_devices()获取 NVML 可见的 GPU 数量打印Devices detected: N数量为 0 时打印 No CUDA-capable devices found. 并正常退出返回码 0NVML 不兼容时提示并提前退出用列表推导式[system.Device(indexi) for i in range(num_devices)]构造全部设备句柄逐个调用print_device_info未指定--no-topology时调用print_topology打印Done返回 0。值得强调的是构造system.Device(index...)不需要任何 CUDA 上下文这正是本示例区别于基于 Runtime API 的deviceQuery类示例的核心价值——枚举 GPU 的成本极低适合嵌入启动脚本做环境自检。预期输出解读README 给出了一份双卡机器上的示例输出省略了部分设备详情。其结构分三个区块与源码的三个打印函数一一对应 Driver / NVML CUDA driver version: 13.2 CUDA driver version (full): (13, 2, 0) NVML version: (13, 595, 58, 3) Driver branch: r595_88 Current process: /usr/bin/python Devices detected: 2 -- Device 0 -- Name: Your GPU Name UUID: ... Compute capability: 8.9 Architecture: ADA Brand: BRAND_GEFORCE Memory: total23.99 GiB, used960.00 KiB, free23.52 GiB PCI: domain0000 bus41 device00 id00000000:41:00.0 Temperature (GPU sensor): 47 C Performance state: Pstates.PSTATE_8: 8 GPU topology and peer-to-peer Device 0 - Device 1: topologyTOPOLOGY_HOSTBRIDGE, p2p_read..., p2p_write... Done解读要点版本字段README 示例的CUDA driver version (full): (13, 2, 0)对应源码中内核态版本的元组形态NVML version: (13, 595, 58, 3)则是 NVML 库自身的四段式版本号Driver branch: r595_88对应驱动分支字符串。性能状态PSTATE_8是 NVML 定义的 P-state 枚举值0 为最高性能数字越大代表更低的性能/功耗档位输出直接打印枚举对象。架构与品牌Architecture: ADA是device.arch.name的枚举名Ada Lovelace 架构Brand: BRAND_GEFORCE是 NVML 的品牌枚举。数据可变性README 明确提示设备名、算力、温度、拓扑细节会因 GPU 与系统不同而变化示例输出仅用于说明格式。与其他示例的衔接Python 生态内的定位本示例在 Python 示例体系中承担环境感知角色。同目录下的其他入门示例如vectorAdd、simplePrint、deviceQuery等见 python/1_GettingStarted 目录结构在各自运行前通常可以复用本示例的思路做环境预检仓库的公共工具模块 cuda_samples_utils.py 中也有check_cuda_requirements()检查cupy与cuda.core.Device是否可导入与print_gpu_info()打印设备名与算力等辅助函数与systemInfo的环境体检目标互补——前者偏向依赖是否齐全后者偏向系统信息是否健康。注意事项与适用边界NVML 兼容性是功能上限当CUDA_BINDINGS_NVML_IS_COMPATIBLE为假时脚本只能输出用户态驱动版本与进程名无法枚举设备详情。这是驱动与cuda-python绑定版本不匹配时的预期行为升级驱动或对齐cuda-python版本即可解决。字段级容错算力、架构、温度等字段在部分 GPU如某些虚拟化环境或专业卡上可能不可用示例通过逐字段try/except保证整体可运行读者可沿用这一模式扩展自己的查询字段。P2P 查询的适用前提拓扑/P2P 信息只在多卡且有完整 NVML 权限的环境中才有意义单卡机器建议直接使用--no-topology精简输出。版本配套本示例面向 CUDA Toolkit 13.x 与cuda-python13.x、cuda-core1.0.0的配套组合requirements.txt若使用其他大版本组合API 名称与枚举路径可能变化请以对应版本的cuda.core文档为准。小结systemInfo示例以不到 210 行的单文件实现完整演示了cuda.core.system的三类能力版本探测用户态/内核态驱动、NVML、分支、设备枚举与元数据读取算力、架构、显存、PCI、温度、P-state、多卡关系分析拓扑共同祖先与 P2P 读写状态。其不创建 CUDA 上下文即可查询的特性使其成为 CI 环境检查、部署前体检、多卡调试等场景中一个轻量而实用的参考实现示例源码中随处可见的字段级容错与兼容性分支也为编写健壮的系统巡检脚本提供了可直接借鉴的工程范式。【免费下载链接】cuda-samplesSamples for CUDA Developers which demonstrates features in CUDA Toolkit项目地址: https://gitcode.com/GitHub_Trending/cu/cuda-samples创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考