---
title: DSL功能调试
description: "若算子运行出错，开发者可参见本章节描述的方法在CPU中进行DSL算子的功能调试，验证算子的算法逻辑是否正确。"
url: https://www.hiascend.com/document/detail/zh/canncommercial/latest/others/tbeaicpudevg/atlasopdev_10_0040.html
sourcePath: /source/zh/canncommercial/900/others/tbeaicpudevg/atlasopdev_10_0040.html
indexId: 753e06858d808148022646a4bf9bb0aa0bcb9cdc0233470308e68a76e75d2ae273
---
# DSL功能调试

#### 功能介绍

若算子运行出错，开发者可参见本章节描述的方法在CPU中进行DSL算子的功能调试，验证算子的算法逻辑是否正确。

使用DSL方式开发TBE算子的用户只需要关注算法逻辑，直接调用TBE DSL提供的auto_schedule接口即可完成算子的自动调度。因此，确认算法描述逻辑正确的情况下，如果算子运行依然出错，则可把错误归结为TBE内部错误，您可在LINK(https://gitee.com/ascend/modelzoo)中通过issue进行问题反馈。


#### 使用方法

TBE DSL提供了在CPU上验证算子功能正确性的调试框架，方便开发者快速验证算子功能的正确性，具体流程如下：

图1 DSL功能调试流程

1. 进入调试模式并获取算子运行的上下文。

  a. 调用    tbe.common.testing.debug
接口，并配合python with语句进入调试模式，选择CPU作为算子的运行平台。
  b. 调用    tbe.common.testing.get_ctx
接口，获取算子运行的上下文。
2. 定义golden数据，用于后续的中间Tensor数据验证及算子输出验证。
3. 实现DSL算子的计算逻辑，并根据需要进行中间数据验证。

  a. 调用TBE提供的DSL接口进行计算逻辑描述，指明算子的计算方法和步骤。
  b. （可选）中间Tensor数据验证
    开发者可调用tbe.common.testing.print_tensor接口，将中间Tensor的数据存入文件或直接打屏显示，调用tbe.common.testing.assert_allclose接口进行中间Tensor的数据校验。

4. 调用TVM的create_schedule接口，为算子创建调度实例对象。
5. 算子编译运行

  a. 调用    tbe.common.testing.build
接口，编译生成在CPU上运行的DSL算子。
  b. 调用    tbe.common.testing.run
接口执行算子。
6. 验证输出数据的正确性。
  至此，DSL算子的调试代码编写完成。开发者可编写入口函数，调用算子接口，进行算子的功能调试。


#### 调试示例

本示例为了展示如何校验中间tensor，输入两个tensor a与b，实现d=a+b+b的加法运算。先计算c=a+b，然后再计算d=c+b，其中c为中间tensor。

```
from tbe import tvm
from tbe import dsl
from tbe.common.utils import para_check
from tbe.common.utils import shape_util
# 引入testing模块相关接口
from tbe.common.testing.testing import *
import numpy as np
@para_check.check_input_type(dict, dict, dict, str)
def addtest(input_a, input_b, output_d, kernel_name="addtest"):
# 进入DSL调试模式，并选择CPU作为运行平台
with debug():
# 获取算子运行的上下文
ctx = get_ctx()
# 获取输入数据的shape与dtype
shape_a = shape_util.scalar2tensor_one(input_a.get("shape"))
shape_b = shape_util.scalar2tensor_one(input_b.get("shape"))
data_type = input_a.get("dtype").lower()
# 使用numpy定义输入golden数据大小
a = tvm.nd.array(np.random.uniform(size=shape_a).astype(data_type), ctx)
b = tvm.nd.array(np.random.uniform(size=shape_b).astype(data_type), ctx)
# 使用numpy将输出d初始化为全0
d = tvm.nd.array(np.zeros(shape_a, dtype=data_type), ctx)
# 调用TVM的placeholder接口对输入tensor进行占位，并返回一个tensor对象
data_a = tvm.placeholder(shape_a, name="data_1", dtype=data_type)
data_b = tvm.placeholder(shape_b, name="data_2", dtype=data_type)
# 调用DSL计算接口实现data_a + data_b
data_c = dsl.vadd(data_a, data_b)
# 中间Tensor数据验证
sample = open('samplefile.txt', 'w')
# 将中间tensor data_c存入文件samplefile.txt
print_tensor(data_c, ofile=sample)
# 检查中间tensor data_c的值是否正确
assert_allclose(data_c, desired=a.asnumpy() + b.asnumpy(), tol=[1e-7, 1e-7])
print("The value of data_c is the same as the expected value.")
# 继续自定义DSL的逻辑撰写,调用DSL接口实现：data_d = data_c + data_b
data_d = dsl.vadd(data_c, data_b)
# 调用TVM的create_schedule接口，为算子创建调度实例对象，入参为输出tensor的OP列表。
s = tvm.create_schedule(data_d.op)
# 编译生成算子,data_a,data_b,data_d是占位的输入输出列表，AddTest是我们自定义算子的名称
build(s, [data_a, data_b, data_d], name="AddTest")
# 执行算子,将a,b,d按顺序代入编译出来的DSL算子AddTest
run(a, b, d)  # AddTest(a, b, d)
# 将输出数据d的值打印出来,并预期结果进行比较，看是否相符
print("d:", d)
tvm.testing.assert_allclose(d.asnumpy(), a.asnumpy() + b.asnumpy() + b.asnumpy())
print("The actual output is the same as the expected output.")
# 编写入口函数，调用addtest函数
if __name__ == "__main__":
input_output_dict = {"shape": (2, 3, 4),"format": "ND","ori_shape": (2, 3, 4),"ori_format": "ND", "dtype":"float32"}
addtest(input_output_dict, input_output_dict, input_output_dict, kernel_name="addtest")
```

在屏幕上的输出为：

```
======================== debug enter =======================
The value of data_c is the same as the expected value.
Tensor add_0 is saved to file samplefile.txt.
d: [[[1.1099341  2.7536283  0.6441797  1.9604567 ]
[0.25995332 1.997332   1.4089121  1.7263429 ]
[0.59042984 1.079533   2.1142702  1.3301892 ]]
[[1.6043677  1.2658448  1.7424912  0.57584894]
[1.6016111  1.2254462  0.34414443 1.43648   ]
[2.1096592  1.4920356  2.0675716  2.458529  ]]]
The actual output is the same as the expected output.
======================== debug exit ========================
```

由打印信息“The value of data_c is the same as the expected value.”可知中间tensor data_c的计算结果与预期结果相同。

由打印信息“The actual output is the same as the expected output. ”可知最终输出结果与预期结果相同。

中间tensor data_c的数据存储到了samplefile.txt文件中。
