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

CANN/catlass TLA张量详解

TLA Tensors【免费下载链接】catlass本项目是CANN的算子模板库提供NPU上高性能矩阵乘及其相关融合类算子模板样例。项目地址: https://gitcode.com/cann/catlass本文介绍 TLA 中的Tensor。如果说Layout负责描述“逻辑坐标如何映射到内存”那么Tensor就是在Layout的基础上再绑定具体数据、当前视图起点和存储层级后的可访问对象。在本文中Tensor一律指逻辑视图MakeTensor创建的是视图不发生数据拷贝。operator()的切片结果是子视图不发生数据拷贝。GetTile与TileView返回的是 tile 视图不发生数据拷贝。MakeTensorLike只是把一块已有存储绑定成“与参考 Tensor 逻辑尺寸一致”的新视图本身不执行数据搬运。真正的数据移动应由显式的搬运或计算接口完成而不是由这些视图构造接口隐式完成。关于Layout的基础定义请先参考 Layout。先分清四个组成部分Tensor的模板参数是BuiltinTensor、Layout、Coord、Position。第一次接触时建议先把这四部分分开理解。BuiltinTensorBuiltinTensor是 AscendC 提供的底层张量对象例如GlobalTensor或LocalTensor。它表示“底层存储对象本身”。LayoutLayout描述逻辑坐标如何映射到内存以及逻辑有效范围如何表达。CoordCoord是当前Tensor视图在BuiltinTensor所表达的父逻辑空间中的起点坐标。这里需要特别强调两点coord的单位是元素不是字节。coord表示“这个视图从BuiltinTensor所表达的父逻辑空间的哪里开始看”不是 tile 编号。例如一个逻辑大小为(8, 16)的矩阵中如果某个子 Tensor 的coord()是(2, 4)它表示“这个视图的左上角对应父逻辑矩阵的第 2 行、第 4 列”。PositionPosition是 AscendC 中的位置标签例如Arch::PositionGM{}、Arch::PositionL1{}。它用于区分数据位于 GM、L1、L0 等哪一层存储。Tensor 构造当前使用MakeTensor构造Tensor。using namespace tla; GlobalTensorfloat A ...; auto layout tla::MakeLayoutfloat, Catlass::layout::RowMajor(8, 16); // 1. 默认从逻辑坐标 (0, 0) 开始 auto tensorA MakeTensor(A, layout, Arch::PositionGM{}); // 2. 显式指定当前视图起点 auto tensorA_sub MakeTensor(A, layout, tla::MakeCoord(1, 5), Arch::PositionGM{});可以按下面的方式理解layout决定“如何解释这块内存”。coord决定“当前视图从BuiltinTensor所表达的父逻辑空间的哪里开始”。Tensor 的常用接口TLATensor提供以下常用接口.data()返回底层内存对象。.layout()返回布局。.coord()返回当前视图起点。.shape()返回layout.shape()。.stride()返回layout.stride()。.originShape()返回layout.originShape()。(coord0, coord1, ...)按坐标索引或切片。统一理解三类“坐标”TLA 文档中最容易混淆的是几类不同的“坐标”。下面给出统一约定。元素坐标 element coord元素坐标表示“按元素计数的逻辑位置”例如(row, col)。GetTile、crd2offset、普通索引访问等接口使用的都是这种坐标。tile 坐标 tile coordtile 坐标表示“第几个 tile”不是第几个元素。例如在tileShape (64, 128)时tileCoord (1, 2)表示第 1 个行 tile、第 2 个列 tile。它对应的元素起点是(1 * 64, 2 * 128)。视图起点 view coordtensor.coord()表示当前Tensor视图在BuiltinTensor所表达的父逻辑空间中的起点。它由创建这个视图的操作决定例如MakeTensor、GetTile、TileView或切片操作。可以用一句话概括element coord是元素位置。tile coord是 tile 编号。tensor.coord()是当前视图的起点。用一个完整示例理解coord()下面用同一个矩阵串联MakeTensor、GetTile几种情形。using namespace tla; GlobalTensorfloat A ...; auto layout tla::MakeLayoutfloat, Catlass::layout::RowMajor(8, 16); auto tensorA MakeTensor(A, layout, Arch::PositionGM{}); // tensorA.coord() (0, 0) auto tensorA_sub MakeTensor(A, layout, MakeCoord(1, 5), Arch::PositionGM{}); // tensorA_sub.coord() (1, 5) auto tileA GetTile(tensorA_sub, MakeCoord(2, 4), MakeShape(4, 8)); // tileA.coord() (3, 9)上面分别表示tensorA直接观察整块逻辑矩阵因此起点是(0, 0)。tensorA_sub从BuiltinTensor所表达的父逻辑空间的(1, 5)开始观察因此起点变为(1, 5)。tileA在tensorA_sub的基础上再取一个起点为(2, 4)的 tile因此新视图起点是(1, 5) (2, 4) (3, 9)。使用operator()进行索引与切片TLATensor支持使用operator()做索引也支持使用tla::_表达整维切片返回子 Tensor 视图。基本规则不带tla::_时tensor(i, j, ...)返回一个底层BuiltinTensor访问结果本质上对应tensor.data()[offset]。带tla::_时tensor(..., tla::_, ...)返回子 Tensor 视图被索引的维度会被固定保留tla::_所在维度。这里使用的坐标参数必须是一层 tuple即每个维度都是标量或tla::_不支持嵌套 tuple。等价语义可写为tensor.data()[tensor.layout()(tensor.coord() coord_arg)]输出 Tensor 的维度设输入张量 rank 为 $R$coord中出现tla::_的维度索引集合为 ${d_0, d_1, ..., d_{k-1}}$则输出 Tensor 的 rank 为 $k$。输出 Tensor 的layout.shape()、layout.stride()、layout.originShape()是输入布局在这些维度上的投影。输出 Tensor 的coord()会重新从全 0 开始因为它已经成为新的局部视图。例如对 3D 张量A(B, M, K)auto A2 A3(b, tla::_, tla::_); // 3D - 2D得到 (M, K) 视图 auto A1 A2(r, tla::_) // 2D - 1D得到 (K)视图获取 TileTensorGetTileGetTile用于从父 Tensor 上切出一个 tile 视图不拷贝数据。template class Tensor, class Coord, class Shape auto GetTile(Tensor const tensor, Coord const coord, Shape const shape);参数语义如下coord元素坐标表示 tile 左上角在父 Tensor 逻辑空间中的起点。shapetile 的期望尺寸单位是元素。using namespace tla; auto layout tla::MakeLayoutfloat, Catlass::layout::RowMajor(8, 16); auto tensor MakeTensor(A, layout, Arch::PositionGM{}); // 从逻辑坐标 (2, 4) 开始取一个 4 x 8 的 tile auto tile GetTile(tensor, tla::MakeCoord(2, 4), MakeShape(4, 8));返回结果可理解为tile.coord()tensor.coord()(2, 4)。tile.layout().shape()表示期望 tile 尺寸或其与父布局结构一致的表达形式。tile.layout().originShape()表示该 tile 真实有效的逻辑范围触边时会自动裁剪。使用约束支持tensor.layout().depth 1。若tensor.layout().depth 1即分形或嵌套布局当前GetTileLayout仅支持rank 2。coord与shape都必须为一层 tuple并满足rank(coord) rank(shape) Tensor::rank。边界行为例如父 Tensor 的逻辑尺寸是(8, 16)执行auto tail GetTile(tensor, tla::MakeCoord(6, 10), MakeShape(4, 8));那么期望尺寸仍然是(4, 8)。但逻辑上只剩下 2 行、6 列有效数据。因此tail.layout().originShape()会变成(2, 6)。TileViewTileView与GetTile的行为等价区别只在于输入坐标的单位不同GetTile接收元素坐标。TileView接收 tile 坐标。template class TensorT, class TileCoord, class TileShape auto TileView(TensorT const tensor, TileCoord const tileCoord, TileShape const tileShape);例如auto tensorTileA tla::TileView( tensorA, tla::MakeCoord(0u, kLoopIdx), tla::MakeShape(IntL1_TILE_M{}, IntL1_TILE_K{}) );等价关系TileView与GetTile可以直接按下面的等式理解TileView(t, tileCoord, tileShape) GetTile(t, tileCoord ⊙ tileShape, tileShape)这里的⊙表示逐维相乘例如(1, 2) ⊙ (64, 128) (64, 256)这条等式表示TileView先把 tile 坐标转换为元素坐标。然后按GetTile的规则创建同一个 tile 视图。因此两者的差别只在于调用者提供的是哪一种坐标单位而不是返回结果的逻辑语义。为什么TileView更适合分块循环在实际 kernel 或 block 循环中循环变量通常就是 tile 编号而不是元素坐标。因此TileView往往更直接。下面用同一个按 K 维分块的例子做对比。写法一使用GetTileconstexpr uint32_t tileM 64; constexpr uint32_t tileK 128; for (uint32_t kTile 0; kTile kTiles; kTile) { auto coord tla::MakeCoord(0u, kTile * tileK); auto shape tla::MakeShape(tileM, tileK); auto tensorTileA tla::GetTile(tensorA, coord, shape); // use tensorTileA }写法二使用TileViewconstexpr uint32_t tileM 64; constexpr uint32_t tileK 128; for (uint32_t kTile 0; kTile kTiles; kTile) { auto tensorTileA tla::TileView( tensorA, tla::MakeCoord(0u, kTile), tla::MakeShape(tileM, tileK) ); // use tensorTileA }这两段代码的逻辑结果相同但第二种写法直接使用 tile 坐标更贴近分块循环本身的语义也更不容易把“tile 坐标”和“元素坐标”混淆。创建类似的 TensorMakeTensorLikeMakeTensorLike用于创建一个“逻辑尺寸与likeTensor一致”的新 Tensor。最常见的用途是从一个已有 tile 视图出发在另一层内存中构造对应 Tensor并自动继承其originShape()。在未指定layoutBase时行为为根据 LayoutTagDst 决定布局从 LikeTensor::Element 推断 ElementDst从 likeTensor 的 originShape 提取尺寸。调用MakeLayoutElementDst, LayoutTagDst(originShape())构造目标 layout可能会因分型布局合法要求对shape进行以分型为粒度的向上取整。指定layoutBase时使用MakeLayout(layoutBase.shape(), layoutBase.stride(), likeTensor.originShape())构造目标layout。这里仍然需要强调MakeTensorLike构造的是新视图不执行数据搬运。它只是把用户传入的builtinTensor绑定成一个新的 TLATensor并让这个新视图复用likeTensor的逻辑尺寸语义。当前MakeTensorLike仅支持likeTensor.rank 2。接口分为三类典型场景。// 1) 从 LikeTensor::Element 推断 ElementDst template class LayoutTagDst, class BuiltinTensor, class LikeTensor, class PositionType auto MakeTensorLike(BuiltinTensor const builtinTensor, LikeTensor const likeTensor, PositionType); // 2) 显式指定 ElementDst template class LayoutTagDst, class ElementDst, class BuiltinTensor, class LikeTensor, class PositionType auto MakeTensorLike(BuiltinTensor const builtinTensor, LikeTensor const likeTensor, PositionType); // 3) 提供 layoutBase template class LayoutTagDst, class BuiltinTensor, class LikeTensor, class PositionType, class LayoutBase auto MakeTensorLike(BuiltinTensor const builtinTensor, LikeTensor const likeTensor, PositionType, LayoutBase const layoutBase); template class LayoutTagDst, class ElementDst, class BuiltinTensor, class LikeTensor, class PositionType, class LayoutBase auto MakeTensorLike(BuiltinTensor const builtinTensor, LikeTensor const likeTensor, PositionType, LayoutBase const layoutBase);场景一源和目标元素类型相同这是最常见的场景。例如从 GM 中的一个halftile 创建对应的 L1 Tensor元素类型不变只是存储层级改变。auto tensorTileA tla::TileView( tensorA, tla::MakeCoord(blockM, kTile), tla::MakeShape(L1_TILE_M, L1_TILE_K) ); auto tensorL1A tla::MakeTensorLikeLayoutTagL1A( l1ATensorList[l1ListId], tensorTileA, Arch::PositionL1{} ); // 结果 // 1. tensorL1A 使用 L1 目标布局 // 2. tensorL1A 的 originShape 与 tensorTileA 相同 // 3. 元素类型从 likeTensor 自动推断场景二目标元素类型不同当目标 Tensor 的元素类型与源 Tensor 不一致时需要显式指定ElementDst。例如L0C 中使用 accumulator 类型。需要从half输入生成float累加视图。目标内存对象的PrimType与LikeTensor::Element不同。auto tensorL0C tla::MakeTensorLikeLayoutTagL0C, float( l0cTensor, tensorTileC, Arch::PositionL0C{} ); // 结果 // 1. tensorL0C 的逻辑尺寸继承自 tensorTileC // 2. 目标元素类型显式为 float // 3. 适用于 accumulator 或类型提升场景场景三目标布局需要额外控制有些场景下仅指定LayoutTagDst还不够因为目标布局的基础形状或步长需要用户显式给出。例如目标 Tensor 采用特定分形布局。需要固定某个 L1 的物理排布。注意L0的排布由originShape唯一确定因此定制L0上的非预期排布为不合法行为。需要预先给出特殊的shape/stride结构但逻辑有效范围仍要继承自likeTensor。auto layoutBaseL1A tla::MakeLayouthalf, LayoutTagL1A(L1_TILE_M, L1_TILE_K); auto tensorL1A tla::MakeTensorLikeLayoutTagL1A( l1ATensor, tensorTileA, Arch::PositionL1A{}, layoutBaseL1A ); // 结果 // 1. tensorL1A 的 shape/stride 来自 layoutBaseL1A // 2. tensorL1A 的 originShape 继承自GM上的 tensorTileA // 3. 即使当前 tile 是尾块逻辑有效范围也不会丢失如果既要控制目标布局又要显式指定目标元素类型可以使用同时带layoutBase和ElementDst的重载。实际使用模式在 block 层和 kernel 层常见写法通常是两步用TileView从父 Tensor 得到 tile 视图自动处理边界。用MakeTensorLike在目标内存层级构造对应 Tensor自动继承originShape()。这套模式的价值在于主流程始终围绕 tile 编程。尾块逻辑通过originShape自动传递。数据搬运和计算阶段都能复用同一套逻辑尺寸语义减少边界分支和歧义。【免费下载链接】catlass本项目是CANN的算子模板库提供NPU上高性能矩阵乘及其相关融合类算子模板样例。项目地址: https://gitcode.com/cann/catlass创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关文章:

CANN/catlass TLA张量详解

TLA Tensors 【免费下载链接】catlass 本项目是CANN的算子模板库,提供NPU上高性能矩阵乘及其相关融合类算子模板样例。 项目地址: https://gitcode.com/cann/catlass 本文介绍 TLA 中的 Tensor。 如果说 Layout 负责描述“逻辑坐标如何映射到内存”&#xf…...

AI驱动蛋白质工程:从语言模型与拓扑数据分析到高效工作流构建

1. 项目概述:当AI遇见蛋白质工程 蛋白质,作为生命活动的核心执行者,其功能多样性令人惊叹。从催化生化反应的酶,到识别外来抗原的抗体,再到传递信号的受体,蛋白质几乎参与了所有生命过程。蛋白质工程&#…...

小红书无水印下载工具终极指南:5分钟快速上手的完整教程

小红书无水印下载工具终极指南:5分钟快速上手的完整教程 【免费下载链接】XHS-Downloader 小红书(XiaoHongShu、RedNote)链接提取/作品采集工具:提取账号发布、收藏、点赞、专辑作品链接;提取搜索结果作品、用户链接&a…...

CANN/NDDMA多维数据搬运优化

深入理解NDDMA多维数据搬运:昇腾算子开发性能优化利器 【免费下载链接】cann-learning-hub CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。 项目地址: https://gitcode.…...

DouyinLiveRecorder:一键录制40+平台直播的终极解决方案

DouyinLiveRecorder:一键录制40平台直播的终极解决方案 【免费下载链接】DouyinLiveRecorder 可循环值守和多人录制的直播录制软件,支持抖音、TikTok、Youtube、快手、虎牙、斗鱼、B站、小红书、pandatv、sooplive、flextv、popkontv、twitcasting、wink…...

工业踩坑实录(十七):从40分到高分:工业零件OCR,通用模型一上来就给我打脸

从40分到高分:工业零件OCR,通用模型一上来就给我打脸 工业零件上印一行字,你以为直接丢给OCR就能认。现实是,通用模型跑上去,准确率四十来分,跟瞎猜差不多。 2026-05-08 更新: 发这篇文章之前收…...

Python自动化抓取同花顺问财数据:量化投资的终极解决方案

Python自动化抓取同花顺问财数据:量化投资的终极解决方案 【免费下载链接】pywencai 获取同花顺问财数据 项目地址: https://gitcode.com/gh_mirrors/py/pywencai 还在为获取股票数据而烦恼吗?每天手动登录同花顺问财网站,复制粘贴数据…...

RKDevTool.exe对update.img进行拆包和重新合并

...

交通预测实战:从数据到模型,构建AI驱动的时空预测系统

1. 项目概述:为什么交通预测值得用AI重做一遍?干了这么多年数据分析和算法工程,我越来越觉得,交通预测是个典型的“看起来简单,做起来掉坑”的领域。早些年,大家用ARIMA、卡尔曼滤波,后来上了一…...

超级个体崛起:一人公司(One-Person Company)的技术栈——软件测试从业者的全能武器库

在AI重构生产关系的2026年,“一人公司”已从概念变为触手可及的商业现实。对于深谙质量保障、逻辑严谨且具备工程化思维的软件测试从业者而言,这不仅是职业发展的备选路径,更是一次将“技术债”转化为“数字资产”的价值跃迁。当“单人成军”…...

Spring AI 1.0.7、1.1.6、2.0.0-M6 发布:143 项更新,含重要改进与安全修复

2026 年 5 月 8 日,Spring AI 1.0.7、1.1.6、2.0.0 - M6 版本正式发布,带来 143 项改进、错误修复和文档更新,还包含多项安全修复程序。版本总体亮点此次发布的三个版本在改进、稳定性、文档和安全性方面均有提升。共进行 42 项增强改进&…...

Council框架:构建可编排的智能决策委员会系统

1. 项目概述:从单体应用到分布式决策的演进在软件架构的演进历程中,我们常常面临一个核心挑战:如何将复杂的业务逻辑从臃肿的单体应用中剥离出来,构建出清晰、可维护且具备高内聚、低耦合特性的系统。传统的做法是引入微服务架构&…...

在多轮对话应用中如何利用Taotoken的路由能力保障服务连续性

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 在多轮对话应用中如何利用Taotoken的路由能力保障服务连续性 多轮对话应用的核心在于维持连贯的上下文,为用户提供流畅…...

UE5 GameFeature创建与使用

UE5 的 GameFeature 机制,本质是将游戏功能拆解为独立的、可动态加载/卸载的模块。其设计目标聚焦于以下工程问题: 大世界与长线运营项目:如《堡垒之夜》在节日期间临时注入限时玩法(扔雪球、礼物空投),活…...

教育AI信任构建:透明度与可解释性如何破解多利益相关者困局

1. 项目概述:当AI走进课堂,我们到底在担心什么?最近和几位在一线教学的朋友聊天,发现一个挺有意思的现象:学校采购了一批据说能“智能批改作文”、“个性化推荐习题”的AI教学工具,但老师们用起来的积极性并…...

生成式AI重塑智能座舱:从多模态交互到车端部署的工程实践

1. 项目概述:当生成式AI“坐”进驾驶舱最近几年,生成式AI的浪潮席卷了各行各业,从写诗作画的ChatGPT、Midjourney,到能编程的Copilot,大家已经见怪不怪了。但你可能没太留意,这股风其实早就吹进了汽车行业&…...

可解释AI(XAI)技术解析:从原理到行业落地实践

1. 项目概述:为什么我们需要“看得懂”的AI?最近几年,AI模型的能力边界被不断刷新,从能写诗作画的生成式模型,到能精准预测蛋白质结构的AlphaFold,其表现常常令人惊叹。然而,一个越来越突出的矛…...

CANN/pypto设置立方体切片形状

pypto.set_cube_tile_shapes 【免费下载链接】pypto PyPTO(发音: pai p-t-o):Parallel Tensor/Tile Operation编程范式。 项目地址: https://gitcode.com/cann/pypto 产品支持情况 产品是否支持Ascend 950PR/Ascend 950DT√Atlas A2 …...

CANN学习中心:AddCustom算子工程示例

完整示例:AddCustom 算子工程 【免费下载链接】cann-learning-hub CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。 项目地址: https://gitcode.com/cann/cann-learning-…...

2025届必备的五大降重复率网站解析与推荐

Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 将文本里的AIGC痕迹予以降格处理,其关键环节在于对AI所具备的规律性表达予以破除…...

CANN/社区安全发布指南

版本发布网络安全质量要求 【免费下载链接】community 本项目是CANN开源社区的核心管理仓库,包含社区的治理章程、治理组织、通用操作指引及流程规范等基础信息 项目地址: https://gitcode.com/cann/community 为保障版本网络安全质量,版本发布前…...

在Node.js后端服务中集成Taotoken实现多模型智能对话功能

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 在Node.js后端服务中集成Taotoken实现多模型智能对话功能 为Node.js后端服务添加智能对话能力,是现代应用开发中的常见…...

CANN/pypto设置Pass优化参数

pypto.set_pass_options 【免费下载链接】pypto PyPTO(发音: pai p-t-o):Parallel Tensor/Tile Operation编程范式。 项目地址: https://gitcode.com/cann/pypto 产品支持情况 产品是否支持Atlas A3 训练系列产品/Atlas A3 推理系列产…...

考PMP别乱报!双官方认证考试中心,合规有保障!

在PMP报考过程中,最核心的风险点在于机构资质。一旦误选非官方授权的机构,可能导致35小时培训证明不被认可、报名被驳回,甚至影响后续证书续期。而“双官方认证”是规避这些风险的根本保障。 才聚是国内少数同时持有PMI(美国项目管…...

CANN驱动带外通道状态查询

dcmi_get_device_outband_channel_state 【免费下载链接】driver 本项目是CANN提供的驱动模块,实现基础驱动和资源管理及调度等功能,使能昇腾芯片。 项目地址: https://gitcode.com/cann/driver 函数原型 int dcmi_get_device_outband_channel_s…...

CANN Cumsum算子测试题

决赛题目:Cumsum 算子测试用例设计 【免费下载链接】cann-competitions 本仓库用于 CANN 开源社区各类竞赛、开源课题、社区任务等课题发布、开发者作品提交和展示。 项目地址: https://gitcode.com/cann/cann-competitions 任务说明 本题目要求参赛者为 CA…...

AI/ML学习持久性研究:社会归属感与职业信心的双重引擎效应

1. 项目概述:为什么我们要关心“学生持久性”? 在机器学习与人工智能这个炙手可热的领域,我们常常被顶尖会议的论文、刷榜的模型、高薪的职位所吸引。然而,一个容易被忽视却至关重要的问题是:那些满怀热情踏入这个领域…...

可视化后台轻松维护PC管理系统

一、概述总结蘑菇云响应式企业官网是基于微擎框架开发的 PC 端企业官网搭建系统,支持响应式布局、独立域名绑定、可视化内容管理,可快速搭建适配多终端的企业官方网站。系统具备官方正品保障、源码加密安全稳定,配备产品管理、新闻资讯、在线…...

Snowflake DATEADD函数实战指南:时间计算、性能优化与跨时区处理

1. 为什么 DATEADD 是 Snowflake 里最值得你花时间吃透的函数之一在 Snowflake 实际项目里跑过上百个调度任务、处理过 TB 级时序数据、给金融客户搭过三年滚动预测模型之后,我越来越确信一件事:DATEADD 不是“又一个日期函数”,而是你 SQL 能…...

4G无线RS485/232对传模块:远程数传,赋能智慧园区升级

4G无线RS485/232模块有效解决传统有线方案在老旧园区改造、设备分散区域的数据采集与设备控制难题,适用于智慧园区的建设和改造。 4G无线RS485/232对传模块完全可以用在智慧园区,而且是智慧园区物联网组网的常用核心设备。一、核心适配逻辑 智慧园区里大…...