asc_transto5hd
产 品 支 持 情 况
| 产 品 | 是 否 支 持 |
|---|---|
| √ | |
| √ | |
| √ |
功 能 说 明
数 据 格 式 转 换,一 般 用 于 将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为 例 进 行 介 绍:
函 数 原 型
- 常 规 计 算
__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)
- 同 步 计 算
__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。
调 用 示 例
// 示 例 一:
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);
}