news 2026/9/20 0:34:18

pypto_pro.language.move 数据搬运接口详解:L1/L0A/L0B/L0C/UB 多级内存搬移与随路量化激活

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
pypto_pro.language.move 数据搬运接口详解:L1/L0A/L0B/L0C/UB 多级内存搬移与随路量化激活
  • 人工智能
  • 编译器
  • 模型编译
  • 高性能计算
  • 深度学习
  • CANN

【免费下载链接】pypto

PyPTO(发音: pai p-t-o):Parallel Tensor/Tile Operation编程范式。

项目地址:https://gitcode.com/cann/pypto
点击查看免费下载

pypto_pro.language.move是 CANN PyPTO 编程范式中最核心的片上数据搬运动作,负责在 L1 Buffer、L0A/L0B Buffer、L0C Buffer、UB(Unified Buffer)等各级片上内存之间搬运 Tile 数据,并可在搬运过程中随路完成格式转换、量化(scale)与激活(ReLU)等融合操作。本文以该接口的官方文档为主体,结合 move 接口声明源码 与仓库中的测试用例,完整讲解其函数原型、参数语义、数据类型与分形约束、offset 子块搬运语义,以及三类量化参数传参方式与 phase 硬件握手机制,帮助开发者直接写出可运行、可对齐精度的搬运代码。

产品支持情况

该接口在不同硬件平台上支持情况不同,接口文档通过注释块明确标注(见 move.md):

  • Ascend 950PR / Ascend 950DT:支持。
  • Atlas A3 训练系列产品 / Atlas A3 推理系列产品:不支持。
  • Atlas A2 训练系列产品 / Atlas A2 推理系列产品:不支持。

也就是说,当前move接口属于 Ascend 950 系列特有能力。配套的 AccToVecMode、ReluPreMode 以及 phase 机制(phase 使用约束)均只在 950 系列上可用。

功能说明

move用于片上 Tile 与 Tile 之间的数据搬运(tile↔tile),不涉及 GM(Global Memory)。从 move 接口源码注释 可以看到其支持的存储空间路径与对应硬件流水:

源(src)目的(dst)硬件流水
Acc(L0C)Vec(UB)fix(Fixpipe)
Mat(L1)Left(L0A)mte1(MTE1)
Mat(L1)Right(L0B)mte1(MTE1)
Mat(L1)Vec(UB)v(Vector)
Vec(UB)Mat(L1)mte3(MTE3)
其他组合v(Vector)

同时,move支持三类随路融合操作(side operations):acc_to_vec_mode(L0C→UB 双目标搬运模式)、relu_pre_mode(随路 ReLU 激活)、scale(Fixpipe 量化比例,支持整块或按列粒度)。这些融合能力使move不只是"搬数据",而是"搬运即计算",减少中间步骤与流水同步开销。

函数原型

pypto_pro.language.move( dst_tile: Tile, src_tile: Tile, offset: Optional[Offset] = None, *, acc_to_vec_mode: Optional[AccToVecMode] = None, relu_pre_mode: Optional[ReluPreMode] = None, scale: Optional[Union[float, Scalar, Tile]] = None, phase: Optional[STPhase] = None, ) -> None

函数返回Noneoffset之后的所有参数均为关键字参数*分隔),且均带默认值,仅dst_tilesrc_tile为必填。从 move 声明 可以确认,scale支持floatScalarTile三种类型,这也决定了三种不同的量化粒度。

参数说明

参数输入/输出说明
dst_tile输出目的操作数,Tile类型,支持的数据类型与分形详见约束说明。
src_tile输入源操作数,Tile类型,支持的数据类型与分形详见约束说明。
offset输入可选,小 Tile 在大 Tile 中的相对位置,格式为[offset_m, offset_n],单位为元素个数。见下方语义详解。
acc_to_vec_mode输入可选,L0C Buffer→UB 搬运时是否开启双目标搬运模式,AccToVecMode 类型。
relu_pre_mode输入可选,L0C Buffer→UB 搬运时是否开启随路 ReLU 操作,ReluPreMode 类型。
scale输入可选,量化参数。数据搬出 L0C Buffer 时由 Fixpipe 乘以该比例并转换到目的数据类型。详见量化参数的使用。
phase输入可选,phase 使用约束。

offset 的子块搬运语义

offset表示小 Tile 在大 Tile 中的相对位置,方向取决于源、目的 Tile 的 shape 大小关系:

  • 当源操作数的 shape ≥ 目的操作数的 shape 时:表示从源操作数的第offset_m行、offset_n列开始,数据搬运量取目的操作数的valid_shape。典型场景是"大 Tile 取子块"。
  • 当源操作数的 shape < 目的操作数的 shape 时:表示从目的操作数的第offset_m行、offset_n列开始,数据搬运量取源操作数的valid_shape。典型场景是"分块写入大 Tile"。

注意 move 源码注释 中 offset 被描述为"从更宽源 Tile 中提取子块"的[offset_m, offset_k],其本质含义与文档一致:以元素为单位的二维偏移。另外在 Acc→Vec 场景下,phaseoffset不能同时使用(move 源码注释 明确 phase 仅用于 Acc→Vec 路径,且不可与 offset 组合)。

acc_to_vec_mode:双目标搬运模式

acc_to_vec_mode仅在 L0C Buffer→UB 场景生效,枚举定义见 AccToVecMode:

枚举值说明
SingleModeVec0单目标模式,将整个矩阵写入 Vec0 的目标 UB。
SingleModeVec1单目标模式,将整个矩阵写入 Vec1 的目标 UB。
DualModeSplitM双目标模式,按 M 维度拆分,M/2×N 个元素写入每个 UB。尾块时框架自动将 valid_M 向上对齐到 2 的倍数得到 aligned_M;Vec0(sub_id=0)得到前 aligned_M/2 行,Vec1(sub_id=1)得到剩余 valid_M − aligned_M/2 行。注意:valid_M 为 1 时仅切分给 Vec0。
DualModeSplitN双目标模式,按 N 维度拆分,M×N/2 个元素写入每个 UB。尾块时框架自动将 valid_N 向上对齐到 32 的倍数得到 aligned_N;Vec0 得到前 aligned_N/2 列,Vec1 得到剩余 valid_N − aligned_N/2 列。注意:valid_N 不超过 16 时仅切分给 Vec0。

双目标模式的核心价值在于:将 L0C 中的矩阵结果一分为二写入两个 UB(对应两个 vector 核),提升后续 Vector 计算的并行度,这是 Flash Attention 等长序列注意力实现的重要手法。

DualModeSplitN 的卡死风险:接口文档特别指出,DualModeSplitNphase同时使用时,若 N 未 32 对齐可能出现卡死现象。建议在矩阵乘运算前对 L0B Buffer 的 N 设置 valid shape,使其向上对齐到 32 的倍数。

relu_pre_mode:随路 ReLU

relu_pre_mode使能 L0C Buffer→UB 搬运过程中的随路 ReLU,枚举定义见 ReluPreMode:

PYPTO_DECLARE_ENUM(ReluPreMode, NormalRelu # 使能随路ReLU操作 )

随路 ReLU 逐元素将负值置零、正值保持不变:

$$dst = \max(src, 0) = \begin{cases} src & src > 0 \ 0 & src \leq 0 \end{cases}$$

该操作由 Fixpipe 硬件在搬运数据离开 L0C 时完成,无需先将数据搬到 UB 再调用 Vector 的激活指令,省去一次数据往返和一次流水同步。

scale:量化参数

scale使能量化功能并设置量化模式下的量化参数,数据在搬出 L0C Buffer 时由 Fixpipe 乘以该比例并转换到目的数据类型。不支持与双目标搬运(DualModeSplitM/DualModeSplitN)同时使用。不同传入形式影响量化粒度,详见量化参数的使用一节。

phase:Fixpipe 硬件握手

phase参数(pypto_pro.language.STPhase类型,取PartialFinal)用于 L0C→UB 搬运与矩阵乘之间建立 unit_flag 硬件握手,详细机制见 phase 使用约束。在仓库的自动化测试中也有专门覆盖,例如 test_move_phase.py 与 test_scale_phase_atomic_order.py。

数据类型与分形约束

接口文档给出了完整的"源 → 目的"约束矩阵,覆盖分形(ND/NZ/ZN/ZZ/NN/DN)与数据类型两方面要求:

源 → 目的分形要求数据类型要求
L1 Buffer → L0A Buffer源支持 ND、NZ、ZN、ZZ,目的固定为 NZ源与目的必须相同,支持 DT_INT8、DT_FP8E4M3FN、DT_FP8E5M2、DT_HF8、DT_FP16、DT_BF16、DT_FP32、DT_FP4E2M1、DT_FP4E1M2、DT_FP8E8M0
L1 Buffer → L0B Buffer源支持 ND、NZ、ZN、ZZ,目的固定为 ZN源与目的必须相同,支持的数据类型同上
UB → UB(目的 shape ≤ 源 shape)不校验分形源与目的必须相同;非 ND → NZ 与 ND → NZ 支持集合略有差异(详见 move.md)
UB → UB(目的 shape > 源 shape)ND → ND、NZ → NZ源与目的必须相同,支持 DT_INT8、DT_INT32、DT_FP16、DT_BF16、DT_FP32、DT_FP8E4M3FN、DT_FP8E5M2、DT_FP8E8M0、DT_HF8、DT_FP4E2M1、DT_FP4E1M2
UB → L1 Buffer(目的 shape ≤ 源 shape)源支持 ND、NZ,目的不校验分形源与目的必须相同,支持 DT_INT8、DT_FP8E4M3FN、DT_FP8E5M2、DT_HF8、DT_FP16、DT_BF16、DT_FP32、DT_FP4E2M1、DT_FP4E1M2、DT_FP8E8M0
UB → L1 Buffer(目的 shape > 源 shape)源支持 ND、NZ,目的不校验分形源与目的必须相同,在上一行基础上额外支持 DT_INT32
L1 Buffer → BiasTable Buffer目的 layout 固定为 ND支持 DT_INT32 → DT_INT32、DT_FP32 → DT_FP32、DT_FP16 → DT_FP32、DT_BF16 → DT_FP32
L1 Buffer → Fixpipe Buffer不校验分形目的必须为 DT_INT64 或 DT_UINT64,源数据类型不做限制
L1 Buffer → L0A_MX Buffer源与目的分形均为 ZZ源与目的必须相同,仅支持 DT_FP8E8M0
L1 Buffer → L0B_MX Buffer源与目的分形均为 NN源与目的必须相同,仅支持 DT_FP8E8M0
L0C Buffer → UB(不配置 scale)NZ → ND、NZ → DN、NZ → NZ支持 DT_FP32 → DT_FP32/DT_FP16/DT_BF16,以及 DT_INT32 → DT_INT32
L0C Buffer → UB(配置 scale)NZ → ND、NZ → DN、NZ → NZ支持 DT_FP32 → DT_INT8/DT_UINT8/DT_HF8/DT_FP16/DT_BF16/DT_FP8E4M3FN/DT_FP32,以及 DT_INT32 → DT_INT8/DT_UINT8/DT_FP16/DT_BF16
L0C Buffer → L1 Buffer(仅支持目的 shape > 源 shape)NZ → NZ支持 DT_FP32 → DT_FP32/DT_FP16/DT_BF16,以及 DT_INT32 → DT_INT32

从源码可以印证这些存储单元与硬件流水的对应关系:codegen_common.h 中列出了各缓冲区类型的地址修饰符(如__cc__对应 L0C、__fbuf__对应 Fixpipe Buffer、__ca__/__cb__对应 L0A/L0B),codegen_common.h 中给出了各流水(PIPE_MTE1/PIPE_MTE3/PIPE_V/PIPE_FIX 等)的标识。L0C→UB 场景实际上由 Fixpipe(PIPE_FIX)承载,这正是scalerelu_pre_mode能在搬运过程中"随路"完成的硬件基础。

尾块与 L0A_MX/L0B_MX 的补充约束

  • 尾块场景:需要搭配pypto_pro.language.set_validshape与 TileType 中的compact参数使用,否则可能出现精度失败或卡死现象。
  • L0A_MX / L0B_MX 地址约束:L1 Buffer → L0A_MX/L0B_MX 要求目的 Tile 必须满足L0A_MX Buffer 地址 = L0A Buffer 地址 >> 4L0B_MX Buffer 地址 = L0B Buffer 地址 >> 4,否则 MX 矩阵乘时会读取错误的量化系数。

调用示例

示例一:L1 → L0A / L0B 喂数给矩阵乘

这是最典型的矩阵乘(Matmul)前处理流程:先用pl.load把 GM 数据搬到 L1 Buffer,再用pl.move把 L1 数据分别送入 L0A(左矩阵,NZ)与 L0B(右矩阵,ZN),最后pl.matmul在 L0C 中完成计算:

import os import pypto_pro.language as pl import torch @pl.jit(auto_mutex=True) def kernel( a: pl.Tensor[[64, 128], pl.DT_FP16], b: pl.Tensor[[128, 32], pl.DT_FP16], out: pl.Tensor[[64, 32], pl.DT_FP32], ): a_l1 = pl.make_tile_group( type=pl.TileType(shape=[64, 128], dtype=pl.DT_FP16, target_memory=pl.MemorySpace.Mat, layout=pl.NZ), addrs=0x00000, mutex_ids=[0]) b_l1 = pl.make_tile_group( type=pl.TileType(shape=[128, 32], dtype=pl.DT_FP16, target_memory=pl.MemorySpace.Mat, layout=pl.NZ), addrs=0x10000, mutex_ids=[1]) a_l0a = pl.make_tile_group( type=pl.TileType(shape=[64, 128], dtype=pl.DT_FP16, target_memory=pl.MemorySpace.Left, layout=pl.NZ), addrs=0x0, mutex_ids=[2]) b_l0b = pl.make_tile_group( type=pl.TileType(shape=[128, 32], dtype=pl.DT_FP16, target_memory=pl.MemorySpace.Right, layout=pl.ZN), addrs=0x0, mutex_ids=[3]) c_l0c = pl.make_tile_group( type=pl.TileType(shape=[64, 32], dtype=pl.DT_FP32, target_memory=pl.MemorySpace.Acc, layout=pl.NZ), addrs=0x0, mutex_ids=[4]) with pl.section_cube(): cur_a = a_l1.current() cur_b = b_l1.current() al = a_l0a.current() br = b_l0b.current() ac = c_l0c.current() pl.load(cur_a, a, [0, 0]) pl.load(cur_b, b, [0, 0]) pl.move(al, cur_a) # L1 -> L0A pl.move(br, cur_b) # L1 -> L0B pl.matmul(ac, al, br) pl.store(out, ac, [0, 0]) if __name__ == "__main__": device = f"npu:{int(os.environ.get('TILE_FWK_DEVICE_ID', 0))}" torch.npu.set_device(device) torch.manual_seed(42) a = torch.randn([64, 128], device=device, dtype=torch.float16) b = torch.randn([128, 32], device=device, dtype=torch.float16) out = torch.zeros([64, 32], device=device, dtype=torch.float32) kernel(a, b, out) torch.npu.synchronize() ref = torch.matmul(a.float(), b.float()) torch.testing.assert_close(out, ref, rtol=2e-2, atol=2e-2) print(f"max diff = {(out - ref).abs().max().item()}")

要点说明:

  • L1 → L0A 时目的固定 NZ,L1 → L0B 时目的固定 ZN,与本例 TileType 中的 layout 一致。
  • 矩阵乘对右矩阵采用 ZN 布局,示例中b在 L1 中是 NZ(由 load 写入),move 到 L0B 时目的声明为 ZN。
  • 使用make_tile_group+current()在 cube section 内取当前 Tile,配合mutex_ids管理缓冲区互斥。

示例二:UB 数据转置写入 L1 Buffer

当左矩阵或右矩阵由 Vector 计算在 UB 中产生时,可先通过pl.move将 ND 转换为 NZ,再将结果写入 L1 Buffer:

  • 不转置时,L1 Buffer Tile 使用 NZ,shape 与 UB 中的 NZ Tile 相同。
  • 转置时,L1 Buffer Tile 使用 ZN,shape 的两个维度与 UB 中的 NZ Tile 互换。源 Tile 的 NZ [R, C] 与目的 Tile 的 ZN [C, R] 表示相同的物理分形,因此 ZN 写入本质是"零拷贝转置"。
矩阵是否转置UB 中的 NZ TileL1 Buffer Tile
左矩阵 A[M, K]shape=[M, K]shape=[M, K],NZ
左矩阵 A[M, K]shape=[K, M]shape=[M, K],ZN
右矩阵 B[K, N]shape=[K, N]shape=[K, N],NZ
右矩阵 B[K, N]shape=[N, K]shape=[K, N],ZN

分块写入 L1 Buffer 时可通过offset指定写入位置;源 Tile 的有效区域必须完整落入目的 Tile 范围内。以下示例中vector_result表示 Vector 计算产生的 [K, M] 数据:第一次 move 将其转换为 NZ,第二次 move 将其转置写入 L1 Buffer,得到供左矩阵使用的 [M, K]、ZN 数据:

import pypto_pro.language as pl M, K = 64, 128 # 前序Vector计算的输出:UB中的ND [K, M] vector_result = pl.make_tile( pl.TileType( shape=[K, M], dtype=pl.DT_FP16, target_memory=pl.MemorySpace.Vec, layout=pl.ND, ), addr=0x0000, ) # ND转换为NZ时使用的UB Tile vector_nz = pl.make_tile( pl.TileType( shape=[K, M], dtype=pl.DT_FP16, target_memory=pl.MemorySpace.Vec, layout=pl.NZ, ), addr=0x4000, ) # 转置后的数据写入L1 Buffer,逻辑shape为[M, K] lhs_l1 = pl.make_tile( pl.TileType( shape=[M, K], dtype=pl.DT_FP16, target_memory=pl.MemorySpace.Mat, layout=pl.ZN, ), addr=0x20000, ) with pl.section_vector(): pl.move(vector_nz, vector_result) # ND [K, M] → NZ [K, M] pl.move(lhs_l1, vector_nz) # NZ [K, M] → ZN [M, K]

仓库中 test_move_nd_to_nz_vec.py 对该场景有直接覆盖:测试中dstflat_view共享同一地址但属于不同 IR 值,auto_mutex无法识别该依赖,因此测试显式插入pl.system.sync_src(set_pipe=pl.PipeType.V, wait_pipe=pl.PipeType.MTE3, event_id=3)来保证 Vector 与 MTE3 之间的执行顺序——这提示我们在真实工程中,当搬运目的地址与源存在别名关系时,需要手动管理流水同步。

量化参数的使用

scale支持三种传参形式,对应三种量化粒度:

方式一:scale 为编译期常量(float)

# acc: L0C Buffer中的Tile, DT_FP32 # vec_tile: UB Tile, DT_INT8 pl.matmul(acc, q_left, k_right) pl.move(vec_tile, acc, scale=0.5) # L0C Buffer -> UB,随路按 0.5 量化为 INT8

直接传固定值,适用于整块 Tile 使用同一比例。从 move 源码注释 可知,该路径走 deqScalar(per-tensor 量化)。

方式二:scale 为运行时标量(Scalar)

import struct @pl.jit() def kernel(..., scale_bits: pl.DT_INT32): # ... pl.move(vec_tile, acc, scale=scale_bits) scale_bits = struct.unpack("!I", struct.pack("!f", 0.5))[0] kernel(..., scale_bits=scale_bits)

量化比例在运行时确定,需按数据类型传值:

  • DT_FP32:直接传原始比例值(如0.5)。源码注释说明运行时 FP32 标量会被自动按 IEEE-754 位模式重解释(codegen bitcast),因此传原始 float 数值即可。
  • DT_INT32、DT_INT64:传预编码的 float32 位模式转成的整数,即struct.pack("!f", 0.5)拆包后的整数。其他运行时标量 dtype(FP16/BF16/无符号/窄整数)会在解析期被拒绝。

方式三:scale 为 Tile 类型(逐列量化)

每列使用独立比例,适用于 per-channel 量化场景,前提条件较多:

  • 目标存储区域必须为Fixpipe Bufferpl.MemorySpace.Scaling)。
  • shape 为[1, N](列量化),N 必须是 16 的倍数且 N ≤ 512;[N, 1]的行量化不支持(move 源码注释 明确说明硬件只支持每列缩放)。
  • dtype 为 DT_INT64。
  • 目的操作数的 Tile 数据类型为DT_INT8时,Fixpipe Buffer 中每个 DT_INT64 元素的bit46 需置 1,用于选择有符号量化;未置位时 L0C Buffer 中的负值会被按无符号解读。
  • 用户需先把比例数据从 GM 搬到 L1 Buffer,再搬到 Fixpipe Buffer,并完成 MTE1→FIX 同步。框架不会自动分配缓冲或插入同步,数据流完全由用户负责(move 源码注释)。
# fp_mat: L1 Buffer中的Tile, shape [1, 64], DT_INT64 # fp_tile: Fixpipe Buffer中的Tile, shape [1, 64], DT_INT64 # acc: L0C Buffer中的Tile, DT_INT32 # vec_tile: UB Tile, DT_FP16 @pl.jit() def kernel(..., fp_params: pl.Tensor[[1, 64], pl.DT_INT64]): # ... pl.load(fp_mat, fp_params, [0, 0]) # GM -> L1 pl.move(fp_tile, fp_mat) # L1 Buffer -> Fixpipe Buffer pl.system.sync_src(set_pipe=pl.PipeType.MTE1, wait_pipe=pl.PipeType.FIX, event_id=1) pl.system.sync_dst(set_pipe=pl.PipeType.MTE1, wait_pipe=pl.PipeType.FIX, event_id=1) pl.matmul(acc, q_left, k_right) pl.move(vec_tile, acc, scale=fp_tile) # L0C Buffer -> UB,按列独立比例反量化为DT_FP16

Host 侧如何准备量化比例张量,分两种情况:

# 情况一、Kernel需要DT_INT64,若使用float32的比例张量,需要先进行转换 import torch_npu scale_value = 2.0 scale_fp32 = torch.ones(1, 64, dtype=torch.float32, device=device) * scale_value fp_params = torch_npu.npu_trans_quant_param(scale_fp32) # 情况二、目的Tile数据类型为DT_INT8时,需要将Fixpipe Buffer中的Tile每个INT64元素的bit46需置1 def _make_scale_tensor(device: str, scale_values: list) -> torch.Tensor: scale_bits_list = [] for scale_value in scale_values: scale_bits = struct.unpack("!I", struct.pack("!f", scale_value))[0] scale_bits |= 1 << 46 # signed INT8 flag scale_bits_list.append(scale_bits) return torch.tensor(scale_bits_list, dtype=torch.int64, device=device).reshape(1, 64) scale_values = [2.0] * 64 fp_params = _make_scale_tensor(device, scale_values)

仓库对量化参数有大量针对性测试,可作为实现参考:test_scale_param.py、test_scale_per_channel_advanced.py、test_scale_move_dtype.py、test_scale_dtype_validation.py、test_scale_value_range.py 以及 test_scale_relu_fusion.py(scale 与 ReLU 融合)。

phase 与双目标搬运的配合

phase(STPhase)与acc_to_vec_mode是 L0C→UB 场景下最常用的两个可选参数,二者配合可实现"双目标搬运 + 硬件握手"的高效流水。需要注意:

  • DualModeSplitN 与 phase 同时使用时,若 N 未 32 对齐,可能出现卡死现象(详见参数说明),建议对 L0B 的 N 预先对齐到 32 的倍数。
  • 尾块 + 双目标:框架自动对齐 valid_M/valid_N,UB 侧用户需自行计算两个 Vec 的 valid shape。完整示例见 AccToVecMode 文档:DualModeSplitM 下aligned_M=34v0=(valid_M+1)//2*2//2v1=valid_M-v0;DualModeSplitN 下aligned_N=64v0=(valid_N+31)//32*32//2v1=valid_N-v0
  • 仓库测试 test_dual_mode_tail.py 专门验证尾块场景下的双目标搬运切分行为。

Flash Attention 的 QK matmul 是 phase + move 配合的经典模式:matmul 结果需要 vector 核做 softmax 后处理,store只能直接写 GM、无法在 UB 上继续计算,因此必须通过move(配合DualModeSplitNSTPhase.Final)将累加器数据搬到 UB。完整正确用法与三个错误案例(matmul 无 Final 导致卡死、store 未配 phase 导致精度问题、循环内 store(Final) 后 matmul 卡死)参见 phase 使用约束。

总结

pypto_pro.language.move是 Ascend 950 系列上连接 Cube(矩阵乘)与 Vector(UB 计算)两套流水、贯通 L1/L0A/L0B/L0C/UB 多级存储的核心动作。使用时需要重点关注四类信息:

  1. 路径合法性:根据约束说明确认源/目的存储空间组合及其数据类型、分形是否受支持,尤其注意 L0C→UB 的 Fixpipe 路径与 L1→L0A/L0B 的 MTE1 路径差异。
  2. offset 语义:根据源/目的 shape 大小关系确定是"从源读子块"还是"向目的写子块",并确保有效区域完整落入目的范围。
  3. 量化粒度scale的 float/Scalar/Tile 三种形式分别对应整块、运行时标量、逐列三种量化粒度,逐列量化时需自行完成 GM→L1→Fixpipe 的数据流与 MTE1→FIX 同步,INT8 场景还需置位 bit46。
  4. 同步与握手:尾块场景需配合set_validshapecompact;需要省去软件同步时可配置phase走 unit_flag 硬件握手,但必须保证 matmul 与 move 的 phase 配对使用并以 Final 收尾。
  • 人工智能
  • 编译器
  • 模型编译
  • 高性能计算
  • 深度学习
  • CANN

【免费下载链接】pypto

PyPTO(发音: pai p-t-o):Parallel Tensor/Tile Operation编程范式。

项目地址:https://gitcode.com/cann/pypto
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 0:33:21

Windows 下用 Bash 的完整指南:Git Bash 与 WSL2 配置实践

作为一个常年主力 Windows 笔记本、偶尔用 Mac 的前端开发者&#xff0c;我对这种挫败感太熟了&#xff1a;刚在 Mac 上敲顺的ls、grep、cat、curl&#xff0c;切回 Windows 后第一件事就是在 PowerShell 里挨个报错&#xff1b;项目里不少脚手架和 npm scripts 是按 Unix 语法…

作者头像 李华
网站建设 2026/9/20 0:29:40

Release check

人工智能AI Agent交互助手工具调用MCP Clients本地部署Agent 工作流RAG 【免费下载链接】zeroclaw Fast, small, and fully autonomous AI personal assistant infrastructure, any OS, any platform — deploy anywhere, swap anything &#x1f980; 项目地址&#xff1a; ht…

作者头像 李华
网站建设 2026/9/20 0:28:47

Cursor 是编程提效工具,Base URL 走 TaoToken 通道行不行

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 0:27:04

RN鸿蒙化实践:Modal弹窗实现与白屏渲染异常排查

在React Native跨端这条路上&#xff0c;OpenHarmony是一个绕不开的新平台。最近把公司的核心流程页迁移到鸿蒙生态上&#xff0c;最让我记忆犹新的不是首页性能优化&#xff0c;也不是复杂的动画&#xff0c;而是一个看似人畜无害的Modal确认取消弹窗。这东西在Android/iOS上闭…

作者头像 李华
网站建设 2026/9/20 0:26:51

额度消耗异常?TaoToken 这样改 AI_GATEWAY_BASE_URL,summary_key 单独建

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华