Skip to content
版 本

asc_transto5hd

产 品 支 持 情 况

产 品是 否 支 持
Atlas A3 训 练 系 列 产 品/Atlas A3 推 理 系 列 产 品
Atlas A2 训 练 系 列 产 品/Atlas A2 推 理 系 列 产 品
Ascend 950PR/Ascend 950DT

功 能 说 明

数 据 格 式 转 换,一 般 用 于 将NCHW格 式 转 换 成NC1HWC0格 式。特 别 的,也 可 以 用 于 二 维 矩 阵 数 据 块 的 转 置。本 接 口 单 次Repeat内 可 处 理512Byte的 数 据(16个DataBlock),根 据 数 据 类 型 不 同,支 持 不 同shape的 矩 阵 转 置(比 如 数 据 类 型 为half时,单 次Repeat可 完 成16*16大 小 的 矩 阵 转 置),同 时 还 可 以 支 持 多 次Repeat操 作。

单 次repeat内 转 换 规 则 如 下:

  • 当 输 入 数 据 类 型 位 宽 为16位 时,每 个DataBlock中 包 含16个 数,指 令 内 部 会 循 环16次,每 次 循 环 都 会 分 别 从 指 定 的16个DataBlock中 的 对 应 位 置 取 值,组 成 一 个 新 的DataBlock单 元 放 入 目 的 地 址 中。如 下 图 所 示,图 中 的srcList[0]-srcList[15]代 表 源 操 作 数 的16个DataBlock。

  • 当 数 据 类 型 位 宽 为32位 时,每 个DataBlock包 含8个 数,指 令 内 部 会 循 环8次,每 次 循 环 都 会 分 别 从 指 定 的16个DataBlock中 的 对 应 位 置 取 值,组 成2个 新 的DataBlock放 入 目 的 地 址 中。如 下 图 所 示:

  • 当 数 据 类 型 位 宽 为8位 时,每 个DataBlock包 含32个 数,指 令 内 部 会 循 环16次,每 次 循 环 都 会 分 别 从 指 定 的16个DataBlock中 的 对 应 位 置 取 值,组 成 半 个DataBlock放 入 目 的 地 址 中,读 取 和 存 放 是 在DataBlock的 高 半 部 还 是 低 半 部 由 参 数srcHighHalf和dstHighHalf决 定。如 下 图 所 示:

基 于 以 上 的 转 换 规 则,使 用 该 接 口 进 行NC1HWC0格 式 转 换 或 者 矩 阵 转 置。NC1HWC0格 式 转 换 相 对 复 杂,这 里 给 出 其 具 体 的 转 换 方 法:

NCHW格 式 转 换 成NC1HWC0格 式 时,如 果 是 数 据 类 型 的 位 宽 为32位 或 者16位,则C0=16;如 果 数 据 类 型 的 位 宽 为8位,则C0=32。下 图 以C0=16为 例 进 行 介 绍:

函 数 原 型

  • 常 规 计 算
C++
__aicore__ inline void asc_transto5hd_b32(ub_addr8_t dst, ub_addr8_t src, uint8_t repeat,
    uint16_t dst_stride, uint16_t src_stride)
__aicore__ inline void asc_transto5hd_b16(ub_addr8_t dst, ub_addr8_t src, uint8_t repeat,
    uint16_t dst_stride, uint16_t src_stride)
__aicore__ inline void asc_transto5hd_b8(ub_addr8_t dst, ub_addr8_t src, uint8_t repeat,
    uint16_t dst_stride, uint16_t src_stride, bool dst_high_half, bool src_high_half)
  • 同 步 计 算
C++
__aicore__ inline void asc_transto5hd_b32_sync(ub_addr8_t dst, ub_addr8_t src, uint8_t repeat,
    uint16_t dst_stride, uint16_t src_stride)
__aicore__ inline void asc_transto5hd_b16_sync(ub_addr8_t dst, ub_addr8_t src, uint8_t repeat,
    uint16_t dst_stride, uint16_t src_stride)
__aicore__ inline void asc_transto5hd_b8_sync(ub_addr8_t dst, ub_addr8_t src, uint8_t repeat,
    uint16_t dst_stride, uint16_t src_stride, bool dst_high_half, bool src_high_half)

参 数 说 明

参 数 名输 入/输 出描 述
dst输 出目 的 地 址 寄 存 器。
src输 入源 地 址 寄 存 器。
repeat输 入重 复 迭 代 次 数, repeat∈[0,255]。
注 意 事 项:
• 当repeat为1时,目 的 操 作 数/源 操 作 数 的 有 效 起 始 位 置 为dst/src序 列 输 入 的 起 始 位 置 加 上dst_stride/src_stride。如 果 要 让 目 的 操 作 数/源 操 作 数 的 有 效 起 始 位 置 为dst/src序 列 输 入 的 起 始 位 置,需 要 将dst_stride/src_stride置 为0。
•当repeat大 于1时,第 一 次repeat中 目 的 操 作 数/源 操 作 数 的 有 效 起 始 位 置 为dst/src序 列 输 入 的 起 始 位 置,第 二 次 会 加 上dst_stride/src_stride。以 此 类 推。
dst_stride输 入相 邻 迭 代 间,目 的 操 作 数 相 同DataBlock地 址Stride,单 位:DataBlock。
相 邻 迭 代 间 相 同DataBlock的 地 址 步 长 参 数 的 详 细 说 明 请 参 考repeatStride
src_stride输 入相 邻 迭 代 间,源 操 作 数 相 同DataBlock地 址Stride,单 位:DataBlock。
相 邻 迭 代 间 相 同DataBlock的 地 址 步 长 参 数 的 详 细 说 明 请 参 考repeatStride
dst_high_half输 入指 定 每 个dst地 址 中 的 数 据 存 储 到DataBlock的 高 半 部 还 是 低 半 部,该 配 置 只 配 置int8_t/uint8_t的 数 据 类 型。
支 持 的 数 据 类 型 为bool,有 以 下 两 种 取 值:
• true:表 示 存 储 于DataBlock的 高 半 部。
• false:表 示 存 储 于DataBlock的 低 半 部。
src_high_half输 入指 定 每 个src地 址 中 的 数 据 存 储 到DataBlock的 高 半 部 还 是 低 半 部,该 配 置 只 配 置int8_t/uint8_t的 数 据 类 型。
支 持 的 数 据 类 型 为bool,有 以 下 两 种 取 值:
• true:表 示 存 储 于DataBlock的 高 半 部。
•false:表 示 存 储 于DataBlock的 低 半 部。

返 回 值 说 明

流 水 类 型

PIPE_V

约 束 说 明

  • 操 作 数 地 址 对 齐 约 束 请 参 考通 用 地 址 对 齐 约 束
  • 操 作 数 地 址 重 叠 约 束 请 参 考通 用 地 址 重 叠 约 束
  • 进 行NCHW格 式 到NC1HWC0格 式 的 转 换 时,一 般 用 法 是 将src/dst中 的 每 个 元 素 配 置 为 每 个HW平 面 的 起 点。
  • 为 了 性 能 更 优,数 据 类 型 位 宽 为8位 时 建 议 先 固 定dst_high_half/src_high_half,再HW方 向Repeat后,再 改 变dst_high_half/src_high_half。

调 用 示 例

C++
// 示 例 一:
constexpr uint64_t total_length = 256;    // total_length指 参 与 计 算 的 数 据 长 度
__ubuf__ half src[total_length];
__ubuf__ half dst[total_length];
const uint32_t STEP = 16;
// src_list和dst_list是16个DataBlock地 址 的 数 组
__ubuf__ half* src_list[16] = {
    (__ubuf__ half*)(src + 0 * STEP),
    (__ubuf__ half*)(src + 1 * STEP),
    (__ubuf__ half*)(src + 2 * STEP),
    (__ubuf__ half*)(src + 3 * STEP),
    (__ubuf__ half*)(src + 4 * STEP),
    (__ubuf__ half*)(src + 5 * STEP),
    (__ubuf__ half*)(src + 6 * STEP),
    (__ubuf__ half*)(src + 7 * STEP),
    (__ubuf__ half*)(src + 8 * STEP),
    (__ubuf__ half*)(src + 9 * STEP),
    (__ubuf__ half*)(src + 10 * STEP),
    (__ubuf__ half*)(src + 11 * STEP),
    (__ubuf__ half*)(src + 12 * STEP),
    (__ubuf__ half*)(src + 13 * STEP),
    (__ubuf__ half*)(src + 14 * STEP),
    (__ubuf__ half*)(src + 15 * STEP)
};
__ubuf__ half* dst_list[16] = {
    (__ubuf__ half*)(dst + 0 * STEP),
    (__ubuf__ half*)(dst + 1 * STEP),
    (__ubuf__ half*)(dst + 2 * STEP),
    (__ubuf__ half*)(dst + 3 * STEP),
    (__ubuf__ half*)(dst + 4 * STEP),
    (__ubuf__ half*)(dst + 5 * STEP),
    (__ubuf__ half*)(dst + 6 * STEP),
    (__ubuf__ half*)(dst + 7 * STEP),
    (__ubuf__ half*)(dst + 8 * STEP),
    (__ubuf__ half*)(dst + 9 * STEP),
    (__ubuf__ half*)(dst + 10 * STEP),
    (__ubuf__ half*)(dst + 11 * STEP),
    (__ubuf__ half*)(dst + 12 * STEP),
    (__ubuf__ half*)(dst + 13 * STEP),
    (__ubuf__ half*)(dst + 14 * STEP),
    (__ubuf__ half*)(dst + 15 * STEP)
};
const int32_t VA_REG_ARRAY_LEN = 8;
uint8_t repeat = 1;
uint16_t dst_stride = 0;
uint16_t src_stride = 0;

// asc_set_va_reg接 口 要 求 前8个 和 后8个 地 址 序 列 与 地 址 寄 存 器 分 别 关 联
asc_set_va_reg(VA0, dst_list);
asc_set_va_reg(VA1, dst_list + VA_REG_ARRAY_LEN);
asc_set_va_reg(VA2, src_list);
asc_set_va_reg(VA3, src_list + VA_REG_ARRAY_LEN);

asc_transto5hd_b16(VA0, VA2, repeat, dst_stride, src_stride);

// 示 例 二:
constexpr uint64_t total_length = 2 * 32 * 16 * 16;    // total_length指 参 与 计 算 的 数 据 长 度
__ubuf__ half src[total_length];
__ubuf__ half dst[total_length];
const uint32_t DST_STEP = 16;
const uint32_t SRC_STEP = 16 * 16;
const uint32_t OFFSET = 16 * 16 * 16;
const int32_t VA_REG_ARRAY_LEN = 8;
uint8_t repeat = 16;
uint16_t dst_stride = 16;
uint16_t src_stride = 1;

// src_list和dst_list定 义 在 循 环 外 部
__ubuf__ half* src_list[16];
__ubuf__ half* dst_list[16];

for (int j = 0; j < 4; ++j) {
    // 在 循 环 内 更 新 地 址 列 表
    for (int i = 0; i < 16; ++i) {
        src_list[i] = (__ubuf__ half*)(src + OFFSET * j + i * SRC_STEP);
        dst_list[i] = (__ubuf__ half*)(dst + OFFSET * j + i * DST_STEP);
    }
    
    // 每 次 循 环 都 要 设 置 寄 存 器 并 执 行 转 换
    asc_set_va_reg(VA0, dst_list);
    asc_set_va_reg(VA1, dst_list + VA_REG_ARRAY_LEN);
    asc_set_va_reg(VA2, src_list);
    asc_set_va_reg(VA3, src_list + VA_REG_ARRAY_LEN);
    
    asc_transto5hd_b16(VA0, VA2, repeat, dst_stride, src_stride);
}

免 责 声 明:本 站 内 容 由 asc-devkit 仓 master 分 支 自 动 编 译 生 成,属 于 持 续 开 发 版 本,可 能 存 在 缺 陷,仅 供 预 览 与 参 考。如 需 稳 定 及 商 用 资 料,请 查 阅 官 方 昇 腾 社 区