---
title: TIK数据定义
description: "- 指用于数据定义和运算的每一个数的数值类型，包括：int8, uint8, int16, uint16, int32, uint32, float16, float32，uint1（bool）等。"
url: https://www.hiascend.com/document/detail/zh/canncommercial/latest/others/tbeaicpudevg/atlasopdev_10_0050.html
sourcePath: /source/zh/canncommercial/900/others/tbeaicpudevg/atlasopdev_10_0050.html
indexId: e401607456c1e05291ac982e6ef612d45cdbf1ca4c33427ee5135a3f02be218673
---
# TIK数据定义

#### 基本数据类型

- 指用于数据定义和运算的每一个数的数值类型，包括：int8, uint8, int16, uint16, int32, uint32, float16, float32，uint1（bool）等。
- 不同的TIK API支持不同的数据类型。
- TIK为强类型语言，即不同的数据类型之间无法进行计算。


#### TIK对象的标准数据类型

TIK对象的标准数据类型，指在内存中的对象的数据类型，表示用户能以什么格式创建和读写数据，包括两种：Scalar标量数据、Tensor张量数据。


#### 定义一个Scalar标量数据

TIK提供了Scalar接口用于定义Scalar数据，接口原型为：

```
# 接口原型（其中，name和init_value参数可以省略）
Scalar(dtype="int64", name="reg_buf", init_value=None)
```


**表1 参数说明**

| 参数名称 | 输入/输出 | 含义 |
| --- | --- | --- |
| dtype | 输入 | 指定Scalar对象的数据类型，取值： int8,uint8,int16, uint16,float16,int32,uint32，float32, int64, uint64 默认值：int64 |
| name | 输入 | Scalar名字，支持string类型。名字支持数字0\-9,A\-Z,a\-z及下划线组成的字符串，不允许以数字开头 默认值：reg\_buf$(COUNT)， COUNT从零开始计数。 |
| init\_value | 输入 | 初始化值: 可以是立即数（支持int, float类型）、 Scalar变量（支持int, float类型）、 Tensor的某个值、 Expr：包括Scalar变量、立即数组成的Expr。 须知： 如果是Expr，立即数不能是float。 |


```
# 示例1：使用全部3个参数
# 定义一个初值为10.2的立即数（float32）的Scalar数据 data_A
# 结果：data_A ： 10.2
data_A = tik_instance.Scalar(dtype = "float32", name = "data_A", init_value = 10.2)
# 示例2：省略name参数
# 定义一个初值为4的立即数（int16）的Scalar数据 data_B
# 结果：data_B ： 4
data_B = tik_instance.Scalar(dtype = "int16", init_value = 4)
# 示例3：省略name和init_value参数
# 定义一个不设置初始值的int32的Scalar数据 data_C
# 结果：相当于声明了一个类型为int32的data_C
data_C = tik_instance.Scalar(dtype = "int32")
```

```
# 注意：如果init_value是Expr，Expr中的立即数不能是float，只能是int。
# 正确初始化：Expr（data_a + 1）由Scalar和int组成：
data_a = tik_instance.Scalar(dtype = "int16", init_value = 1)
data_b = tik_instance.Scalar(dtype = "int16", init_value = data_a + 1)
# 错误初始化：Expr（data_a + 1.2）由Scalar和float组成：
data_a = tik_instance.Scalar(dtype = "int16", init_value = 1)
data_b = tik_instance.Scalar(dtype = "int16", init_value = data_a + 1.2)
```


#### 定义一个Tensor张量数据

Tensor数据对应于存储Buffer中的数据，TIK提供了Tensor接口用于定义Tensor数据，用户一般只需关注张量定义的数据类型（dtype）、形状（shape）与数据存储空间（scope）即可，函数原型为：

```
# 接口原型1（仅使用基本参数）
data = tik_instance.Tensor(dtype, shape, name = "", scope = tik.xxx)
# 接口原型2（使用拓展参数）
Tensor(dtype, shape, scope, name, enable_buffer_reuse=False, is_workspace=False, is_atomic_add=False, max_mem_size=None, init_value=None)
```


**表2 参数说明**

| 参数名称 | 输入/输出 | 含义 |
| --- | --- | --- |
| dtype | 输入 | 指定Tensor对象的数据类型，取值： uint8、int8、uint16、int16、float16、uint32、int32、float32、uint64、int64 |
| shape | 输入 | 指定Tensor对象的形状，支持List、Tuple类型，List、Tuple中的元素可以为立即数（int、float）、Scalar（int、uint）或Expr（int、uint）。不建议使用float类型的立即数。 shape的大小需要注意以下约束： shape的大小不能超过8维。 shape大小请根据实际需要设置，但不能超过scope指定的存储单元的大小，存储单元的大小可通过get\_soc\_spec查询。 |
| scope | 输入 | Tensor 内存类型范围，指定Tensor对象的所在buffer空间，取值： scope\_cbuf：L1 Buffer scope\_cbuf\_out：L1OUT Buffer scope\_ubuf ： Unified Buffer scope\_gm： Global Memory 其中scope\_gm代表外部存储，其他为内部存储，只有将外部存储中的数据搬运到内部存储中，才能完成相应的计算；当scope为gm时，不能在for\_range内部定义Tensor。 |
| name | 输入 | Tensor名字，string类型。名字支持数字0\-9,A\-Z,a\-z及下划线组成的字符串，不支持以数字开头。 tensor 的名字需要保持唯一。 说明： scope为scope\_gm时，不支持为"\_\_fake\_tensor"。 |
| enable\_buffer\_reuse | 输入 | 保留参数，不建议使用。 |
| is\_workspace | 输入 | bool值，默认值为False。 当该值为True时，代表当前Tensor是用于中间存储数据，而不用于输入输出。当取值为True时，需要保证scope为scope\_gm，同时，不包含在输入输出中，即输入输出的Tensor的name中不含workspace中的Tensor。 |
| is\_atomic\_add | 输入 | 是否进行初始化GM空间，默认值为False。 当设置为True时，默认将GM空间初始化为0。 当设置为False时，GM空间不进行初始化。 当该值为True时，需要保证scope为scope\_gm。 说明： 仅算子在网络中执行的场景下，此参数才生效。网络执行时，Graph Engine会根据此参数判断是否进行GM的空间初始化。 |
| max\_mem\_size | 输入 | Tensor所占据的空间大小。 当shape中不含变量时，用户可以不指定该值，或者指定max\_mem\_size为shape中各元素乘积再乘上dtype\_size。 当shape中包含变量时，用户既可以指定一个常数max\_mem\_size，且max\_mem\_size必须大于等于shape中各元素乘积再乘上dtype\_size，并且为dtype\_size的整数倍数；也可以不指定max\_mem\_size，程序运行时拿到shape的具体数值再分配内存（动态shape Tensor）。但当tensor的is\_workspace字段为True时，必须指定max\_mem\_size。 |
| init\_value | 输入 | Tensor的初始值，为单个元素或list/tuple类型的值。 注意：该参数为预留参数，当前版本暂不支持。 |


```
# 定义一个数值类型为float16，存储空间在global_memory，size为128的Tensor data_B
data_B = tik_instance.Tensor("float16", (128,), name="data_B", scope=tik.scope_gm)
```

TIK会自动为每个申请的Tensor对象分配空间，并且避免各个数据块之间的地址冲突。且TIK会自动检查数据之间的数据依赖性，实现数据的同步。

注意：

用户定义的Tensor在内存分配时会对起始地址进行对齐，不同scope的对齐要求请参见通用约束。用户需特别注意因地址对齐导致的超出对应内存类型的总容量时，会引起编译报错。


#### Scalar数据赋值及修改值（set_as）

TIK提供了set_as接口，用于设置或改变Scalar的值。

```
from tbe import tik
tik_instance = tik.Tik()
# 示例1：将Scalar的值设置为一个立即数（整数）
s1 = tik_instance.Scalar(dtype = "int32")      # 声明一个int32类型的scalar变量 s1
s1.set_as(10)                                  # 将s1的值设为10
# 示例2：将Scalar的值设置为一个立即数（float）
s2 = tik_instance.Scalar(dtype = "float16")    # 声明一个float16类型的scalar变量 s2
s2.set_as(10.2)                                # 将s2的值设为10.2
# 示例3：将Scalar的值设置为另一个Scalar变量的值
s3 = tik_instance.Scalar(dtype = "float16", init_value = 2.4)  # 定义一个初值为2.4的标量s3
s4 = tik_instance.Scalar(dtype = "float16")    # 声明一个float16类型的scalar变量 s4
s4.set_as(s3)                                  # 将s3的值赋给s4
# 示例4：将Scalar的值设置为由Scalar和立即数组成的Expr的值
s5 = tik_instance.Scalar(dtype = "int32", init_value = 1)     # 定义一个初值为1的标量s5
s6 = tik_instance.Scalar(dtype = "int32")     # 声明一个int32类型的scalar变量 s6
s6.set_as(s5+20)                              # 将Expr(s5+20)的值赋给s6，结果：s6 = 21
# 示例5：将Scalar的值设置为Tensor的某个值
s7 = tik_instance.Scalar(dtype = "int16")
tensor_a = tik_instance.Tensor("int16", (4,), name="tensor_a", scope=tik.scope_ubuf)
s7.set_as(tensor_a[0])
'''
例如：
tensor_a = [1,2,3,4]
则经过赋值后：
s7 = 1
'''
```


#### 为Tensor赋值

TIK提供了两种方式为Tensor赋值，设置或修改Tensor的内容。

1. 方法一：通过  set_as
设置或改变Tensor的值。

```
# 示例：
from tbe import tik
tik_instance = tik.Tik()
data_A = tik_instance.Tensor("int16", (4,), name="data_A", scope=tik.scope_ubuf)
data_B = tik_instance.Tensor("int16", (4,), name="data_B", scope=tik.scope_ubuf)
data_B[1].set_as(4)             # 将data_B的第二个元素的值设为4                   （1）
data_A[0].set_as(data_B[1])     # 将data_B的第二个元素的值赋给data_A的第一个元素   （2）
'''
例如：
data_A = [1, 1, 1, 1]
data_B = [0, 0, 0, 0]
经过赋值语句（1）后：
data_B = [0, 4, 0, 0]
经过赋值语句（2）后：
data_A = [4, 1, 1, 1]
'''
```


2. 方法二：通过Tensor数组下标，改变Tensor内容，相关接口：  改变Tensor内容
。

```
# 示例：
'''
data_A初始值为：[1.2, 2.4, 3.6, 4.8]
'''
from tbe import tik
tik_instance = tik.Tik()
data_A = tik_instance.Tensor("float16", (4,), name="data_A", scope=tik.scope_ubuf)
scalar_B = tik_instance.Scalar(dtype="float16", name="scalar_B", init_value=2.0)
scalar_idx = tik_instance.Scalar(dtype="int16", name="scalar_idx", init_value=1)
# index为0, value为1.0, 下面这条语句将一个立即数赋给data_A的第一个元素
data_A[0] = 1.0
'''
经过下标修改值后：
data_A = [1.0, 2.4, 3.6, 4.8]
'''
# index为scalar_idx, value为scalar_B, 下面这条语句将一个scalar赋给data_A的第二个元素
data_A[scalar_idx] = scalar_B
'''
经过下标修改值后：
data_A = [1.0, 2.0, 3.6, 4.8]
'''
# index为由scalar(int16)和立即数int组成的Expr, value为由scalar(float16)和立即数float组成的Expr, 下面这条语句将一个Expr赋给data_A的第三个元素
data_A[scalar_idx+1] = scalar_B + 2.2
'''
经过下标修改值后：
data_A = [1.0, 2.0, 4.2, 4.8]
'''
```


除了以上两种修改Tensor值的方法，还有其余所有的Tensor运算API都可以对Tensor的值进行修改，例如：使用vec_add接口可以进行加法运算，将相加的结果赋给目的Tensor。


#### 获取Tensor形状

TIK提供了shape接口用于获取Tensor shape。

```
# 示例：
from tbe import tik
tik_instance = tik.Tik()
data_A = tik_instance.Tensor("float16", (128,), name="data_A", scope=tik.scope_ubuf)
data_A.shape   # 输出data_A的shape，为：[128]
```


#### 改变Tensor形状

TIK提供了reshape接口用于改变Tensor shape。

```
# 示例：
from tbe import tik
tik_instance = tik.Tik()
data_A = tik_instance.Tensor("int16", (4,), name="data_A", scope=tik.scope_gm)
# 将data_A的形状由原来的4*1改变为2*2
data_A.reshape((2,2))
'''
初始：data_A = [1, 2, 3, 4]
经过reshape后：
data_A = [[1, 2], [3, 4]]
'''
```


#### 通过下标切片获取Tensor部分数据

TIK提供了相关接口，可以通过Tensor数组下标，获得Tensor内部分数据，形成新的Tensor，相关接口：获取Tensor部分数据。

```
# 示例：
from tbe import tik
tik_instance = tik.Tik()
data_A = tik_instance.Tensor("int16", (8,), name="data_A", scope=tik.scope_gm)
data_B = tik_instance.Tensor("int16", (4,), name="data_B", scope=tik.scope_gm)
data_B = data_A[4:]   # 对data_A进行切片，data_B包含data_A第5个数及其之后的所有数据
'''
例如：
data_A = [1,2,3,4,5,6,7,8]
经过切片取值后：
data_B = [5,6,7,8]
'''
```


#### 以指定数据类型读取数据

TIK提供了reinterpret_cast_to接口，用于以用户指定的数据类型，读取相同内存数据，并对内存中的字节重新解释。

例如：128个float16，则可以使用reinterpret_cast_to指定以float32的方式读取该段数据，会获得64个float32，因此reinterpret_cast_to并非真正将每一个float16数据转化成对应float32数据，这一点与数据精度转换接口vec_conv不同。

```
# 示例：
from tbe import tik
tik_instance = tik.Tik()
data_A = tik_instance.Tensor("float16", (16,), name="data_A", scope=tik.scope_gm)
data_B = data_A.reinterpret_cast_to("uint32")
data_C = data_B.reinterpret_cast_to("float16")
"""调用结果如下：
输入数据：       # data_A 原本是float16的数据
data_A:
[ 4.812e+00  1.870e-04 -5.692e-02  2.528e-02 -9.225e+02 -1.431e+02
-1.541e+01 -2.018e-03  1.653e-03 -4.090e+00  2.016e+01 -5.846e+04
-8.072e-03  2.627e+00 -3.174e-02 -3.088e-01]
输出数据：
data_B:         # data_B 是以uint32的形式读取的
[ 169952464  645507913 3631866677 2552417204 3289847493 4213394698
1094819874 3035736080]
data_C:         # data_C 是以float16的形式读取的
[ 4.812e+00  1.870e-04 -5.692e-02  2.528e-02 -9.225e+02 -1.431e+02
-1.541e+01 -2.018e-03  1.653e-03 -4.090e+00  2.016e+01 -5.846e+04
-8.072e-03  2.627e+00 -3.174e-02 -3.088e-01]
"""
```
