调试

TVM调试器是用于调试TVM计算图执行的接口。它有助于在TVM运行时提供对图形结构和张量值的访问。

调试交换格式

1.计算图Graph

通过relay 以json序列化格式构建的优化图将按原样转储,它包含有关Graph的全部信息。UX可以直接使用此图,也可以将此图转换为UX可以理解的格式。
图表JSON格式说明如下:
1. nodes Node是json中的占位符或计算Node。Node存储为列表。一个Node包含以下信息

  • op-操作类型,null表示它是一个占位符/变量/输入Node,而“ tvm_op”表示该Node可以执行
  • name -Node名称
  • inputs-此操作的输入位置,Inputs是具有(nodeid,index,version)的元组列表。(可选的)如果此Node是一个输入Node(即作为别的Node的输入参数),inputs为空[]。
  • attrs -Node的属性,包含以下信息
    • flatten_data -执行前是否需要将该数据展平
    • func_name -融合函数名称,对应于 relay 编译过程在lib中生成的符号。
    • num_inputs -该Node的输入数量
    • num_outputs -该Node产生的输出数量
  1. arg_nodes arg_nodes是Node索引的列表,该索引是图形的占位符/变量/输入或常量/参数。
    3. heads heads是条目列表,作为图的输出。
    4. node_row_ptr node_row_ptr存储转发路径的历史记录,因此您可以在推理任务中跳过构造整个图形的过程。
    5. attrs attrs可以包含版本号或类似的有用信息。
  • storage_id -存储布局中每个Node的内存插槽ID。
  • dtype -每个Node的数据类型(枚举值)。
  • dltype -每个Node的数据类型顺序。
  • shape -每个Node的形状为k阶。
  • device_index -图形中每个条目的设备分配。

转储图的示例:

  1. {
  2. "nodes": [ # List of nodes
  3. {
  4. "op": "null", # operation type = null, this is a placeholder/variable/input or constant/param node
  5. "name": "x", # Name of the argument node
  6. "inputs": [] # inputs for this node, its none since this is an argument node
  7. },
  8. {
  9. "op": "tvm_op", # operation type = tvm_op, this node can be executed
  10. "name": "relu0", # Name of the node
  11. "attrs": { # Attributes of the node
  12. "flatten_data": "0", # Whether this data need to be flattened
  13. "func_name": "fuse_l2_normalize_relu", # Fused function name, corresponds to the symbol in the lib generated by compilation process
  14. "num_inputs": "1", # Number of inputs for this node
  15. "num_outputs": "1" # Number of outputs this node produces
  16. },
  17. "inputs": [[0, 0, 0]] # Position of the inputs for this operation
  18. }
  19. ],
  20. "arg_nodes": [0], # Which all nodes in this are argument nodes
  21. "node_row_ptr": [0, 1, 2], # Row indices for faster depth first search
  22. "heads": [[1, 0, 0]], # Position of the output nodes for this operation
  23. "attrs": { # Attributes for the graph
  24. "storage_id": ["list_int", [1, 0]], # memory slot id for each node in the storage layout
  25. "dtype": ["list_int", [0, 0]], # Datatype of each node (enum value)
  26. "dltype": ["list_str", [ # Datatype of each node in order
  27. "float32",
  28. "float32"]],
  29. "shape": ["list_shape", [ # Shape of each node k order
  30. [1, 3, 20, 20],
  31. [1, 3, 20, 20]]],
  32. "device_index": ["list_int", [1, 1]], # Device assignment for each node in order
  33. }
  34. }

2.张量转储

执行后收到的张量是tvm.ndarray类型。所有张量将以序列化格式保存为二进制字节。结果二进制字节可以由API“ load_params”加载。
加载参数的例子::with open(path_params, “rb”) as fi:
loading_params = bytearray(fi.read())
module.load_params(loaded_params)

如何使用调试器

  1. config.cmakeUSE_GRAPH_RUNTIME_DEBUG标志设为ON
    # Whether enable additional graph debug functions
    set(USE_GRAPH_RUNTIME_DEBUG ON)
  2. 执行’Make’,编译生成 libtvm_runtime.so
  3. 在前端脚本文件中,导入 debug_runtime
    1. from tvm.contrib.debugger import debug_runtime as graph_runtime
    2. m = graph_runtime.create(graph, lib, ctx, dump_root="/tmp/tvmdbg")
    3. # set inputs
    4. m.set_input('data', tvm.nd.array(data.astype(dtype)))
    5. m.set_input(**params)
    6. # execute
    7. m.run()
    8. tvm_out = m.get_output(0, tvm.nd.empty(out_shape, dtype)).asnumpy()
    输出将转储到临时文件夹/tmp或创建运行时时指定的文件夹中的临时文件夹中。

    样本输出

    以下是调试器的示例输出。 ```bash Node Name Ops Time(us) Time(%) Start Time End Time Shape Inputs Outputs

1NCHW1c fuselayout_transform4 56.52 0.02 15:24:44.177475 15:24:44.177534 (1, 1, 224, 224) 1 1 contribconv2dnchwc0 fusecontribconv2d_NCHWc 12436.11 3.4 15:24:44.177549 15:24:44.189993 (1, 1, 224, 224, 1) 2 1 relu0_NCHW8c fuselayout_transformbroadcast_add_relulayout_transform 4375.43 1.2 15:24:44.190027 15:24:44.194410 (8, 1, 5, 5, 1, 8) 2 1 _contrib_conv2d_nchwc1 fusecontribconv2d_NCHWc_1 213108.6 58.28 15:24:44.194440 15:24:44.407558 (1, 8, 224, 224, 8) 2 1 relu1_NCHW8c fuselayout_transformbroadcast_add_relulayout_transform 2265.57 0.62 15:24:44.407600 15:24:44.409874 (64, 1, 1) 2 1 _contrib_conv2d_nchwc2 fusecontribconv2d_NCHWc_2 104623.15 28.61 15:24:44.409905 15:24:44.514535 (1, 8, 224, 224, 8) 2 1 relu2_NCHW2c fuselayout_transformbroadcast_add_relulayout_transform_1 2004.77 0.55 15:24:44.514567 15:24:44.516582 (8, 8, 3, 3, 8, 8) 2 1 _contrib_conv2d_nchwc3 fusecontrib_conv2d_NCHWc_3 25218.4 6.9 15:24:44.516628 15:24:44.541856 (1, 8, 224, 224, 8) 2 1 reshape1 fuselayout_transformbroadcast_add_reshape_transpose_reshape 1554.25 0.43 15:24:44.541893 15:24:44.543452 (64, 1, 1) 2 1 ```