LoadDataWithTranspose
产 品 支 持 情 况
功 能 说 明
该 接 口 实 现 带 转 置 的2D格 式 数 据 从A1/B1到A2/B2的 加 载。
下 面 通 过 示 例 来 讲 解 接 口 功 能 和 关 键 参 数:下 文 图 中 一 个N形 或 者 一 个Z形 代 表 一 个 分 形。
对 于uint8_t/int8_t数 据 类 型,每 次 迭 代 处 理32*32*1B数 据,可 处 理2个 分 形(一 个 分 形512B),每 次 迭 代 中,源 操 作 数 中2个 连 续 的16*32分 形 将 被 合 并 为1个32*32的 方 块 矩 阵,基 于 方 块 矩 阵 做 转 置,转 置 后 分 裂 为2个16*32分 形,根 据 目 的 操 作 数 分 形 间 隔 等 参 数 可 以 有 不 同 的 排 布。
如 下 图 示 例:
- 共 需 要 处 理3072B的 数 据,每 次 迭 代 处 理32*32*1B数 据,需 要3次 迭 代 可 以 完 成,repeatTime = 3;
- srcStride = 1,表 示 相 邻 迭 代 间,源 操 作 数 前 一 个 方 块 矩 阵 与 后 一 个 方 块 矩 阵 起 始 地 址 的 间 隔 为1(单 位:32*32*1B),这 里 的 单 位 实 际 上 是 拼 接 后 的 方 块 矩 阵 的 大 小;
- dstGap = 1,表 示 相 邻 迭 代 间,目 的 操 作 数 前 一 个 迭 代 第 一 个 分 形 的 结 束 地 址 到 下 一 个 迭 代 第 一 个 分 形 起 始 地 址 的 间 隔 为1(单 位:512B);
- dstFracGap = 0,表 示 每 个 迭 代 内 目 的 操 作 数 前 一 个 分 形 的 结 束 地 址 与 后 一 个 分 形 起 始 地 址 的 间 隔 为0(单 位:512B)。

如 下 图 示 例:
- repeatTime和srcStride的 解 释 和 上 图 示 例 一 致。
- dstGap = 0,表 示 相 邻 迭 代 间,目 的 操 作 数 前 一 个 迭 代 第 一 个 分 形 的 结 束 地 址 和 下 一 个 迭 代 第 一 个 分 形 起 始 地 址 无 间 隔。
- dstFracGap = 2,表 示 每 个 迭 代 内 目 的 操 作 数 前 一 个 分 形 的 结 束 地 址 与 后 一 个 分 形 起 始 地 址 的 间 隔 为2(单 位:512B)。

对 于half/bfloat16_t数 据 类 型,每 次 迭 代 处 理16*16*2B数 据,可 处 理1个 分 形(一 个 分 形512B),每 次 迭 代 中,源 操 作 数 中1个16*16分 形 将 被 转 置。
- 共 需 要 处 理1536B的 数 据,每 次 迭 代 处 理16*16*2B数 据,需 要3次 迭 代 可 以 完 成,repeatTime = 3;
- srcStride = 1,表 示 相 邻 迭 代 间,源 操 作 数 前 一 个 方 块 矩 阵 与 后 一 个 方 块 矩 阵 起 始 地 址 的 间 隔 为1 (单 位:16*16*2B);
- dstGap = 0,表 示 相 邻 迭 代 间,目 的 操 作 数 前 一 个 迭 代 第 一 个 分 形 的 结 束 地 址 到 下 一 个 迭 代 第 一 个 分 形 起 始 地 址 无 间 隔;
- 该 场 景 下,因 为 其 分 形 即 为 方 块 矩 阵,每 个 迭 代 处 理 一 个 分 形,不 存 在 迭 代 内 分 形 的 间 隔,该 参 数 设 置 无 效。

对 于float/int32_t/uint32_t数 据 类 型,每 次 迭 代 处 理16*16*4B数 据,可 处 理2个 分 形(一 个 分 形512B),每 次 迭 代 中,源 操 作 数2个 连 续 的16*8分 形 将 被 合 并 为1个16*16的 方 块 矩 阵,基 于 方 块 矩 阵 做 转 置,转 置 后 分 裂 为2个16*8分 形,根 据 目 的 操 作 数 分 形 间 隔 等 参 数 可 以 有 不 同 的 排 布。
如 下 图 示 例:
- 共 需 要 处 理3072B的 数 据,每 次 迭 代 处 理16*16*4B数 据,需 要3次 迭 代 可 以 完 成,repeatTime = 3;
- srcStride = 1,表 示 相 邻 迭 代 间,源 操 作 数 前 一 个 方 块 矩 阵 与 后 一 个 方 块 矩 阵 起 始 地 址 的 间 隔 为1(单 位:16*16*4B),这 里 的 单 位 实 际 上 是 拼 接 后 的 方 块 矩 阵 的 大 小;
- dstGap = 1,表 示 相 邻 迭 代 间,目 的 操 作 数 前 一 个 迭 代 第 一 个 分 形 的 结 束 地 址 到 下 一 个 迭 代 第 一 个 分 形 起 始 地 址 的 间 隔 为1(单 位:512B);
- dstFracGap = 0,表 示 每 个 迭 代 内 目 的 操 作 数 前 一 个 分 形 结 束 地 址 与 后 一 个 分 形 起 始 地 址 的 间 隔 为0(单 位:512B)。

如 下 图 示 例:
- repeatTime和srcStride的 解 释 和 上 图 示 例 一 致。
- dstGap = 0,表 示 相 邻 迭 代 间,目 的 操 作 数 前 一 个 迭 代 第 一 个 分 形 的 结 束 地 址 和 下 一 个 迭 代 第 一 个 分 形 起 始 地 址 无 间 隔。
- dstFracGap = 2,表 示 每 个 迭 代 内 目 的 操 作 数 前 一 个 分 形 结 束 地 址 与 后 一 个 分 形 起 始 地 址 的 间 隔 为2(单 位:512B)。

对 于int4b_t数 据 类 型,每 次 迭 代 处 理64*64*0.5B数 据,可 处 理4个 分 形(一 个 分 形512B),每 次 迭 代 中,源 操 作 数 中4个 连 续 的16*64分 形 将 被 合 并 为1个64*64的 方 块 矩 阵,基 于 方 块 矩 阵 做 转 置,转 置 后 分 裂 为4个16*64分 形,根 据 目 的 操 作 数 分 形 间 隔 等 参 数 可 以 有 不 同 的 排 布。
int4b_t数 据 类 型 需 要 两 个 数 拼 成 一 个int8_t或uint8_t的 数,拼 凑 的 规 则 如 下:
如 下 图 示 例:
- 共 需 要 处 理6144B的 数 据,每 次 迭 代 处 理64*64*0.5B数 据,需 要3次 迭 代 可 以 完 成,repeatTime = 3;
- srcStride = 1,表 示 相 邻 迭 代 间,源 操 作 数 前 一 个 方 块 矩 阵 与 后 一 个 方 块 矩 阵 起 始 地 址 的 间 隔 为1(单 位:64*64*0.5B),这 里 的 单 位 实 际 上 是 拼 接 后 的 方 块 矩 阵 的 大 小;
- dstGap = 1,表 示 相 邻 迭 代 间,目 的 操 作 数 前 一 个 迭 代 第 一 个 分 形 的 结 束 地 址 到 下 一 个 迭 代 第 一 个 分 形 起 始 地 址 的 间 隔 为1(单 位:512B);
- dstFracGap = 0,表 示 每 个 迭 代 内 目 的 操 作 数 前 一 个 分 形 的 结 束 地 址 与 后 一 个 分 形 起 始 地 址 的 间 隔 为0(单 位:512B)。

如 下 图 示 例:
- repeatTime和srcStride的 解 释 和 上 图 示 例 一 致。
- dstGap = 0,表 示 相 邻 迭 代 间,目 的 操 作 数 前 一 个 迭 代 第 一 个 分 形 的 结 束 地 址 和 下 一 个 迭 代 第 一 个 分 形 起 始 地 址 无 间 隔。
- dstFracGap = 2,表 示 每 个 迭 代 内 目 的 操 作 数 前 一 个 分 形 的 结 束 地 址 与 后 一 个 分 形 起 始 地 址 的 间 隔 为2(单 位:512B)。

函 数 原 型
template <typename T>
__aicore__ inline void LoadDataWithTranspose(const LocalTensor<T>& dst, const LocalTensor<T>& src, const LoadData2dTransposeParams& loadDataParams)
// 该 函 数 原 型 仅 支 持Ascend 950PR/Ascend 950DT
template <typename T>
__aicore__ inline void LoadDataWithTranspose(const LocalTensor<T>& dst, const LocalTensor<T>& src, const LoadData2dTransposeParamsV2& loadDataParams)
参 数 说 明
表 1 模 板 参 数 说 明
表 2 参 数 说 明
目 的 操 作 数,结 果 矩 阵,类 型 为LocalTensor。 Ascend 950PR/Ascend 950DT,支 持 的TPosition为B2。 Kirin X90,支 持 的TPosition为A2/B2。 | ||
Ascend 950PR/Ascend 950DT,支 持 的TPosition为B1。 Kirin X90,支 持 的TPosition为A1/B1。 | ||
LoadDataWithTranspose相 关 参 数,类 型 为LoadData2dTransposeParams。 具 体 定 义 请 参 考${INSTALL_DIR}/include/ascendc/basic_api/interface/kernel_struct_mm.h,${INSTALL_DIR}请 替 换 为CANN软 件 安 装 后 文 件 存 储 路 径。 参 数 说 明 请 参 考表3。 | ||
LoadDataWithTranspose相 关 参 数,类 型 为LoadData2dTransposeParamsV2。 参 数 说 明 请 参 考表4。 |
表 3 LoadData2dTransposeParams结 构 体 内 参 数 说 明
表 4 LoadData2dTransposeParamsV2结 构 体 内 参 数 说 明
约 束 说 明
- repeat=0表 示 不 执 行 搬 运 操 作。
- 开 发 者 需 要 保 证 目 的 操 作 数 转 置 后 的 分 形 没 有 重 叠。
- 操 作 数 地 址 对 齐 要 求 请 参 见通 用 地 址 对 齐 约 束。
- 针 对 以 下 型 号,推 荐 使 用LoadData2dTransposeParamsV2作 为 参 数,该 参 数 具 有 更 精 细 的 搬 运 粒 度。
- Ascend 950PR/Ascend 950DT
调 用 示 例
示 例1:该 示 例 输 入a矩 阵 为int8_t类 型,shape为[40,70],输 入b矩 阵 为int8_t类 型,shape为[70,50],输 出c的 类 型 为int32_t。a矩 阵 从A1->A2转 置,b矩 阵 从B1->B2转 置,之 后 进 行Mmad计 算 和Fixpipe计 算。完 整 使 用 样 例 请 参 见LoadData_L12L0样 例。
Textuint16_t m = 40, k = 70, n = 50; uint32_t fractalShape[0] = 16; uint32_t fractalShape[1] = 32 / sizeof(int8_t); uint32_t fractalNum = 2 uint32_t fractalSize = fractalShape[0] * fractalShape[1]; // A矩 阵 LoadDataWithTranspose: Nz -> Zz // dstoffset要 根 据A矩 阵 在L0上,宽 度 方 向 的 对 齐 来 求 解 // CeilDivision计 算 两 个 整 数 相 除,结 果 向 上 取 整 uint32_t dstOffset = CeilDivision(k, fractalShape[1]) * fractalSize * fractalNum; uint32_t srcOffset = CeilDivision(k, fractalShape[0] * fractalNum) * fractalSize * fractalNum; AscendC::LoadData2dTransposeParams loadDataParams; loadDataParams.startIndex = 0; loadDataParams.repeatTimes = CeilDivision(k, fractalShape[0] * fractalNum); loadDataParams.srcStride = 1; loadDataParams.dstGap = 0; loadDataParams.dstFracGap = CeilDivision(k, fractalShape[1]) - 1; for (int i = 0; i < CeilDivision(m, fractalShape[1]); ++i) { AscendC::LoadDataWithTranspose(a2Local[i * dstOffset], a1Local[i * srcOffset], loadDataParams); } // B矩 阵 LoadDataWithTranspose: Nz -> Zn // CeilDivision计 算 两 个 整 数 相 除,结 果 向 上 取 整 uint32_t dstOffset = CeilDivision(n, fractalShape[0] * fractalNum) * fractalSize * fractalNum; uint32_t srcOffset = fractalSize * fractalNum; AscendC::LoadData2dTransposeParams loadDataParams; loadDataParams.startIndex = 0; loadDataParams.repeatTimes = CeilDivision(n, fractalShape[1]); loadDataParams.srcStride = CeilDivision(k, fractalShape[0] * fractalNum); loadDataParams.dstGap = 1; loadDataParams.dstFracGap = 0; for (int i = 0; i < CeilDivision(k, fractalShape[0] * fractalNum); ++i) { AscendC::LoadDataWithTranspose(b2Local[i * dstOffset], b1Local[i * srcOffset], loadDataParams); }示 例2:该 示 例 输 入a矩 阵 为half类 型,shape为[40,70],输 入b矩 阵 为half类 型,shape为[70,50],输 出c的 类 型 为float。a矩 阵 从A1->A2转 置,b矩 阵 从B1->B2转 置,之 后 进 行Mmad计 算 和Fixpipe计 算。完 整 使 用 样 例 请 参 见LoadData_L12L0样 例。
Textuint16_t m = 40, k = 70, n = 50; uint32_t fractalShape[0] = 16; uint32_t fractalShape[1] = 32 / sizeof(half); uint32_t fractalNum = 1 uint32_t fractalSize = fractalShape[0] * fractalShape[1]; // A矩 阵 LoadDataWithTranspose: Nz -> Zz // CeilDivision计 算 两 个 整 数 相 除,结 果 向 上 取 整 uint32_t dstOffset = CeilDivision(k, fractalShape[1]) * fractalSize * fractalNum; uint32_t srcOffset = CeilDivision(k, fractalShape[0] * fractalNum) * fractalSize * fractalNum; AscendC::LoadData2dTransposeParams loadDataParams; loadDataParams.startIndex = 0; loadDataParams.repeatTimes = CeilDivision(k, fractalShape[0] * fractalNum); loadDataParams.srcStride = 1; loadDataParams.dstGap = 0; loadDataParams.dstFracGap = CeilDivision(k, fractalShape[1]) - 1; for (int i = 0; i < CeilDivision(m, fractalShape[1]); ++i) { AscendC::LoadDataWithTranspose(a2Local[i * dstOffset], a1Local[i * srcOffset], loadDataParams); } // B矩 阵 LoadDataWithTranspose: Nz -> Zn // CeilDivision计 算 两 个 整 数 相 除,结 果 向 上 取 整 uint32_t dstOffset = CeilDivision(n, fractalShape[0] * fractalNum) * fractalSize * fractalNum; uint32_t srcOffset = fractalSize * fractalNum; AscendC::LoadData2dTransposeParams loadDataParams; loadDataParams.startIndex = 0; loadDataParams.repeatTimes = CeilDivision(n, fractalShape[1]); loadDataParams.srcStride = CeilDivision(k, fractalShape[0] * fractalNum); loadDataParams.dstGap = 0; loadDataParams.dstFracGap = 0; for (int i = 0; i < CeilDivision(k, fractalShape[0] * fractalNum); ++i) { AscendC::LoadDataWithTranspose(b2Local[i * dstOffset], b1Local[i * srcOffset], loadDataParams); }示 例3:该 示 例 输 入a矩 阵 为float类 型,shape为[40,70],输 入b矩 阵 为float类 型,shape为[70,50],输 出c的 类 型 为float。a矩 阵 从A1->A2转 置,b矩 阵 从B1->B2转 置,之 后 进 行Mmad计 算 和Fixpipe计 算。完 整 使 用 样 例 请 参 见LoadData_L12L0样 例。
Textuint32_t m = 40, k = 70, n = 50; uint32_t fractalShape[0] = 16; uint32_t fractalShape[1] = 32 / sizeof(float); uint32_t fractalNum = 2 uint32_t fractalSize = fractalShape[0] * fractalShape[1]; // A矩 阵 LoadDataWithTranspose: Zz -> Zz // CeilDivision计 算 两 个 整 数 相 除,结 果 向 上 取 整 uint32_t dstOffset = CeilDivision(k, fractalShape[1] * fractalNum) * fractalSize * fractalNum; uint32_t srcOffset = fractalSize * fractalNum; AscendC::LoadData2dTransposeParams loadDataParams; loadDataParams.startIndex = 0; loadDataParams.repeatTimes = CeilDivision(k, fractalShape[1] * fractalNum); loadDataParams.srcStride = CeilDivision(m, fractalShape[1] * fractalNum); loadDataParams.dstGap = 1; loadDataParams.dstFracGap = 0; for (int i = 0; i < CeilDivision(m, fractalShape[1] * fractalNum); ++i) { AscendC::LoadDataWithTranspose(a2Local[i * dstOffset], a1Local[i * srcOffset], loadDataParams); } // B矩 阵 LoadDataWithTranspose: Nz -> Zn // CeilDivision计 算 两 个 整 数 相 除,结 果 向 上 取 整 uint32_t dstOffset = CeilDivision(n, fractalShape[0]) * fractalSize * fractalNum; uint32_t srcOffset = CeilDivision(n, fractalShape[1] * fractalNum) * fractalSize * fractalNum; AscendC::LoadData2dTransposeParams loadDataParams; loadDataParams.startIndex = 0; loadDataParams.repeatTimes = CeilDivision(n, fractalShape[1] * fractalNum); loadDataParams.srcStride = 1; loadDataParams.dstGap = 0; loadDataParams.dstFracGap = CeilDivision(n, fractalShape[0]) - 1; for (int i = 0; i < CeilDivision(k, fractalShape[0]); ++i) { AscendC::LoadDataWithTranspose(b2Local[i * dstOffset], b1Local[i * srcOffset], loadDataParams); }示 例4:该 示 例 使 用 了LoadData2dTransposeParamsV2结 构 体 作 为 参 数,输 入a矩 阵 为int8_t类 型,shape为[128,128],输 入 数 据 格 式 为NZ,输 入b矩 阵 为int8_t类 型,shape为[128,256],输 入 数 据 格 式 为NZ,输 出c的 类 型 为float。a矩 阵 从A1->A2不 转 置,b矩 阵 从B1->B2转 置,示 例 仅 展 示 接 口 调 用 过 程,其 余 计 算 和 搬 运 不 作 参 考。
Textuint32 m = 256; uint32 n = 256; uint32 k = 128; pipe = tpipe; TQue<TPosition::B1, 1> qidB1_; TQue<TPosition::B2, 1> qidB2_; uint32 m = 128; pipe->InitBuffer(qidB1_, 1, n * k * sizeof(int8_t)); pipe->InitBuffer(qidB2_, 1, n * k * sizeof(int8_t)); auto rightMatrix = qidB1_.template DeQue<int8_t>(); LocalTensor<int8_t> b2 = qidB2_.AllocTensor<int8_t>(); uint16_t fracNum = 2; uint16_t kStep = CeilDiv(kLength, 16); uint16_t nStep = CeilDiv(nLength, 32); for (uint16_t i = 0; i < nStep; i ++) { LoadData2dTransposeParamsV2 loadDataParams; loadDataParams.startIndex = i * kStep; loadDataParams.repeatTimes = kStep / 2; loadDataParams.srcStride = 2; loadDataParams.dstGap = nStep*2 - 1; LoadDataWithTranspose(b2[1024*i], rightMatrix, loadDataParams); } qidB2_.EnQue(b2); qidB1_.FreeTensor(rightMatrix);