ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

cuda-samples 之 cuDLA 混合模式(Hybrid Mode)深度解析:用 CUDA 编程 Tegra DLA 的完整工作流

cuda-samples 之 cuDLA 混合模式(Hybrid Mode)深度解析:用 CUDA 编程 Tegra DLA 的完整工作流 cuda-samples 之 cuDLA 混合模式Hybrid Mode深度解析用 CUDA 编程 Tegra DLA 的完整工作流【免费下载链接】cuda-samplesSamples for CUDA Developers which demonstrates features in CUDA Toolkit项目地址: https://gitcode.com/GitHub_Trending/cu/cuda-samples导读本文以 NVIDIA cuda-samples 仓库中的 cuDLAHybridMode 示例 为核心深入讲解 cuDLACUDA Deep Learning Accelerator的混合模式Hybrid Mode——即通过 CUDA 运行时 API 编程 DLA 硬件的完整流程。读完本文你将掌握 cuDLA 与 CUDA 的协作模型、loadable 加载、张量描述符查询、显存注册、任务提交与流同步等关键技术并能在 Tegraaarch64平台上独立构建与运行该示例。cuDLA 与 Hybrid Mode 是什么cuDLA 是 NVIDIA 面向 TegraJetson平台提供的 DLADeep Learning Accelerator编程接口。DLA 是 Tegra SoC 上独立于 GPU SM 的专用深度学习推理加速器通常通过 TensorRT 或 DLAS 生态间接使用。cuDLA 则将 DLA 的能力以 API 形式直接暴露给开发者使其能够在更低层级控制推理任务的调度。cuDLA 有两种编程模式Standalone Mode独立模式完全脱离 CUDA 运行时仅通过 cuDLA 驱动 APIcudlaCreateDevice、cudlaSubmitTask等操作 DLA参见仓库中的 cuDLAStandaloneMode 示例Hybrid Mode混合模式将 DLA 任务嵌入 CUDA 流stream体系DLA 推理与 CUDA kernel、内存拷贝在同一流中按序调度实现 DLA 与 GPU 工作负载的统一编排。本示例 cuDLAHybridMode 即演示此模式。混合模式的核心价值在于开发者可以用一套流式编程模型同时管理 GPU 与 DLA 两套硬件无需单独维护两套同步机制。示例总览目录结构与支持平台该示例位于仓库cpp/8_Platform_Specific/Tegra/cuDLAHybridMode/共三个文件文件作用main.cu示例唯一源文件包含完整的主流程CMakeLists.txtCMake 构建配置负责链接 cudla 库README.md示例说明文档依据 README.md 的声明关键概念Key ConceptscuDLA、数据并行算法Data Parallel Algorithms、图像处理Image Processing支持的 SM 架构SM 6.0 / 6.1 / 7.0 / 7.2 / 7.5 / 8.0 / 8.6 / 8.7 / 8.9 / 9.0从 Pascal 到 Blackwell 全系;支持的操作系统Linux、QNX支持的 CPU 架构aarch64即 Tegra/Jetson 的 ARM64 平台。值得注意虽然 README 声明支持 Linux 与 QNX 两个系统但 CMakeLists.txt 中明确限定CMAKE_SYSTEM_NAME STREQUAL Linux才会添加构建目标非 Linux 环境下会输出Will not build sample cuDLAHybridMode - requires Linux OS并跳过构建。构建时还需找到cudla库否则同样会被跳过并提示CUDLA not found。构建与运行命令行参数与 CMake 配置命令行用法程序入口 main.cu 首先校验参数个数Usage : ./cuDLAHybridMode loadable imageFile参数含义loadableDLA 可执行文件由 TensorRT 或 DLAS 工具链生成的 DLA loadable 二进制程序会将其整体读入内存imageFile输入图像文件路径用于填充 DLA 推理输入张量示例会打印 loadable 文件大小The file size %ld并校验实际读取字节数与文件大小一致否则报Read wrong size退出。CMake 构建要点CMakeLists.txt 揭示了该示例的构建细节cmake_minimum_required(VERSION 3.20)project(... LANGUAGES C CXX CUDA)find_package(CUDAToolkit REQUIRED)定位 CUDA Toolkit随后find_library(CUDLA_LIB cudla PATHS ${CUDAToolkit_LIBRARY_DIR} ...)查找 cuDLA 驱动库默认 CUDA 架构为CMAKE_CUDA_ARCHITECTURES 87 110对应 Orin 等 8.7 架构与 Blackwell 11.0 架构与 README 中支持的 SM 8.7 / 9.0 对应编译标准为cxx_std_17 cuda_std_17并开启CUDA_SEPARABLE_COMPILATION ON与--extended-lambda编译选项ENABLE_CUDA_DEBUG开启时追加-Gcuda-gdb 调试信息否则默认追加-lineinfo行号调试信息链接目标仅为${CUDLA_LIB}即 cuDLA 库。构建前提是安装匹配平台的 CUDA ToolkitREADME 的 Prerequisites 章节要求且环境包含cudla.h头文件与libcudla库。源码级解析Hybrid Mode 的十步工作流main.cu 将整个推理流程组织为清晰的十个阶段。下面按执行顺序逐段剖析所有行号均对应仓库内源文件。1. 资源结构体统一管理句柄与缓冲源码在 main.cu#L66-L78 定义了ResourceList结构体集中保存整个生命周期内的资源typedef struct { cudlaDevHandle devHandle; // cuDLA 设备句柄 cudlaModule moduleHandle; // DLA loadable 模块句柄 unsigned char *loadableData; // loadable 文件的内存副本 cudaStream_t stream; // CUDA 流混合模式的核心 unsigned char *inputBuffer; // 主机侧输入缓冲 unsigned char *outputBuffer; // 主机侧输出缓冲 void *inputBufferGPU; // 设备侧输入缓冲 void *outputBufferGPU;// 设备侧输出缓冲 cudlaModuleTensorDescriptor *inputTensorDesc; // 输入张量描述符 cudlaModuleTensorDescriptor *outputTensorDesc;// 输出张量描述符 } ResourceList;配合cleanUp()main.cu#L82-L130完成逆序释放cudlaModuleUnload、cudlaDestroyDevice、cudaFree、cudaStreamDestroy并在释放后将指针置空防止重复释放。该结构贯穿整个示例任何一步失败都会调用cleanUp安全退出。2. 初始化 CUDA 运行时程序先读取 loadable 到内存校验fread读取量随后初始化 CUDA 运行时main.cu#L187-L201result cudaFree(0); // 惰性初始化 CUDA 运行时 result cudaSetDevice(0); // 选择 0 号设备错误处理统一使用cudaGetErrorName(result)将 CUDA 错误码转换为可读字符串输出。3. 创建设备CUDLA_CUDA_DLA 是关键标志混合模式与独立模式的分水岭出现在设备创建调用main.cu#L203-L211err cudlaCreateDevice(0, devHandle, CUDLA_CUDA_DLA);第三个参数CUDLA_CUDA_DLA明确要求通过 CUDA 上下文驱动 DLA这正是 Hybrid Mode 的本质。对比 cuDLAStandaloneMode 示例 中不使用 CUDA 的独立模式该标志决定了后续任务提交如何与 CUDA 流交互。4. 从内存加载 DLA 模块loadable 文件已读入loadableData通过 cudlaModuleLoadFromMemory 从内存加载err cudlaModuleLoadFromMemory(devHandle, loadableData, file_size, moduleHandle, 0);成功后打印Successfully loaded module。5. 创建 CUDA 流混合模式的关键设施——CUDA 流main.cu#L226-L235result cudaStreamCreateWithFlags(stream, cudaStreamNonBlocking);使用cudaStreamNonBlocking标志创建非阻塞流使流内操作可与默认流流 0并发。后续 DLA 任务将提交到该流与cudaMemcpyAsync、cudaMemsetAsync等 CUDA 操作按序执行。6. 查询张量描述符探明 DLA 网络的输入输出加载模块后需向模块查询输入/输出张量的数量与形状main.cu#L237-L301。这一阶段依次调用四次cudlaModuleGetAttributes属性枚举含义CUDLA_NUM_INPUT_TENSORS输入张量个数写入attribute.numInputTensorsCUDLA_NUM_OUTPUT_TENSORS输出张量个数CUDLA_INPUT_TENSOR_DESCRIPTORS输入张量描述符数组CUDLA_OUTPUT_TENSOR_DESCRIPTORS输出张量描述符数组描述符结构cudlaModuleTensorDescriptor的内容由 printTensorDesc 完整打印开发者可据此了解 DLA 网络的详细契约TENSOR NAME : name size: 字节数 dims: [n, c, h, w] data fmt: dataFormat data type: dataType data category: dataCategory pixel fmt: pixelFormat pixel mapping: pixelMapping stride[0..3]: 每维步长其中dims以 NCHW 布局给出stride描述各维的内存步长dataType/dataFormat描述数值类型与数据排布。后续所有内存分配都以描述符中的size为基准。7. 分配主机与设备缓冲注册 CUDA 显存依据inputTensorDesc[0].size/outputTensorDesc[0].size分别在主机分配缓冲并清零main.cu#L303-L330再通过cudaMalloc分配设备显存main.cu#L332-L351。混合模式的关键一步是调用cudlaMemRegister将 CUDA 分配的显存注册给 DLAmain.cu#L353-L372err cudlaMemRegister(devHandle, (uint64_t *)inputBufferGPU, inputTensorDesc[0].size, inputBufferRegisteredPtr, 0); err cudlaMemRegister(devHandle, (uint64_t *)outputBufferGPU, outputTensorDesc[0].size, outputBufferRegisteredPtr, 0);cudlaMemRegister返回 DLA 侧的注册指针inputBufferRegisteredPtr该指针是后续任务提交时 DLA 实际访问的地址。注册成功后打印ALL MEMORY REGISTERED SUCCESSFULLY。8. 准备输入数据并提交 DLA 任务输入数据通过流异步拷贝进入显存输出显存先清零main.cu#L374-L386cudaMemcpyAsync(inputBufferGPU, inputBuffer, inputTensorDesc[0].size, cudaMemcpyHostToDevice, stream); cudaMemsetAsync(outputBufferGPU, 0, outputTensorDesc[0].size, stream);随后构造cudlaTask并调用cudlaSubmitTask提交main.cu#L388-L403cudlaTask task; task.moduleHandle moduleHandle; task.outputTensor outputBufferRegisteredPtr; task.numOutputTensors 1; task.numInputTensors 1; task.inputTensor inputBufferRegisteredPtr; task.waitEvents NULL; task.signalEvents NULL; err cudlaSubmitTask(devHandle, task, 1, stream, 0);cudlaSubmitTask的第四个参数即 CUDA 流——DLA 任务被插入该流与之前的cudaMemcpyAsync、cudaMemsetAsync以及后续的cudaMemcpyAsync形成严格有序的执行序列。waitEvents/signalEvents为 NULL表示无需额外的跨流事件同步若需要与其他流协调可在此传入cudaEvent_t。提交成功打印SUBMIT IS DONE !!!。9. 同步流并回收结果提交后通过流内异步拷贝将结果搬回主机main.cu#L405-L417cudaMemcpyAsync(outputBuffer, outputBufferGPU, outputTensorDesc[0].size, cudaMemcpyDeviceToHost, stream); cudaStreamSynchronize(stream);cudaStreamSynchronize阻塞主机直到流内全部操作包括 DLA 推理完成此后outputBuffer即为可用的推理结果。这一步正是混合模式相对独立模式的收益所在DLA 计算被无缝纳入 CUDA 流的依赖图开发者无需自行实现轮询或等待。10. 反注册显存与逆序清理推理完成后先调用cudlaMemUnregister反注册输入/输出显存main.cu#L421-L435然后依次释放描述符、主机缓冲、显存销毁流、卸载模块、销毁设备main.cu#L437-L486每步均校验返回值最终打印cuDLAHybridMode DONE !!!正常退出。涉及的 CUDA Runtime API 一览依据 README.md 的声明本示例涉及的 CUDA Runtime API 及其在源码中的作用如下API作用源码位置cudaFree惰性初始化运行时、释放显存main.cu#L188cudaSetDevice选择推理设备main.cu#L195cudaStreamCreateWithFlags创建非阻塞 CUDA 流main.cu#L226cudaMalloc分配设备侧输入/输出显存main.cu#L335cudaMemcpyAsync流内主机↔设备数据搬运main.cu#L375cudaMemsetAsync流内清零输出显存main.cu#L381cudaStreamSynchronize阻塞主机等待流完成main.cu#L412cudaStreamDestroy销毁流main.cu#L453cudaGetErrorName将错误码转为可读字符串全流程错误处理混合模式 vs 独立模式仓库内横向对照仓库cpp/8_Platform_Specific/Tegra/目录下还提供了另外三个 cuDLA 示例可帮助理解本示例在整个 cuDLA 生态中的定位cuDLAStandaloneMode独立模式README 明确定义为不借助 CUDA 编程 DLADLA can be programmed without using CUDA且无 CUDA Runtime API 清单其构建还依赖 NVSCI 库cuDLALayerwiseStatsHybrid同样是混合模式但附加了逐层layerwise统计信息查询能力cuDLAErrorReporting演示通过 CUDA 检测 DLA 错误的机制。三者的 CUDA Runtime API 清单与本示例完全一致cudaStreamCreateWithFlags、cudaMalloc、cudaMemcpyAsync等说明流化 DLA 任务是混合模式示例的共同骨架本示例是其中最小、最完整的入门范式。注意事项与扩展方向输入数据填充为占位实现源码中的 initializeInputBuffers 目前仅保留接口注释Read the file in filePath and fill up buf according to format并直接返回 0实际输入缓冲由memset清零。也就是说本示例重点演示的是完整的调用流程与资源管理真实推理前需要开发者根据张量描述符NCHW、dataFormat、pixelFormat 等自行实现图像文件解析与像素填充流同步语义cudlaSubmitTask将 DLA 任务插入 CUDA 流若你的应用同时有 GPU kernel 需要执行只需将它们提交到同一流即可自然获得 DLA 与 GPU 的顺序/并发编排跨流协作则可利用waitEvents/signalEvents字段架构与平台限制该示例面向 aarch64 上的 Tegra 平台构建目标仅对 Linux 启用且必须存在cudla库实际部署前请确认目标 Jetson 设备的 DLA 能力与 CUDA Toolkit 版本匹配。总体而言cuDLAHybridMode 是理解如何用 CUDA 流统一驱动 DLA 与 GPU的最佳起点——从设备创建到任务提交的十个步骤勾勒出 cuDLA 混合模式的完整心智模型可直接迁移到 cuDLALayerwiseStatsHybrid逐层统计与 cuDLAErrorReporting错误上报等更复杂的生产场景。【免费下载链接】cuda-samplesSamples for CUDA Developers which demonstrates features in CUDA Toolkit项目地址: https://gitcode.com/GitHub_Trending/cu/cuda-samples创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表