LocalTensor
功能说明
用于存放AI Core中Local Memory(内部存储)的数据,支持QuePosition为VECIN、VECOUT、VECCALC、A1、A2、B1、B2、CO1、CO2。
定义原型
template <typename T> class LocalTensor { __aicore__ inline T GetValue(const uint32_t offset) template <typename T1> void SetValue(const uint32_t offset, const T1 value); __aicore__ inline LocalTensor<T> operator[](const uint32_t offset) T& operator()(const uint32_t offset) __aicore__ inline uint64_t GetSize(); __aicore__ inline void SetUserTag(const TTagType tag); __aicore__ inline TTagType GetUserTag(); __aicore__ inline int32_t GetPosition(); template <typename CAST_T> __aicore__ inline LocalTensor<CAST_T> ReinterpretCast(); __aicore__ inline uint64_t GetPhyAddr(); __aicore__ inline void SetSize(const uint32_t size); __aicore__ inline uint32_t GetLength(); __aicore__ inline void SetShapeInfo(const ShapeInfo& shapeInfo); __aicore__ inline ShapeInfo GetShapeInfo(); __aicore__ inline void SetAddrWithOffset(LocalTensor<T1> &src, uint32_t offset); __aicore__ inline void SetBufferLen(uint32_t dataLen); __aicore__ inline void SetAddr(const uint64_t offset); // 以下函数仅支持CPU 调试 int32_t ToFile(const std::string &fileName); void Print(); }
函数说明
类型T支持所有数据类型,但需要遵循使用此LocalTensor的指令的数据类型支持情况。
函数名称 |
入参说明 |
含义 |
---|---|---|
GetValue |
offset:偏移量,单位为 element |
获取 LocalTensor 中的某个值,返回 T 类型的立即数。 该接口仅在LocalTensor的TPosition为VECIN/VECCALC/VECOUT时支持。 |
SetValue |
offset:偏移值,单位为 element value:设置值,单位为任意类型 |
设置 LocalTensor 中的某个值。 该接口仅在LocalTensor的TPosition为VECIN/VECCALC/VECOUT时支持。 |
operator[] |
offset:偏移量 |
获取距原LocalTensor起始地址偏移量为offset的新LocalTensor,注意offset不能超过原有LocalTensor的size大小。 |
operator() |
index: 下标索引 |
获取本LocalTensor的第index个变量的引用。用于左值,相当于SetValue接口,用于右值,相当于GetValue接口。 |
GetSize |
无 |
获取当前LocalTensor size大小。单位为元素。 |
SetSize |
size:元素个数, 单位为 element |
设置当前LocalTensor size大小。单位为元素。当用户重用local tensor变量且使用长度发生变化的时候,需要使用此接口重新设置Size。 |
SetUserTag |
tag:设置的Tag信息,类型TTagType对应为int32_t。 |
为Tensor添加用户自定义信息,用户可以根据需要设置对应的Tag。后续可通过GetUserTag获取指定Tensor的Tag信息,并根据Tag信息对Tensor进行相应操作。 |
GetUserTag |
- |
获取指定Tensor块的Tag信息,用户可以根据Tag信息对Tensor进行不同操作。 |
ReinterpretCast |
- |
将当前Tensor重解释为用户指定的新类型,转换后的Tensor与原Tensor地址及内容完全相同,Tensor的大小(字节数)保持不变。 |
GetPhyAddr |
- |
返回LocalTensor的地址 |
GetPosition |
- |
获取QuePosition抽象的逻辑位置,支持QuePosition为VECIN、VECOUT、VECCALC、A1、A2、B1、B2、CO1、CO2。 |
GetLength |
无 |
获取LocalTensor数据长度,单位为Byte。 |
SetShapeInfo |
shapeInfo:ShapeInfo结构体 |
设置LocalTensor的shapeInfo。 |
GetShapeInfo |
无 |
获取LocalTensor的shapeInfo。注意:Shape信息没有默认值,只有通过SetShapeInfo设置过Shape信息后,才可以调用该接口获取正确的ShapeInfo。 |
SetAddrWithOffset |
src:基础地址的Tensor,将该Tensor的地址作为基础地址,设置偏移后的Tensor地址。 offset:偏移的长度 |
设置带有偏移的Tensor地址。用于快速获取定义一个Tensor,同时指定新Tensor相对于旧Tensor首地址的偏移。偏移的长度为旧Tensor的元素个数。 |
SetAddr |
TBuffAddr address:tensor buffer地址 |
设置tensor地址。用于快速申请一个Tensor。 |
SetBufferLen |
dataLen:buffer长度 |
设置buffer长度。单位为字节。 |
ToFile |
fileName:文件名称 |
只限于CPU调试,将LocalTensor数据Dump到文件中,用于精度调试,文件保存在执行目录。 |
dataLen:打印元素个数 |
只限于CPU调试,在调试窗口中打印LocalTensor数据用于精度调试,每一行打印一个datablock(32Bytes)的数据。 |
注意事项
不要大量使用SetValue对LocalTensor进行赋值,会使性能下降。若需要大批量赋值,请根据实际场景选择数据填充基础API接口或数据填充高阶API接口,以及在需要生成递增数列的场景,选择ArithProgression。
调用示例
// srcLen = 256, num = 100, M=50 // 示例1 for (int32_t i = 0; i < srcLen; ++i) { input_local.SetValue(i, num); // 对input_local中第i个位置进行赋值为num } // 示例1结果如下: // 数据(input_local): [100 100 100 ... 100] // 示例2 for (int32_t i = 0; i < srcLen; ++i) { auto element = input_local.GetValue(i); // 获取input_local中第i个位置的数值 } // 示例2结果如下: // element 为100 // 示例3 for (int32_t i = 0; i < srcLen; ++i) { input_local(i) = num; // 对input_local中第i个位置进行赋值为num } // 示例3结果如下: // 数据(input_local): [100 100 100 ... 100] // 示例4 for (int32_t i = 0; i < srcLen; ++i) { auto element = input_local(i); // 获取input_local中第i个位置的数值 } // 示例4结果如下: // element 为100 // 示例5 auto size = input_local.GetSize(); // 获取input_local的长度,size大小为input_local有多少个element // 示例5结果如下: // size大小为srcLen,256。 // 示例6 Add(output_local[16], input_local[16], input_local2[16], M); // operator[]使用方法,input_local[16]为从起始地址开始偏移量为16的新tensor // 示例6结果如下: // 输入数据(input_local): [100 100 100 ... 100] // 输入数据(input_local2): [1 2 3 ... 66] // 输出数据(output_local): [... 117 118 119 ... 166] // 示例7 TTagType tag = 10; input_local.SetUserTag(tag); // 对LocalTensor设置tag信息。 // 示例8 LocalTensor<half> tensor1 = que1.DeQue<half>(); TTagType tag1 = tensor1.GetUserTag(); LocalTensor<half> tensor2 = que2.DeQue<half>(); TTagType tag2 = tensor2.GetUserTag(); LocalTensor<half> tensor3 = que3.AllocTensor<half>(); /* 使用Tag控制条件语句执行*/ if((tag1 <= 10) && (tag2 >=9)) { Add(tensor3, tensor1, tensor2, TILE_LENGTH); // 当tag1小于等于10,tag2大于等于9的时候,才能进行相加操作。 } // 示例9 // input_local为int32_t 类型,包含16个元素(64字节) for (int32_t i = 0; i < 16; ++i) { input_local.SetValue(i, i); // 对input_local中第i个位置进行赋值为i } // 调用ReinterpretCast将input_local重解释为int16_t类型 LocalTensor<int16_t> interpre_tensor = input_local.ReinterpretCast<int16_t>(); // 示例9结果如下,二者数据完全一致,在物理内存上也是同一地址,仅根据不同类型进行了重解释 // input_local:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // interpre_tensor:0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0 10 0 11 0 12 0 13 0 14 0 15 0 // 示例10 //调用GetPhyAddr()返回LocalTensor地址 CastImpl((__ubuf__ T1*)dstLocal.GetPhyAddr(), (__ubuf__ T2*)srcLocal.GetPhyAddr(), round_mode, calCount); // 示例11 const Hardware srcHWPos = GetPhyType((QuePosition)srcLocal.GetPosition()); if constexpr (srcHWPos == Hardware::UB) { // 处理逻辑1 } else { // 处理逻辑2 } // 示例12 // 获取localTensor的长度(单位为Byte),数据类型为int32_t,所以是16*sizeof(int32_t) uint32_t len = input_local.GetLength(); // input_local:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // len: 64 // 示例13 设置Tensor的ShapeInfo信息 LocalTensor<T> maxUb = softmaxMaxBuf.template Get<T>(); maxUb.SetShapeInfo(ShapeInfo(2, maxSumShape, DataFormat::ND)); // 示例14 获取Tensor的ShapeInfo信息 ShapeInfo dstShapeInfo = dstGlobal.GetShapeInfo(); tiling.dstShapeB = dstShapeInfo.originalShape[0]; tiling.dstShapeN = dstShapeInfo.originalShape[1]; tiling.dstShapeS = dstShapeInfo.originalShape[2]; tiling.dstShapeHN = dstShapeInfo.originalShape[3]; tiling.dstShapeH = dstShapeInfo.shape[2]; // 示例15 SetAddrWithOffset,用于快速获取定义一个Tensor,同时指定新Tensor相对于旧Tensor首地址的偏移 // 需要注意,偏移的长度为旧Tensor的元素个数 LocalTensor<float> tmpBuffer = tempBmm2Queue.template AllocTensor<float>(); LocalTensor<half> tmpHalfBuffer; tmpHalfBuffer.SetAddrWithOffset(tmpBuffer, calcSize * 2); // 示例16 SetAddr用于快速申请一个Tensor,如下示例申请的Tensor地址为32,长度为1024字节,位于VECCALC LocalTensor<T> stackBuffer; TBuffAddr buffAddr; buffAddr.dataLen = 1024; buffAddr.bufferAddr = 32; buffAddr.logicPos = (uint8_t)QuePosition::VECCALC; stackBuffer.SetAddr(buffAddr); // 示例17 SetBufferLen 如下示例将申请的Tensor长度修改为1024(单位为字节) LocalTensor<float> tmpBuffer = tempBmm2Queue.template AllocTensor<float>(); tmpBuffer.SetBufferLen(1024); // 示例18 SetSize 如下示例将申请的Tensor长度修改为256(单位为元素) LocalTensor<float> tmpBuffer = tempBmm2Queue.template AllocTensor<float>(); tmpBuffer.SetSize(256); // 示例19 只限于CPU调试,将LocalTensor数据Dump到文件中,用于精度调试,文件保存在执行目录 LocalTensor<T> tmpTensor = softmaxMaxBuf.template Get<T>(); tmpTensor.ToFile("tmpTensor.bin"); // 示例20 只限于CPU调试,在调试窗口中打印LocalTensor数据用于精度调试,每一行打印一个datablock(32Bytes)的数据 LocalTensor<int32_t> input_local= softmaxMaxBuf.template Get<int32_t>(); for (int32_t i = 0; i < 16; ++i) { input_local.SetValue(i, i); // 对input_local中第i个位置进行赋值为i } input_local.Print(); // 0000: 0 1 2 3 4 5 6 7 8 // 0008: 9 10 11 12 13 14 15