AllocTensor
产 品 支 持 情 况
- Ascend 950PR/Ascend 950DT:支 持
- Atlas A3 训 练 系 列 产 品/Atlas A3 推 理 系 列 产 品:支 持
- Atlas A2 训 练 系 列 产 品/Atlas A2 推 理 系 列 产 品:支 持
- Atlas 200I/500 A2 推 理 产 品:支 持
- Atlas 推 理 系 列 产 品AI Core:支 持
- Atlas 推 理 系 列 产 品Vector Core:不 支 持
- Atlas 训 练 系 列 产 品:支 持
- Kirin X90:支 持
- Kirin 9030:支 持
功 能 说 明
头 文 件 路 径 为:"basic_api/kernel_tpipe.h"。
从Que中 分 配Tensor,Tensor所 占 大 小 为InitBuffer时 设 置 的 每 块 内 存 长 度。
函 数 原 型
non-inplace接 口:构 造 新 的Tensor作 为 内 存 管 理 的 对 象
C++template <typename T> __aicore__ inline LocalTensor<T> AllocTensor()inplace接 口:直 接 使 用 传 入 的Tensor作 为 内 存 管 理 的 对 象,可 以 减 少Tensor反 复 创 建 的 开 销,具 体 使 用 指 导 可 参 考Tensor原 地 操 作。
C++template <typename T> __aicore__ inline void AllocTensor(LocalTensor<T>& tensor)
参 数 说 明
表1 模 板 参 数 说 明
参 数 名 | 说 明 |
|---|---|
T | Tensor的 数 据 类 型,支 持 的 类 型 请 见LocalTensor相 关 描 述。 |
表2 参 数 说 明
参 数 名 称 | 输 入/输 出 | 含 义 |
|---|---|---|
tensor | 输 入 | inplace接 口 需 要 传 入LocalTensor作 为 内 存 管 理 的 对 象。 |
约 束 说 明
- 同 一 个TPosition上 的 所 有Queue,连 续 调 用AllocTensor接 口 申 请 的Tensor数 量,根 据AI处 理 器 型 号 的 不 同,有 数 量 约 束。申 请Buffer时,需 要 满 足 该 约 束。
- Ascend 950PR/Ascend 950DT不 超 过8个。
- Atlas A3 训 练 系 列 产 品/Atlas A3 推 理 系 列 产 品 不 超 过8个。
- Atlas A2 训 练 系 列 产 品/Atlas A2 推 理 系 列 产 品 不 超 过8个。
- Atlas 200I/500 A2 推 理 产 品 不 超 过8个。
- Atlas 推 理 系 列 产 品AI Core不 超 过8个。
- Atlas 推 理 系 列 产 品Vector Core不 超 过8个。
- Atlas 训 练 系 列 产 品 不 超 过4个。
- Kirin X90不 超 过8个。
- Kirin 9030不 超 过8个。
- non-inplace接 口 分 配 的Tensor内 容 可 能 包 含 随 机 值。
- non-inplace接 口,需 要 将TQueBind的depth模 板 参 数 设 置 为 非 零 值;inplace接 口,需 要 将TQueBind的depth模 板 参 数 设 置 为0。
返 回 值 说 明
non-inplace接 口 返 回 值 为LocalTensor对 象,inplace接 口 没 有 返 回 值。
调 用 示 例
示 例 一
C++// 使用AllocTensor分配Tensor AscendC::TPipe pipe; AscendC::TQue<AscendC::TPosition::VECOUT, 2> que; int num = 2; int len = 1024; pipe.InitBuffer(que, num, len); // InitBuffer分配内存块数为2,每块大小为1024Bytes AscendC::LocalTensor<half> tensor1 = que.AllocTensor<half>(); // AllocTensor分配Tensor长度为1024Bytes示 例 二
C++// 连续使用AllocTensor的限制场景举例如下: AscendC::TQue<AscendC::TPosition::VECIN, 1> que0; AscendC::TQue<AscendC::TPosition::VECIN, 1> que1; AscendC::TQue<AscendC::TPosition::VECIN, 1> que2; AscendC::TQue<AscendC::TPosition::VECIN, 1> que3; AscendC::TQue<AscendC::TPosition::VECIN, 1> que4; AscendC::TQue<AscendC::TPosition::VECIN, 1> que5; // 不建议: // 比如,算子有6个输入,需要申请6块buffer // 通过6个队列为其申请内存,分别为que0~que5,每个que分配1块,申请VECIN TPosition上的buffer总数为6 // 假设,同一个TPosition上连续Alloc的Buffer数量限制为4,超出该限制后,使用AllocTensor/FreeTensor会出现分配资源失败 // 在NPU上可能体现为卡死等异常行为,在CPU Debug场景会出现报错提示 pipe.InitBuffer(que0, 1, len); pipe.InitBuffer(que1, 1, len); pipe.InitBuffer(que2, 1, len); pipe.InitBuffer(que3, 1, len); pipe.InitBuffer(que4, 1, len); pipe.InitBuffer(que5, 1, len); AscendC::LocalTensor<T> local1 = que0.AllocTensor<T>(); AscendC::LocalTensor<T> local2 = que1.AllocTensor<T>(); AscendC::LocalTensor<T> local3 = que2.AllocTensor<T>(); AscendC::LocalTensor<T> local4 = que3.AllocTensor<T>(); // 第5个AllocTensor会出现资源分配失败,同一个TPosition上同时Alloc出来的Tensor数量超出了4个的限制 AscendC::LocalTensor<T> local5 = que4.AllocTensor<T>(); // 此时建议通过以下方法解决: // 如果确实有多块buffer使用,可以将多个buffer合并到一块buffer,通过偏移使用 pipe.InitBuffer(que0, 1, len * 3); pipe.InitBuffer(que1, 1, len * 3); /* * 分配出3块内存大小的LocalTensor, local1的地址为que0中buffer的起始地址, * local2的地址为local1的地址偏移len后的地址,local3的地址为local1的地址偏移 * len * 2的地址 */ int32_t offset1 = len; int32_t offset2 = len * 2; AscendC::LocalTensor<T> local1 = que0.AllocTensor<T>(); AscendC::LocalTensor<T> local2 = local1[offset1]; AscendC::LocalTensor<T> local3 = local1[offset2];示 例 三:inplace接 口
C++AscendC::TPipe pipe; AscendC::TQue<AscendC::TPosition::VECIN, 0> que; int num = 2; int len = 1024; pipe.InitBuffer(que, num, len); // InitBuffer分配内存块数为2,每块大小为1024Bytes AscendC::LocalTensor<half> tensor1; que.AllocTensor<half>(tensor1); // AllocTensor分配Tensor长度为1024Bytes