当前位置: 首页 > news >正文

在 KubeVirt 中使用 GPU Operator

在 KubeVirt 中使用 GPU Operator

基于最新的GPU Operator版本24.9.0。

原文链接:GPU Operator with KubeVirt — NVIDIA GPU Operator 24.9.0 documentation

1. 简介

KubeVirt 是 Kubernetes 的一个虚拟机管理插件,允许您在 Kubernetes 集群中运行和管理虚拟机。它消除了为虚拟机和容器工作负载管理独立集群的需求,二者现在可以在单一 Kubernetes 集群中共存。

在此之前,GPU Operator 仅支持为运行 GPU 加速的容器配置工作节点。现在,GPU Operator 也可以用于为运行 GPU 加速的虚拟机配置工作节点。

运行带有 GPU 的容器和虚拟机所需的前提条件不同,主要区别在于所需的驱动程序。例如,数据中心驱动程序用于容器,vfio-pci 驱动程序用于 GPU 直通,而 NVIDIA vGPU Manager 用于创建 vGPU 设备。

现在可以将 GPU Operator 配置为根据节点上配置的 GPU 工作负载来部署不同的软件组件。以下示例展示了这一点。

  • 节点 A 被配置为运行容器。
  • 节点 B 被配置为运行具有直通 GPU 的虚拟机。
  • 节点 C 被配置为运行具有 vGPU 的虚拟机。

节点 A 配置的软件组件:

  • NVIDIA 数据中心驱动程序:用于安装驱动程序。
  • NVIDIA 容器工具包:确保容器可以正确访问 GPU。
  • NVIDIA Kubernetes 设备插件:用于发现 GPU 资源并将其发布给 kubelet。
  • NVIDIA DCGM 和 DCGM Exporter:用于监控 GPU。

节点 B 配置的软件组件:

  • VFIO 管理器:用于加载 vfio-pci 并将其绑定到节点上的所有 GPU。
  • 沙盒设备插件:用于发现 GPU 直通资源并将其发布给 kubelet。

节点 C 配置的软件组件:

  • NVIDIA vGPU 管理器:用于安装驱动程序。
  • NVIDIA vGPU 设备管理器:用于在节点上创建 vGPU 设备。
  • 沙盒设备插件:用于发现 vGPU 设备并将其发布给 kubelet。

2. 假设、约束和依赖项

  • 一个 GPU 工作节点可以运行特定类型的 GPU 工作负载——容器、具有 GPU 直通的虚拟机或具有 vGPU 的虚拟机——但不能混合运行这些类型的工作负载。
  • 集群管理员或开发者需提前了解集群的需求,并正确地为节点贴上标签,以指示其将运行的 GPU 工作负载类型。
  • 运行 GPU 加速虚拟机(使用 pGPU 或 vGPU)的工作节点假定为裸机。
  • GPU Operator 不会自动在附带 GPU/vGPU 的 KubeVirt 虚拟机中安装 NVIDIA 驱动。
  • 用户在将 GPU 直通和 vGPU 资源分配给 KubeVirt 虚拟机之前,必须手动将所有 GPU 直通和 vGPU 资源添加到 KubeVirt CR 中的 permittedDevices 列表中。有关更多信息,请参阅 KubeVirt 文档。
  • 不支持基于 MIG 的 vGPU。

3. 先决条件

  • 在 BIOS 中启用虚拟化和 IOMMU 扩展(Intel VT-d 或 AMD IOMMU)。
  • 主机以 intel_iommu=onamd_iommu=on 启动内核。
  • 如果计划使用 NVIDIA vGPU,并且 GPU 基于 NVIDIA Ampere 架构或更新架构,则必须在 BIOS 中启用 SR-IOV。请参考 NVIDIA vGPU 文档,确保满足使用 NVIDIA vGPU 的所有先决条件。
  • KubeVirt 已安装在集群中。
  • 从 KubeVirt v0.58.2 和 v0.59.1 开始,需设置 DisableMDEVConfiguration 功能门控:
kubectl patch kubevirt -n kubevirt kubevirt --type='json' \-p='[{"op": "add", "path": "/spec/configuration/developerConfiguration/featureGates/-", "value": "DisableMDEVConfiguration" }]'

示例输出

kubevirt.kubevirt.io/kubevirt patched

4. 入门指南

使用 GPU Operator 和 KubeVirt 的高层次工作流程如下:

  1. 确保已设置禁用中介设备配置的功能门控。

  2. 根据将要运行的 GPU 工作负载类型为工作节点打标签。

  3. 安装 GPU Operator 并设置 sandboxWorkloads.enabled=true

如果使用 NVIDIA vGPU,还需要执行其他步骤,这将在后续部分中介绍。

5. 为工作节点打标签

使用以下命令为工作节点添加标签:

kubectl label node <node-name> --overwrite nvidia.com/gpu.workload.config=vm-vgpu

可以为标签 nvidia.com/gpu.workload.config 指定以下值:containervm-passthroughvm-vgpu。GPU Operator 使用该标签的值来确定在每个工作节点上部署哪些操作对象。

如果节点上不存在 nvidia.com/gpu.workload.config 标签,GPU Operator 将假定默认的 GPU 工作负载配置为 container,并部署支持该类型负载所需的软件组件。要覆盖默认的 GPU 工作负载配置,可在 ClusterPolicy 中设置以下值:sandboxWorkloads.defaultWorkload=<config>

6. 安装 GPU Operator

根据是否计划使用 NVIDIA vGPU,选择以下适当的小节以安装 GPU Operator。

通常,ClusterPolicy 中的 sandboxWorkloads.enabled 标志控制 GPU Operator 是否可以为虚拟机工作负载(以及容器工作负载)配置 GPU 工作节点。默认情况下,此标志是禁用的,这意味着所有节点将使用相同的软件配置以支持容器工作负载,并且不会使用 nvidia.com/gpu.workload.config 节点标签。

注意

术语“沙箱”通常指在一个单独的隔离环境中运行软件,通常是为了增加安全性(如虚拟机)。我们使用“沙箱工作负载”一词来表示在虚拟机中运行的工作负载,无论使用何种虚拟化技术。

安装 GPU Operator(不使用 NVIDIA vGPU)

安装 GPU Operator,并启用 sandboxWorkloads

helm install --wait --generate-name \-n gpu-operator --create-namespace \nvidia/gpu-operator \--set sandboxWorkloads.enabled=true

安装 GPU Operator(使用 NVIDIA vGPU)

构建私有的 NVIDIA vGPU Manager 容器镜像并推送到私有镜像仓库。请按照本节提供的步骤操作。

创建 GPU Operator 的命名空间:

kubectl create namespace gpu-operator

创建用于访问 NVIDIA vGPU Manager 镜像的 ImagePullSecret:

kubectl create secret docker-registry ${REGISTRY_SECRET_NAME} \--docker-server=${PRIVATE_REGISTRY} --docker-username=<username> \--docker-password=<password> \--docker-email=<email-id> -n gpu-operator

安装 GPU Operator,启用 sandboxWorkloadsvgpuManager,并指定之前构建的 NVIDIA vGPU Manager 镜像:

helm install --wait --generate-name \-n gpu-operator --create-namespace \nvidia/gpu-operator \--set sandboxWorkloads.enabled=true \--set vgpuManager.enabled=true \--set vgpuManager.repository=<path to private repository> \--set vgpuManager.image=vgpu-manager \--set vgpuManager.version=<driver version> \--set vgpuManager.imagePullSecrets={${REGISTRY_SECRET_NAME}}

由 GPU Operator 部署的 vGPU Device Manager 会自动创建 vGPU 设备,这些设备可以分配给 KubeVirt 虚拟机。默认情况下,GPU Operator 会在所有 GPU 上创建一组默认设备。要了解 vGPU Device Manager 的更多信息以及如何配置在集群中创建的 vGPU 设备类型,请参考 vGPU 设备配置文档。

7. 向 KubeVirt CR 中添加 GPU 资源

更新 KubeVirt 自定义资源,使集群中的所有 GPU 和 vGPU 设备均被允许并可以分配给虚拟机。

以下示例展示了如何允许 A10 GPU 设备和 A10-24Q vGPU 设备。

  1. 确定 GPU 设备的资源名称:

    kubectl get node cnt-server-2 -o json | jq '.status.allocatable | with_entries(select(.key | startswith("nvidia.com/"))) | with_entries(select(.value != "0"))'
    

    示例输出

    {"nvidia.com/NVIDIA_A10-12Q": "4"
    }
    
  2. 确定 GPU 的 PCI 设备 ID。

    可以在 PCI IDs 数据库中按设备名称进行搜索。

    如果有节点的主机访问权限,可以使用以下命令列出 NVIDIA GPU 设备:

    lspci -nnk -d 10de:
    

    示例输出

    65:00.0 3D controller [0302]: NVIDIA Corporation GA102GL [A10] [10de:2236] (rev a1)Subsystem: NVIDIA Corporation GA102GL [A10] [10de:1482]Kernel modules: nvidiafb, nouveau
    
  3. 修改 KubeVirt 自定义资源,以下为部分示例:

    ...
    spec:configuration:developerConfiguration:featureGates:- GPU- DisableMDEVConfigurationpermittedHostDevices:pciHostDevices:- externalResourceProvider: truepciVendorSelector: 10DE:2236resourceName: nvidia.com/GA102GL_A10mediatedDevices:- externalResourceProvider: truemdevNameSelector: NVIDIA A10-24QresourceName: nvidia.com/NVIDIA_A10-24Q
    ...
    
  4. 根据您的设备替换 YAML 中的值:

    • pciHostDevices 下,将 pciVendorSelectorresourceName 替换为您的 GPU 型号。
    • mediatedDevices 下,将 mdevNameSelectorresourceName 替换为您的 vGPU 类型。
  5. 设置 externalResourceProvider=true,以表明该资源由外部设备插件(即 GPU Operator 部署的 sandbox-device-plugin)提供。

有关更多配置信息,请参阅 KubeVirt 用户指南。

8. 创建带有 GPU 的虚拟机

在 GPU Operator 完成将沙箱设备插件和 VFIO 管理器 pod 部署到工作节点上,并将 GPU 资源添加到 KubeVirt 允许列表之后,可以通过编辑 VirtualMachineInstance 清单中的 spec.domain.devices.gpus 字段,将 GPU 分配给虚拟机。

apiVersion: kubevirt.io/v1alpha3
kind: VirtualMachineInstance
...
spec:domain:devices:gpus:- deviceName: nvidia.com/GA102GL_A10name: gpu1
...
  • deviceName 是表示设备的资源名称。
  • name 是在虚拟机中用于标识该设备的名称。

9. vGPU 设备配置

vGPU 设备管理器(vGPU Device Manager)用于在 GPU 工作节点上创建 vGPU 设备。管理员可以声明式地定义一组可能的 vGPU 设备配置,并应用于节点上的 GPU。运行时,可以将 vGPU 设备管理器指向这些配置中的一个,设备管理器会负责将其应用。配置文件以 ConfigMap 的形式创建,并在所有工作节点之间共享。运行时,可以使用节点标签 nvidia.com/vgpu.config 来决定在特定时间应在节点上应用哪个配置。如果节点没有此标签,则使用默认配置。有关此组件及其配置的更多信息,请参阅项目的 README。

默认情况下,GPU Operator 部署一个 vGPU 设备管理器的 ConfigMap,包含所有 NVIDIA vGPU 支持的 vGPU 类型的命名配置。用户可以通过应用 nvidia.com/vgpu.config 节点标签为工作节点选择特定配置。例如,将节点标记为 nvidia.com/vgpu.config=A10-8Q 会在节点上的所有 A10 GPU 上创建 3 个 A10-8Q 类型的 vGPU 设备(注:每个 GPU 最多可创建 3 个 A10-8Q 设备)。如果节点没有标签,则应用默认配置。默认配置会在所有 GPU 上创建 Q 系列的 vGPU 设备,其中每个 vGPU 设备的帧缓冲内存为 GPU 总内存的一半。例如,默认配置会在所有 A10 GPU 上创建两个 A10-12Q 设备,在所有 V100 GPU 上创建两个 V100-8Q 设备,在所有 T4 GPU 上创建两个 T4-8Q 设备。

如果需要自定义的 vGPU 设备配置,可以创建自己的 ConfigMap:

kubectl create configmap custom-vgpu-config -n gpu-operator --from-file=config.yaml=/path/to/file

然后通过设置 vgpuDeviceManager.config.name=custom-vgpu-config 配置 GPU Operator 使用该自定义配置。

10. 应用新的 vGPU 设备配置

可以通过设置 nvidia.com/vgpu.config 节点标签,在每个节点上应用特定的 vGPU 设备配置。如果不希望应用默认配置,建议在安装 GPU Operator 前先设置此节点标签。

在已成功应用某一 vGPU 设备配置后切换配置时,假定该节点上没有正在运行的带 vGPU 的虚拟机。任何现有的虚拟机需要先关闭或迁移。

在安装 GPU Operator 后要应用新配置,只需更新 nvidia.com/vgpu.config 节点标签。以下是一个包含两个 A10 GPU 系统上的运行示例:

nvidia-smi -L
GPU 0: NVIDIA A10 (UUID: GPU-ebd34bdf-1083-eaac-2aff-4b71a022f9bd)
GPU 1: NVIDIA A10 (UUID: GPU-1795e88b-3395-b27b-dad8-0488474eec0c)

按照之前章节中的步骤安装 GPU Operator,且未使用 nvidia.com/vgpu.config 标签对节点进行标记时,将应用默认的 vGPU 配置:创建四个 A10-12Q 设备(每个 GPU 两个设备):

kubectl get node cnt-server-2 -o json | jq '.status.allocatable | with_entries(select(.key | startswith("nvidia.com/"))) | with_entries(select(.value != "0"))'
{"nvidia.com/NVIDIA_A10-12Q": "4"
}

如果希望创建 A10-4Q 设备,可以这样标记节点:

kubectl label node <node-name> --overwrite nvidia.com/vgpu.config=A10-4Q

在 vGPU 设备管理器完成应用新配置后,所有 GPU Operator 相关的 pod 应恢复到 Running 状态。

kubectl get pods -n gpu-operator
NAME                                                          READY   STATUS    RESTARTS   AGE
...
nvidia-sandbox-device-plugin-daemonset-brtb6                  1/1     Running   0          10s
nvidia-sandbox-validator-ljnwg                                1/1     Running   0          10s
nvidia-vgpu-device-manager-8mgg8                              1/1     Running   0          30m
nvidia-vgpu-manager-daemonset-fpplc                           1/1     Running   0          31m

此时在节点上可以看到 12 个 A10-4Q 设备,因为每个 A10 GPU 可创建 6 个 A10-4Q 设备。

kubectl get node cnt-server-2 -o json | jq '.status.allocatable | with_entries(select(.key | startswith("nvidia.com/"))) | with_entries(select(.value != "0"))'
{"nvidia.com/NVIDIA_A10-4Q": "12"
}

11. 构建 NVIDIA vGPU 管理器镜像

注意:

如果计划使用 NVIDIA vGPU,才需要构建 NVIDIA vGPU 管理器镜像。如果仅计划使用 PCI 直通,请跳过此部分。

本节涵盖了构建 NVIDIA vGPU 管理器容器镜像并将其推送到私有注册表的过程。

下载 vGPU 软件

从 NVIDIA 许可门户下载 vGPU 软件。

  • 登录到 NVIDIA 许可门户,并导航到软件下载部分。

  • NVIDIA vGPU 软件位于 NVIDIA 许可门户的 软件下载 部分。

  • vGPU 软件包以 zip 文件形式打包。下载并解压该包,以获取适用于 Linux 的 NVIDIA vGPU 管理器文件 NVIDIA-Linux-x86_64-<version>-vgpu-kvm.run

注意:

对于 NVIDIA AI 企业客户,必须使用 aie .run 文件来构建 NVIDIA vGPU 管理器镜像。请下载 NVIDIA-Linux-x86_64-<version>-vgpu-kvm-aie.run 文件,并在继续执行后续步骤之前将其重命名为 NVIDIA-Linux-x86_64-<version>-vgpu-kvm.run

克隆驱动容器仓库并构建驱动镜像

打开终端并克隆驱动容器镜像仓库。

git clone https://gitlab.com/nvidia/container-images/driver
cd driver

切换到适用于您的操作系统的 vgpu-manager 目录

以 Ubuntu 20.04 为例:

cd vgpu-manager/ubuntu20.04

注意:

对于 RedHat OpenShift,运行 cd vgpu-manager/rhel8 使用 rhel8 文件夹。

复制从解压的 zip 文件中获得的 NVIDIA vGPU 管理器文件

cp <local-driver-download-directory>/*-vgpu-kvm.run ./

设置以下环境变量:

  • PRIVATE_REGISTRY - 用于存储驱动镜像的私有注册表名称。
  • VERSION - 从 NVIDIA 软件门户下载的 NVIDIA vGPU 管理器版本。
  • OS_TAG - 必须与客户端操作系统版本匹配。上面的示例中使用的是 ubuntu20.04。对于 RedHat OpenShift,应设置为 rhcos4.x,其中 x 是受支持的 OCP 次版本号。
  • CUDA_VERSION - 用于构建驱动镜像的 CUDA 基础镜像版本。

示例:

export PRIVATE_REGISTRY=my/private/registry VERSION=510.73.06 OS_TAG=ubuntu20.04 CUDA_VERSION=11.7.1

构建 NVIDIA vGPU 管理器镜像

docker build \--build-arg DRIVER_VERSION=${VERSION} \--build-arg CUDA_VERSION=${CUDA_VERSION} \-t ${PRIVATE_REGISTRY}/vgpu-manager:${VERSION}-${OS_TAG} .

将 NVIDIA vGPU 管理器镜像推送到私有注册表(registry)

docker push ${PRIVATE_REGISTRY}/vgpu-manager:${VERSION}-${OS_TAG}

相关文章:

在 KubeVirt 中使用 GPU Operator

在 KubeVirt 中使用 GPU Operator 基于最新的GPU Operator版本24.9.0。 原文链接&#xff1a;GPU Operator with KubeVirt — NVIDIA GPU Operator 24.9.0 documentation 1. 简介 KubeVirt 是 Kubernetes 的一个虚拟机管理插件&#xff0c;允许您在 Kubernetes 集群中运行和…...

安慰剂检验Stata代码(全套代码、示例数据及参考文献)

数据简介&#xff1a;随着因果推断方法在实证研究中的使用比例不断提升&#xff0c;越来越多的文章进行安慰剂检验。其检验基本原理与医学中的安慰剂类似&#xff0c;即使用假的政策发生时间或实验组进行分析&#xff0c;以检验能否得到政策效应。如果依然得到了政策效应&#…...

DAY6 线程

作业1&#xff1a; 多线程实现文件拷贝&#xff0c;线程1拷贝一半&#xff0c;线程2拷贝另一半&#xff0c;主线程回收子线程资源。 代码&#xff1a; #include <myhead.h> sem_t sem1; void *copy1()//子线程1函数 拷贝前一半内容 {int fd1open("./1.txt",O…...

基于STM32的智能门锁系统设计思路:蓝牙、RFID等技术

一、项目概述 在现代家居安全领域&#xff0c;传统门锁因其安全性不足、开锁方式单一等问题&#xff0c;已逐渐无法满足用户的需求。传统机械锁容易被撬开、复制钥匙&#xff0c;同时开锁方式仅限于物理钥匙&#xff0c;给用户带来不便。因此&#xff0c;本文旨在设计并开发一…...

AndroidStudio-广播

一、广播的本质 广播是一种数据传输方式 二、Android 中的广播 发送一条广播&#xff0c;可以被不同的广播接收者所接收&#xff0c;广播接收者收到广播之后&#xff0c;再进行逻辑处理。 三、收发标准广播 广播的收发过程分为三个步骤&#xff1a; 1.发送标准广播 2.定义…...

基于表格滚动截屏(表格全部展开,没有滚动条)

import html2canvasPro from html2canvas // 截图&#xff0c;平辅表格 async function resetAgSize() {const allColumns gridApi.value.getColumns()let totalColumnWidth 0let totalColumnHeight 0// 遍历每一个行节点gridApi.value.forEachNode((rowNode) > {totalCo…...

洛谷P1255

P1255 数楼梯 - 洛谷 | 计算机科学教育新生态 数楼梯 题目描述 楼梯有 N 阶&#xff0c;上楼可以一步上一阶&#xff0c;也可以一步上二阶。 编一个程序&#xff0c;计算共有多少种不同的走法。 输入格式 一个数字&#xff0c;楼梯数。 输出格式 输出走的方式总数。 样…...

vue3设置第三方组件 样式::v-deep

在Vue 3中&#xff0c;使用了Composition API的组件可以通过<style>标签内部的::v-deep选择器来深入作用于第三方组件的样式。::v-deep是一个 Scoped CSS 的“深度选择器”&#xff0c;可以穿透组件边界&#xff0c;影响子组件的样式。比如我想修改el-date-picker的颜色边…...

JAVA学习日记(十四)集合进阶

一、单列集合Collection List系列集合特点&#xff1a;添加的元素是有序&#xff08;存和取的顺序一致&#xff09;、可重复、有索引 Set系列集合特点&#xff1a;添加的元素是无序&#xff08;存和取的顺序有可能不一致&#xff09;、不重复、无索引 Collection是所有单列集合…...

mysql全量与增量备份

binlog日志&#xff1a; 从上一次全量备份到下一次全量备份直接产生的数据。 一、全备和增量备份介绍 1、全量备份&#xff1a; 备份所有数据库或只备份一个数据库&#xff0c;全量备份之后&#xff0c;全量备份之前的binlog日志就没用了&#xff0c;一般生产环境会保留3-7天…...

“非法”操控lambda(python)

能过python解释器关卡即是合法脚本代码&#xff0c;偶尔的“违规”操控也是一种唯美。 (笔记模板由python脚本于2024年11月13日 11:18:21创建&#xff0c;本篇笔记适合熟悉python的lambda操控的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.pyth…...

UDP协议和TCP协议之间有什么具体区别?

UDP&#xff08;User Datagram Protocol&#xff09;和TCP&#xff08;Transmission Control Protocol&#xff09;是两种常见的网络传输协议&#xff0c;它们在数据传输中有着显著的区别和适用场景。理解它们的区别对于网络工程师、软件开发人员以及网络安全专家都是至关重要的…...

论文5—《基于改进YOLOv5s的轻量化金银花识别方法》文献阅读分析报告

论文报告&#xff1a;基于改进YOLOv5s的轻量化金银花识别方法 论文报告文档 基于改进YOLOv5s的轻量化金银花识别方法 论文报告文档摘要国内外研究现状国内研究现状国外研究现状 研究目的研究问题使用的研究方法试验研究结果文献结论创新点和对现有研究的贡献1. 目标检测技术2. …...

快手直播间采集教程,快手引流,快手截流,截流工具,直播间截流,快手直播间采集,获客系统,获客软件

功能&#xff1a; 1.输入快手直播间链接可一键监控直播间 2.可采集新进直播间的人 3.可采集直播间所有动作&#xff0c;包含&#xff1a;发弹幕的人和内容、送礼物的人和送的礼物、点亮爱心的人 4.可一键导出新进直播间的快手ID 5.可一键导出直播间动作列表&#xff0c;也可以筛…...

探索MoviePy:Python视频编辑的瑞士军刀

文章目录 &#x1f3ac; 探索MoviePy&#xff1a;Python视频编辑的瑞士军刀第一部分&#xff1a;背景介绍第二部分&#xff1a;MoviePy是什么&#xff1f;第三部分&#xff1a;如何安装MoviePy&#xff1f;第四部分&#xff1a;MoviePy的基本函数使用方法1. 视频剪辑2. 视频拼接…...

mysql 实现分库分表之 --- 基于 MyCAT 的分片策略详解

引言 在我们日常工作的项目中&#xff0c;特别是面向 C 端用户的产品&#xff0c;随着业务量的逐步扩大&#xff0c;数据量也呈指数级增长。为了应对日益增长的数据库压力&#xff0c;数据库优化已成为项目中不可或缺的一环&#xff0c;而分库分表则是海量数据优化方案中的重要…...

Opencascade基础教程(14): 一个模型显示问题

如果显示模型时出现如图情况&#xff0c;正对屏幕的平面特别亮&#xff0c;只需要设置材质为非金属就行。 //创建box并显示TopoDS_Shape aShape BRepPrimAPI_MakeBox(100, 100, 100);Handle(AIS_Shape) aisShpae new AIS_Shape(aShape);aisShpae->SetDisplayMode(AIS_Shad…...

ISP——你可以从这里起步(二)

接上一篇&#xff0c;上一篇是原理篇&#xff0c;这一篇是实战篇&#xff0c;为了实现下面框图中的不完美ISP。 第一章 做一张RAW图自己用 不是所有的人都能获得raw图&#xff0c;即使获得了raw图也需要对应的sensor参数才能把它用起来&#xff0c;所以我找了一条野路子可以把…...

Qt / Qt Quick程序打包的一些坑 (四)

【写在前面】 打包方法见 Qt / Qt Quick程序打包的方法。 这里是再次记录一些坑。 【正文开始】 直接进入正题&#xff1a; 在 Qt5 中&#xff0c;如果我们的 Qml 中使用了【Qt Shapes】模块&#xff0c;那么在打包的时候&#xff0c;会缺少Qt5QuickShapes.dll。 然后&#xff…...

《传统视觉算法在视觉算法中的地位及应用场景

一、引言 在计算机视觉领域的发展历程中&#xff0c;传统视觉算法扮演了至关重要的角色。尽管近年来深度学习算法在视觉任务中取得了巨大的成功&#xff0c;但传统视觉算法依然具有不可替代的地位。传统视觉算法通常基于数学模型和手工设计的特征&#xff0c;具有计算效率高、…...

老老实实干一辈子程序员是没出息的!这本证书你早该学!

一、程序员有没有必要学软考&#xff1f; 当然有&#xff0c;因为你不可能一辈子都是程序员。 你了解或者接触过30岁、35岁以上的程序员去向吗&#xff1f; 我毕业快十年了&#xff0c;当初正赶上互联网时代的浪潮&#xff0c;好几个学计算机的同学毕业后去了一线城市或者深…...

鸿蒙next版开发:相机开发-录像(ArkTS)

在HarmonyOS 5.0中&#xff0c;ArkTS提供了一套完整的API来管理相机功能&#xff0c;特别是录像功能。本文将详细介绍如何在ArkTS中实现录像功能&#xff0c;并提供代码示例进行详细解读。 录像功能开发步骤 1. 导入相关接口 首先&#xff0c;需要导入相机相关的接口&#x…...

闯关leetcode——3206. Alternating Groups I

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/alternating-groups-i/description/ 内容 There is a circle of red and blue tiles. You are given an array of integers colors. The color of tile i is represented by colors[i]: colors[i…...

多个摄像机画面融合:找到同一个目标在多个画面中的伪三维坐标,找出这几个摄像头间的转换矩阵

搞算法&#xff0c;重要的是解决问题的思想&#xff0c;不要再局限于语言、框架、性能&#xff01;&#xff01;&#xff01; 要解决的问题是&#xff1a;在某一个摄像头画面中&#xff0c;目标会被遮挡或者丢失&#xff0c;但在另外一个摄像机画面中&#xff0c;目标完整&…...

Three.js性能优化和实践建议

Three.js 是一个功能强大的 3D 引擎&#xff0c;当场景足够大的时候&#xff0c;就会出现卡顿的现象&#xff0c;首先要保证电脑的性能够用&#xff0c;然后看看下面方法&#xff0c;帮助你提高应用的运行效率。 1. 使用 stats.js 监视性能 在进行任何优化之前&#xff0c;首…...

C#入门 023 什么是类(Class)

什么是“类” 是一种数据结构 是一种数据类型 代表现实世界中的“种类” 构造器和析构器 析构器 析构器&#xff08;Destructor&#xff09;是一种特殊的成员方法&#xff0c;用于在对象被垃圾回收器&#xff08;Garbage Collector, GC&#xff09;回收之前执行清理操作。…...

一篇Spring Boot 笔记

一、Spring Boot 简介 Spring Boot 是一个用于创建独立的、基于 Spring 的生产级应用程序的框架。它简化了 Spring 应用的初始搭建和开发过程&#xff0c;通过自动配置等功能&#xff0c;让开发者能够快速地构建应用&#xff0c;减少了大量的样板代码和复杂的配置。 二、核心特…...

一生一芯 预学习阶段 NEMU代码学习(2)

接上回&#xff1a;一生一芯 预学习阶段 NEMU代码学习&#xff08;1&#xff09; 上次说到这里 static int cmd_c(char *args) {cpu_exec(-1);return 0; } 当输入c时&#xff0c;会执行&#xff1a;cpu_exec(-1); void cpu_exec(uint64_t n) {g_print_step (n < MAX_IN…...

《手写Spring渐进式源码实践》实践笔记(第二十章 实现简单ORM框架)

文章目录 第二十章 简单ORM框架实现背景技术背景基本概念工作原理优点缺点常见的ORM框架 业务背景 目标设计实现代码结构类图实现步骤 测试事先准备属性配置文件测试用例(selectOne)测试结果测试用例(selectList)测试结果 总结 第二十章 简单ORM框架实现 背景 技术背景 ORM&…...

AI技术赋能电商行业:创新应用与未来展望

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《热点时事》 期待您的关注 引言 随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;技术正逐步渗透到各行各业&a…...