---
title: TIK程序控制
description: "过程式编程的程序结构元素包括：顺序、分支、循环。TIK提供if_scope、elif_scope和else_scope接口在TIK DSL程序中定义分支结构；提供for_range接口在TIK DSL程序中定义循环结构；除此之外，其它的TIK DSL接口在当前的代码块中形成顺序结构。TIK借用Python的with语句特性，表达代码块语义。"
url: https://www.hiascend.com/document/detail/zh/canncommercial/latest/others/tbeaicpudevg/atlasopdev_10_0052.html
sourcePath: /source/zh/canncommercial/900/others/tbeaicpudevg/atlasopdev_10_0052.html
indexId: 9a4e0fa4e5308dcf3aaafcfb0ce02ef9f03cf896169312cea0e8281bf576942073
---
# TIK程序控制

过程式编程的程序结构元素包括：顺序、分支、循环。TIK提供if_scope、elif_scope和else_scope接口在TIK DSL程序中定义分支结构；提供for_range接口在TIK DSL程序中定义循环结构；除此之外，其它的TIK DSL接口在当前的代码块中形成顺序结构。TIK借用Python的with语句特性，表达代码块语义。

#### 分支

TIK提供if_scope、elif_scope和else_scope接口定义分支结构。if_scope( )、elif_scope( )和else_scope( )接口在python脚本中以with语句的形式出现，with语句的语句体定义了TIK的if/elif/else代码块，elif与else部分在语法上为可选部分。else_scope如果出现，则与脚本上文中位于相同缩进等级的if_scope形成逻辑互补关系。

```
# if_scope接口：当满足cond时，执行if代码块。返回值：TikWithScope
if_scope(cond)
# 当if_scope语句条件不满足时，且本语句cond2条件满足时，执行此elif_scope代码块
# 首个elif_scope必须在if_scope函数后
elif_scope(cond2)
# 当前面的if_scope以及elif_scope条件都不满足，则执行此else_scope代码块
# else_scope必须在if_scope/elif_scope函数后
else_scope()
```

示例如下：

```
scalar_a = 4
with self.tik_instance.if_scope(scalar_a == 4):  # 判断条件：scalar_a 为 4
scalar_a.set_as(1)    # if代码块，scalar_a 为 4时执行
with self.tik_instance.elif_scope(scalar_a == 5):
scalar_a.set_as(2)    # elif代码块，scalar_a 为 5时执行
with self.tik_instance.else_scope():
scalar_a.set_as(0)     # else代码块，scalar_a 不为4且不为5时执行
# 运行结果： scalar_a = 1
```


TIK分支语句：

```
a = tik_instance.Scalar("int32", init_value = 2)
with tik_instance.if_scope(a > 1):
a.set_as(0)        # if代码块：a > 1 时执行
with tik_instance.elif_scope(a == 1):
a.set_as(1)        # elif代码块：a == 1 时执行
with tik_instance.else_scope():
a.set_as(2)        # else代码块：a < 1 时执行
# 运行结果：a = 0
```

Python原生语句：

```
a = 2
if a > 1:
a = 0       # if代码块：a > 1 时执行
elif a < 1:
a = 1       # if代码块：a < 1 时执行
else:
a = 2       # else代码块：a == 1 时执行
```

TIK的分支语句和Python原生语句的主要区别在于：

- Python原生分支语句：要求a必须是立即数，是在编译时就可以确定的常量数据。编译时会根据判断条件，只编译其中一条指令。
- TIK分支语句：if_scope、elif_scope和else_scope是普通的python指令，几条指令在tik编译的时候都会被编译到，而在运行时，根据a的值，运行其中一条指令。

#### 循环

TIK提供for_range接口在TIK DSL程序中定义循环结构，定义方法为：

```
tik.Tik.for_range(begint, endt, name="i", thread_num = 1, block_num = 1)
```

- begint：循环变量起始值。
- endt：循环变量终止值。
- name：可选，TIK DSL中循环变量名，默认为“i”。
- thread_num：可选，循环中是否开启Double Buffer，用于控制指令并行度。
- block_num：可选循环中使用的核数，用于控制指令并行度。

for_range( )接口在python脚本中以with语句的形式出现，with语句的语句体定义了TIK for循环的循环体。TIK中for循环的循环体构成一个语句块。循环体中的TIK语句，将以尽可能并行的方式被执行。


TIK循环语句：

```
# 示例 1 ：TIK的Python语句
# 定义vec_a, vec_b, vec_c三个Tensor
vec_a = tik_instance.Tensor(...)
vec_b = tik_instance.Tensor(...)
vec_c = tik_instance.Tensor(...)
# TIK的for_range循环语句：
with tik_instance.for_range(0, 10) as i:   # 循环变量 i，循环次数 10
tik_instance.vec_add(..., vec_c, vec_a, vec_b, ...)  # 循环体语句：调用vec_add接口实现加加法运算
```

Python原生语句：

```
# 示例：Python原生语句
# 定义vec_a, vec_b, vec_c三个Tensor
Tensor vec_a(...)
Tensor vec_b(...)
Tensor vec_c(...)
# Python原生循环语句：
for i in range(0, 10):                  # 循环变量 i，循环次数 10
vec_add(vec_c, vec_a, vec_b, ...)   # 循环体语句
```

TIK的循环语句和Python原生语句的主要区别在于：

- Python原生语句：循环变量 i 是立即数，在编译时期会把循环展开如下：

```
c[0] = a[0] + b[0]
c[1] = a[1] + b[1]
c[2] = a[2] + b[2]
c[9] = a[9] + b[9]
```


- TIK循环语句：TIK的循环语句中，循环变量 i 是scalar类型，在编译时期不会将循环展开。运行时期TIK循环语句与Python原生循环语句类似。

#### 分支嵌套

TIK的if_scope/elif_scope/else_scope语句可以和另一个if_scope/elif_scope/else_scope、以及tik的for_range互相嵌套，但不能和python原生的for或if/elif/else语句互相嵌套。

```
# 示例 1 ： tik 的 if/else_scope可以和另一个if/else_scope嵌套，允许：
with self.tik_instance.if_scope(...):
do_something()
with self.tik_instance.if_scope(...):
do_something()
with self.tik_instance.else_scope():
do_something()
with self.tik_instance.else_scope():
do_something()
# 示例 2 ： tik 的 if/else_scope可以和tik的for嵌套，允许：
with self.tik_instance.if_scope(...):
with tik_instance.for_range(0, 10) as i:
do_something()
with self.tik_instance.else_scope():
do_something()
# 错误示例 1 ： tik 的 if/else_scope不可以和python原生if/else嵌套：
with self.tik_instance.if_scope(...):
do_something()
if x > 2:
do_something()
else:
do_something()
with self.tik_instance.else_scope():
do_something()
# 错误示例 2 ： tik 的 if/else_scope不可以和python原生for嵌套：
for i in range(0, 10) :
with self.tik_instance.if_scope(...):
do_something()
with self.tik_instance.else_scope():
do_something()
```


#### 循环嵌套

TIK的for_range语句可以和另一个tik 的for_range、tik的if_scope/elif_scope/else_scope、以及python原生的for互相嵌套，但不能和python原生的if/elif/else语句互相嵌套。

```
# 示例 1：tik的for和另一个tik的for嵌套，允许：
with tik_instance.for_range(0, 10) as i:
with tik_instance.for_range(0, 20) as j:
do_something()
# 示例 2：tik的for和另一个tik的if/else_scope嵌套，允许：
with tik_instance.for_range(0, 10) as i:
with self.tik_instance.if_scope(...):
do_something()
with self.tik_instance.else_scope():
do_something()
# 示例 3：tik的for和另一个python原生的for嵌套，允许：
with tik_instance.for_range(0, 10) as i:
for j in range(0, 20):
do_something()
# 错误示例：tik的for不可以和另一个python原生的if/else嵌套：
with tik_instance.for_range(0, 10) as i:
if i == 0:
do_something()
else:
do_something()
```
