首页/新闻资讯/正文详情

TVM Runtime NDArray 完全指南:tvm.nd.array / tvm.nd.empty / NDArray 核心 API 与底层实现解析

发布时间:2026/9/23 21:39:59 来源:云帆数科 栏目:资讯中心
TVM Runtime NDArray 完全指南:tvm.nd.array / tvm.nd.empty / NDArray 核心 API 与底层实现解析
编译器深度学习模型优化【免费下载链接】tvmOpen deep learning compiler stack for cpu, gpu and specialized accelerators项目地址https://gitcode.com/gh_mirrors/tvm7/tvm点击查看免费下载本文基于 tvm.runtime.ndarray API 参考文档 编写系统讲解 TVMApache TVMPython 前端中tvm.nd.NDArray这一运行时核心数据容器的完整用法。NDArray 是连接前端Relay / Relax / TE与后端运行时CPU / GPU / 各类加速器的数据交接桥掌握tvm.nd.array、tvm.nd.empty以及copyto、numpy、DLPack 互操作等 API是编写可执行的 TVM 推理脚本、自定义算子测试与多设备部署代码的必备技能。读完本文你将能够熟练创建、转换、迁移 NDArray并理解其背后的引用计数与 FFI 调用链。一、NDArray 是什么轻量数据容器而非新的数组库在 python/tvm/runtime/ndarray.py 的类定义中NDArray被明确定义为Lightweight NDArray class of TVM runtime. Strictly this is only an Array Container (a buffer object). No arithmetic operations are defined. All operations are performed by TVM functions.这段话揭示了 TVM 的设计哲学NDArray 只是一个缓冲区对象负责承载数据内存与元信息shape / dtype / device不定义任何算术运算如加法、矩阵乘等。所有计算都由 TVM 的编译产物通过tvm.build生成的函数或 TVM 算子库来执行NDArray 仅作为输入输出的载体。TVM 的目标不是再造一个数组库如 NumPy而是提供一个极简的数据结构便于在已有项目可能已有自己的数组容器中集成 TVM。与 NumPy 的关系NDArray 与 NumPy 是互相转换而非互相替代的关系从 NumPy 到 NDArraytvm.nd.array(numpy_array, device...)会执行一次数据拷贝见下文copyfrom的实现从 NDArray 到 NumPyarr.numpy()同样通过内存拷贝完成在 Python 侧__repr__与__str__的实现中最终输出内容也是通过self.numpy().__repr__()得到的参见 ndarray.py。二、创建 NDArraytvm.nd.array 与 tvm.nd.emptyAPI 文档中给出了两个核心创建函数均在 python/tvm/runtime/ndarray.py 中实现。2.1 tvm.nd.array —— 从源数据创建tvm.nd.array(arr, devicetvm.cpu(0), mem_scopeNone)参数类型说明arrnumpy.ndarray 或 array_like待拷贝的数据源deviceDevice, 可选数组所在的设备默认 CPU 设备 0mem_scopestr, 可选数组的内存作用域memory scope返回NDArray创建的数组其核心实现逻辑ndarray.pyif not isinstance(arr, (np.ndarray, NDArray)): arr np.array(arr) return empty(arr.shape, arr.dtype, device, mem_scope).copyfrom(arr)可见tvm.nd.array本质上是一个先empty分配、再copyfrom拷贝的组合操作如果传入的不是 NumPy 数组会先通过np.array(arr)自动转换因此可以直接传入 Python list如果传入的已经是NDArray则跳过转换注意如果传入的是tvm.ir.container.ArrayIR 容器会直接抛出AttributeError防止误用。2.2 tvm.nd.empty —— 只分配不初始化tvm.nd.empty(shape, dtypefloat32, devicetvm.cpu(0), mem_scopeNone)参数类型说明shapeShapeTuple 或 Sequence数组形状如[1024, 1024]dtypestr数据类型默认float32deviceDevice数组所在设备mem_scopestr, 可选内存作用域返回NDArray未初始化数据的空数组实现中先将 shape 规范化为tvm.runtime.ShapeTuple再通过 FFI 调用底层分配arr _ffi_api.TVMArrayAllocWithScope(shape, dtype, device, mem_scope)TVMArrayAllocWithScope在 C 侧注册于 src/runtime/ndarray.ccTVM_REGISTER_GLOBAL(runtime.TVMArrayAllocWithScope).set_body_typed(NDArray::Empty);即最终调用NDArray::Empty声明于 include/tvm/runtime/ndarray.h由各设备CPU、CUDA、OpenCL 等的分配器完成实际内存申请。测试 test_runtime_ndarray.py 中的test_memory_usage还验证了empty分配后设备可用内存会相应减少且del arr释放最后一个引用后内存会恢复——这正是下一节要讲的引用计数机制。2.3 支持的 dtypeNDArray 支持 TVM 完整的数据类型体系。在 python/tvm/_ffi/runtime_ctypes.py 的STR2DTYPE中登记了void、bool、int8/16/32/64、uint8/16/32/64、float16/32/64以及面向量化与训练场景的e4m3_float8、e5m2_float8二者转换回 NumPy 时需要安装ml_dtypes库。此外 TVM 还支持向量化 lane 类型如float32x4dtype 字符串中的x4后缀会体现在DataType.lanes字段上。三、NDArray 核心属性与方法NDArray的完整 API 通过autoclass指令自动收集到 ndarray.rst 中以下逐一讲解。3.1 属性shape、dtype、devicearr tvm.nd.array(np.random.rand(3, 4)) print(arr.shape) # (3, 4) print(arr.dtype) # float32 print(arr.device) # Device(0, 0) device_type1 表示 CPUdtype属性直接读取self.handle.contents.dtype其中handle是TVMArrayHandle指向 DLTensor 结构device属性返回self.handle.contents.device即 DLTensor 中记录的DLDevice结构device_type device_idshape则由 C 扩展层的NDArrayBase提供。这三个属性与 DLPack 规范中的DLTensor元信息一一对应是数组身份的核心标识。3.2 转换到 NumPynumpy() 与 asnumpy()np_arr arr.numpy() # 推荐用法 np_arr arr.asnumpy() # 旧 API会触发 DeprecationWarningnumpy()的实现ndarray.py要点若 dtype 是向量化类型lanes 1会先把lanes维度展开到 shape 末尾对特殊类型做归一化int4映射为int8bfloat16映射为uint16e4m3_float8/e5m2_float8在安装ml_dtypes时映射为对应 float8 类型否则抛RuntimeError分配 C 连续的 NumPy 数组后调用TVMArrayCopyToBytes从设备内存拷贝数据int4类型还需额外做高低半字节的重新排列才能还原真实数据。asnumpy()在 ndarray.py 中明确标注将在 TVM v0.8 起废弃请改用numpy()。3.3 数据拷贝copyfrom 与 copytocopyfrom外部 → NDArray同步拷贝arr.copyfrom(numpy_array) # 返回 arr 自身便于链式调用实现ndarray.py会做多重校验与适配若源是 NDArray直接调用其copyto若源不是 NumPy 数组先按self.dtype转换检查 shape 严格匹配否则抛ValueError对于bfloat16先将数据视为uint16字节流拷贝若源不是 C 连续先通过np.ascontiguousarray转换最终调用 C 函数TVMArrayCopyFromBytes(self.handle, data, nbytes)C 实现见 src/runtime/ndarray.cc该拷贝总是同步的会触发一次TVMSynchronize。copytoNDArray → 目标target_arr tvm.nd.empty((3, 4), devicetvm.cuda(0)) arr.copyto(target_arr) # 拷贝到已有数组跨设备也可以 gpu_arr arr.copyto(tvm.cuda(0)) # 传 Device自动分配目标数组实现ndarray.py目标是NDArrayBase调用 C 层的_copyto对应TVMArrayCopyFromTo见 src/runtime/ndarray.cc要求两侧字节数严格相等ICHECK_EQ目标是Device先empty分配同 shape/dtype 的数组再拷贝其他类型抛ValueError。切片赋值setitemarr[:] numpy_array或arr[:] other_ndarray被重载为数据拷贝操作。注意它只支持全切片[:]如果传入带 start/stop 的切片会抛ValueError(Array only support set from numpy array)这是有意设计的简化约束参见 ndarray.py。3.4 身份比较same_as /eq/hashNDArray 的相等性比较是基于对象身份底层句柄指针而非数据内容的a tvm.nd.array([1, 2, 3]) b tvm.nd.array([1, 2, 3]) print(a b) # False不同分配 print(a.same_as(a)) # True实现见 ndarray.py__hash__返回handle指针的值__eq__委托给same_as后者仅当两对象是同一底层引用时才返回 True。若需要比较内容应使用np.testing.assert_equal(a.numpy(), b.numpy())这也是测试代码中的通行写法。3.5 创建视图_create_viewNDArray._create_view允许基于现有数组共享底层分配、创建不同逻辑 shape 的视图ndarray.py通过 FFI 的TVMArrayCreateViewC 注册见 src/runtime/ndarray.cc声明见 include/tvm/runtime/ndarray.h实现。文档注释明确警告该接口只应用于底层内存操作会破坏 TVM 的非别名non-aliasing假设未来可能被移除普通用户不应使用。四、设备管理与 Device 对象tvm.nd.empty/tvm.nd.array的device参数接收tvm.runtime.Device。构造 Device 有两种途径4.1 tvm.device(dev_type, dev_id) 通用构造函数assert tvm.device(cpu, 1) tvm.cpu(1) assert tvm.device(cuda, 0) tvm.cuda(0) assert tvm.device(cuda:2) tvm.cuda(2) # 字符串内联设备号实现见 ndarray.py支持int类型掩码或字符串两种输入字符串支持cuda、cuda:2等格式冒号后的数字会覆盖dev_id参数无法识别的设备名抛ValueError。4.2 便捷设备构造函数模块内为每种设备提供了专用工厂函数全部位于 ndarray.py函数对应设备备注tvm.cpu(dev_id0)CPU默认设备tvm.cuda(dev_id0)NVIDIA GPU0.9.0 起推荐替代tvm.gputvm.gpu(dev_id0)CUDA GPU已废弃调用会发 DeprecationWarningtvm.rocm(dev_id0)AMD ROCm GPUtvm.opencl(dev_id0)/tvm.clOpenCL 设备cl opencl别名tvm.metal(dev_id0)/tvm.mtlApple Metalmtl metal别名tvm.vulkan(dev_id0)Vulkan 设备tvm.vpi(dev_id0)VPI 模拟设备用于 RTL 仿真tvm.hexagon(dev_id0)Qualcomm Hexagontvm.webgpu(dev_id0)WebGPUtvm.ext_dev(dev_id0)扩展设备保留给插件设备 API 快速试验设备名称到类型掩码的映射表定义在 python/tvm/_ffi/runtime_ctypes.py 的Device.STR2MASK中其中llvm、stackvm、c、test、hybrid、composite等编译目标名称也统一映射到 CPU。Device结构体runtime_ctypes.py还提供exist设备是否存在且可访问、max_threads_per_block、available_global_memory等运行时属性后者被内存测试用例直接使用。五、DLPack 互操作零拷贝跨框架数据交换DLPack 是 TVM 支持的标准张量内存共享协议NDArray 原生支持 DLPack 导出与导入实现零拷贝的数据交换。5.1 导出NDArray → 其他框架capsule arr.__dlpack__() # 返回 DLPack capsule device_type, device_id arr.__dlpack_device__()__dlpack__(self, streamNone)ndarray.py返回封装了DLManagedTensor的PyCapsulestream参数用于多流场景下由消费者告知生产者同步语义__dlpack_device__()ndarray.py按 DLPack 约定返回(device_type, device_id)元组。实现了这两个协议方法后NDArray 即可直接被 PyTorch、JAX 等支持 DLPack 的框架零拷贝接收。5.2 导入其他框架 → NDArraytorch_tensor torch.arange(6).reshape(2, 3).cuda() tvm_arr tvm.nd.from_dlpack(torch_tensor) # 零拷贝视图from_dlpackndarray.py接受两类输入具有__dlpack__方法的任意对象如 PyTorch Tensor已经是PyCapsule形式的 DLPack capsule。其实现会取出 DLPack 张量的指针创建数组视图并接管原 DLPack tensor 的析构职责移除原始 destructor从而保证生命周期安全。这也是test_runtime_packed_func.py等测试中tvm.nd.array([1, 2, 3])直接用于 PackedFunc 参数的基础。六、底层原理从 Python 到 C 的调用链以tvm.nd.empty为例一次分配经历如下完整链路tvm.nd.empty(shape, dtype, device) → tvm.runtime.ndarray.empty → _ffi_api.TVMArrayAllocWithScope(shape, dtype, device, mem_scope) → NDArray::Empty(ShapeTuple, DLDataType, Device, mem_scope) [src/runtime/ndarray.cc:385] → 设备分配器CPU 走 kDLCPU AllocatorCUDA 走 cudaMalloc 等 → 返回引用计数管理的 ContainerObjectRefNDArray 在 C 侧是ObjectRef的封装include/tvm/runtime/ndarray.h底层由NDArray::Container继承Object与ContainerBase见 ndarray.h持有DLTensor数据指针与引用计数。因此引用计数管理del arr后若引用计数归零底层分配的内存会被立即释放测试test_memory_usage已验证该行为C 接口兼容底层还导出TVMArrayAlloc、TVMArrayFree、TVMArrayCopyFromTo、TVMArrayCopyFromBytes、TVMArrayCopyToBytes等 C APIsrc/runtime/ndarray.ccPython 层的copyfrom/numpy分别通过TVMArrayCopyFromBytes/TVMArrayCopyToBytes与运行时交互对齐要求NDArray::IsAlignedndarray.cc要求data byte_offset满足kAllocAlignment对齐拷贝时CopyFromTo也会校验IsAlignedndarray.cc与字节数一致ICHECK_EQ。七、实战完整可运行的 NDArray 工作流结合 test_runtime_ndarray.py 与 test_minimal_target_codegen_llvm.py 中的通行用法给出一个端到端示例import numpy as np import tvm from tvm import te # 1. 创建 NDArrayCPU x_np np.random.randint(0, 10, size(3, 4)).astype(float32) x tvm.nd.array(x_np, devicetvm.cpu(0)) # 拷贝进 TVM assert isinstance(x, tvm.nd.NDArray) assert x.shape x_np.shape and x.dtype x_np.dtype # 2. 跨设备迁移 cuda_arr x.copyto(tvm.cuda(0)) # 若机器有 GPU back_cpu cuda_arr.copyto(tvm.cpu(0)) # 3. 与编译产物配合构建一个简单的 te 算子 n 100 A te.placeholder((n,), dtypefloat32) B te.compute((n,), lambda i: A[i] 1.0) func tvm.build(te.create_schedule([B.op]), [A, B], llvm) in_arr tvm.nd.array(np.random.randn(n).astype(float32)) out_arr tvm.nd.empty((n,), dtypefloat32) func(in_arr, out_arr) # NDArray 直接作为 PackedFunc 参数 # 4. 转回 NumPy 验证 np.testing.assert_allclose(out_arr.numpy(), in_arr.numpy() 1.0) # 5. DLPack 零拷贝互操作以 torch 为例需已安装 torch # torch_t torch.arange(6).reshape(2, 3) # tvm_arr tvm.nd.from_dlpack(torch_t) # tvm_arr[:] torch_t.numpy() * 2 # 支持全切片赋值注意事项同步语义copyfrom、copyto、numpy()涉及设备的拷贝总是同步的底层会触发TVMSynchronize涉及 GPU 上下文时这是可靠获取结果的前提不要用比较内容NDArray 的是引用比较内容校验请用np.testing.assert_*asnumpy()已废弃新代码统一使用numpy()gpu()已废弃新代码统一使用cuda()。八、相关文档与源码索引API 参考文档docs/reference/api/python/ndarray.rstautomodule/autoclass/autofunction自动生成的模块级 API 页面Python 实现python/tvm/runtime/ndarray.pyNDArray 类、array/empty/from_dlpack、全部设备构造函数FFI 类型定义python/tvm/_ffi/runtime_ctypes.pyDataType、Device、DataTypeCode、TVMArray、STR2DTYPE、STR2MASKC 头文件include/tvm/runtime/ndarray.hNDArray类与Container定义、Empty/CreateView/ToDLPack声明C 实现src/runtime/ndarray.ccNDArray::Empty、CopyFromTo、C API 与 PackedFunc 注册单元测试tests/python/all-platform-minimal-test/test_runtime_ndarray.py覆盖创建、跨设备拷贝、内存生命周期、fp16 转换综上tvm.runtime.ndarray虽然 API 表面简洁却是 TVM 运行时体系的地基向上承接 NumPy / DLPack 生态的数据进出向下通过 FFI 直通各设备分配器。理解 NDArray 的容器定位、引用计数生命周期与拷贝/转换语义是写出正确、高效 TVM 推理与测试代码的第一步。赞分享编译器深度学习模型优化【免费下载链接】tvmOpen deep learning compiler stack for cpu, gpu and specialized accelerators项目地址https://gitcode.com/gh_mirrors/tvm7/tvm点击查看免费下载相关推荐MXNet 稀疏 NDArray 完全指南CSRNDArray 与 RowSparseNDArray 的构造、算子与底层实现MXNet 稀疏 NDArray 完全指南CSRNDArray 与 RowSparseNDArray 的构造、算子与底层实现 MXNet 的 mxnet.nd深度学习人工智能机器学习分布式训练TVM4J 实战指南在 JVM 中接入 Apache TVM Runtime实现 NDArray、PackedFunc、共享库加载与 RPCTVM4J 实战指南在 JVM 中接入 Apache TVM Runtime实现 NDArray、PackedFunc、共享库加载与 RPC TVM4J 是编译器深度学习模型优化Apache MXNet NDArray 完全指南mxnet.ndarray 命令式张量核心解析Apache MXNet NDArray 完全指南mxnet.ndarray 命令式张量核心解析 导读 mxnet.ndarray 是 Apache MXNe深度学习人工智能机器学习分布式训练创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

老配电柜智能化改造:PLC+边缘计算实现AI预警
老配电柜智能化改造:PLC+边缘计算实现AI预警

1. 老配电柜的智能化改造:从"哑巴设备"到"会说话的节点"干了十几年电气自动化,我见过太多配电室里那些"沉默的功臣"——MCC柜、动力柜、老式GGD柜,它们兢兢业业跑了十几年,除了指示灯和指针表&… · 2026/9/23 21:39:59

secs4net实战指南:SECS/GEM协议调试与产线联调避坑
secs4net实战指南:SECS/GEM协议调试与产线联调避坑

简介:本资源是面向工业自动化与半导体设备通信开发者的SECS/GEM协议C#实现开源项目,适用于.NET平台下SECS/GEM设备联调、报文解析、协议栈二次开发等场景,特别适合具备C#基础的中高级开发者深入理解设备通信底层机制。压缩包共320个文件&… · 2026/9/23 21:39:53

cua是什么梗?从拟声词到网络热词的传播密码
cua是什么梗?从拟声词到网络热词的传播密码

“cua”这个词,最近算是彻底火了。刷短视频也好,看直播也好,甚至跟朋友聊天打字,动不动就能蹦出一个“cua”。你要是没搞清楚它到底啥意思,跟人聊天都容易接不上话。很多人以为这就是个随手打的拟声词,但再… · 2026/9/23 21:39:53

LSTM时间序列预测实战:Python源码解析与调参避坑指南
LSTM时间序列预测实战:Python源码解析与调参避坑指南

简介:基于LSTM的时间序列分析预测Python源码,面向数据科学、人工智能方向的学习者与开发者。项目以空气污染数据为例,完整覆盖数据加载与归一化、LSTM模型构建(基于Keras/TensorFlow)、模型训练、评估与未来值预测等环… · 2026/9/23 23:01:53

长尾商品销量预测:基于DNN的时序预测与特征工程实战
长尾商品销量预测:基于DNN的时序预测与特征工程实战

简介:面向供应链备货中的长尾商品销量预测难题,这份基于TensorFlow 1.13编写的DNN项目源码,提供了7天、30天和60天三档预测的实现思路,适合有一定Python基础、希望借助低阶API掌握模型训练与部署的开发者。压缩包共6个文件&#x… · 2026/9/23 23:01:53

EverOS 记忆工作原理:Markdown 为源、SQLite 与 LanceDB 为派生索引的分层存储与同步管线
EverOS 记忆工作原理:Markdown 为源、SQLite 与 LanceDB 为派生索引的分层存储与同步管线

EverOS 记忆工作原理:Markdown 为源、SQLite 与 LanceDB 为派生索引的分层存储与同步管线 【免费下载链接】EverOS One portable memory layer for every AI agent: local-first, Markdown-native, user-owned, and self-evolving across apps, tools, and workflow… · 2026/9/23 23:01:41

鸵鸟目标检测数据集:419张VOC+YOLO双格式标注
鸵鸟目标检测数据集:419张VOC+YOLO双格式标注

简介:本资源是一份面向计算机视觉初学者与目标检测实践者的鸵鸟图像数据集,适用于YOLO、Faster R-CNN等主流检测模型的训练与验证。数据集共419张高质量JPG图像(1–500KB),全部标注为单一类别“ostrich”,并… · 2026/9/23 23:01:35

SAP按销售订单采购生产:从销售订单到采购申请与生产工单的MRP配置链路
SAP按销售订单采购生产:从销售订单到采购申请与生产工单的MRP配置链路

简介:这份文档面向制造业与流通业中从事SAP实施、运维及成本核算的顾问与财务人员,聚焦按销售订单采购生产这一典型场景,解决从销售订单触发采购、生产到结算全流程的配置与操作落地问题。资源包共1个doc文件,约122KB,… · 2026/9/23 23:01:35

Python京东价格监控系统实战:爬虫、SQLite与定时提醒
Python京东价格监控系统实战:爬虫、SQLite与定时提醒

简介:基于Python的京东价格监控系统完整源码,面向有商品比价需求的Python学习者和开发者,解决手动查看价格信息滞后、无法及时决策的痛点。系统整合Requests与Selenium两种爬取方式,支持通过JS接口或页面渲染获取价格,… · 2026/9/23 23:01:28

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码