# Debugging Methods This section will introduce several debugging methods recommended by Dynamic Graph to Static Graph (hereafter called Dynamic-to-Staic). > **NOTE:** > > Please ensure that the dynamic graph code before transformation can run successfully. It is recommended to call [paddle.jit.ProgramTranslator().enable(False)](../../api/dygraph/ProgramTranslator_en.html#enable) to disable Dynamic-to-Static, and run dynamic graph code as follows: ```python import paddle import numpy as np paddle.disable_static() # Disable Dynamic-to-Static paddle.jit.ProgramTranslator().enable(False) @paddle.jit.to_static def func(x): x = paddle.to_tensor(x) if x > 3: x = x - 1 return x func(np.ones([3, 2])) ``` ## Breakpoint Debugging When using Dynamic-to-Static, you can use breakpoints to debug. For example, call `pdb.set_trace()` in your code: ```Python import pdb @paddle.jit.to_static def func(x): x = paddle.to_tensor(x) pdb.set_trace() if x > 3: x = x - 1 return x ``` Executing the following code will land the debugger in the transformed static graph code: ```Python func(np.ones([3, 2])) ``` ```bash > /tmp/tmpR809hf.py(6)func() -> def true_fn_0(x): (Pdb) n > /tmp/tmpR809hf.py(6)func() -> def false_fn_0(x): ... ``` Calling [`paddle.jit.ProgramTranslator().enable(False)`](../../api/dygraph/ProgramTranslator_en.html#enable) before executing the code will land the debugger in the original dynamic graph code: ```python paddle.jit.ProgramTranslator().enable(False) func(np.ones([3, 2])) ``` ```bash > (10)func() -> if x > 3: ... ``` ## Print Transformed Code There are two ways to print the transformed static graph code: 1. Use the attribute `code` of the decorated function: ```Python @paddle.jit.to_static def func(x): x = paddle.to_tensor(x) if x > 3: x = x - 1 return x print(func.code) ``` ```bash def func(x): x = fluid.layers.assign(x) def true_fn_0(x): x = x - 1 return x def false_fn_0(x): return x x = fluid.dygraph.dygraph_to_static.convert_operators.convert_ifelse(x > 3, true_fn_0, false_fn_0, (x,), (x,), (x,)) return x ``` 2. Call `set_code_level(level)` or set environment variable `TRANSLATOR_CODE_LEVEL=level` You can view the transformed code in the log by calling `set_code_level` or set environment variable `TRANSLATOR_CODE_LEVEL`. ```python @paddle.jit.to_static def func(x): x = paddle.to_tensor(x) if x > 3: x = x - 1 return x paddle.jit.set_code_level() # the same effect to set os.environ["TRANSLATOR_CODE_LEVEL"] = '100' func(np.ones([1])) ``` ```bash 2020-XX-XX 00:00:00,980-INFO: After the level 100 ast transformer: 'All Transformers', the transformed code: def func(x): x = fluid.layers.assign(x) def true_fn_0(x): x = x - 1 return x def false_fn_0(x): return x x = fluid.dygraph.dygraph_to_static.convert_operators.convert_ifelse(x > 3, true_fn_0, false_fn_0, (x,), (x,), (x,)) return x ``` `set_code_level` can set different levels to view the code transformed by different ast transformers. For details, please refer to [set_code_level]()。 ## `print` You can call `print` to view variables. `print` will be transformed when using Dynamic-to-Static. When only Paddle Tensor is printed, `print` will be transformed and call Paddle operator [Print](../../api/layers/Print.html) in runtime. Otherwise, call python `print`. ```python @paddle.jit.to_static def func(x): x = paddle.to_tensor(x) # x is a Paddle Tensor, so it will run Paddle Print(x) actually. print(x) # The string is not a Paddle Tensor, so it will run print as-is. print("Here call print function.") if len(x) > 3: x = x - 1 else: x = paddle.ones(shape=[1]) return x func(np.ones([1])) ``` ```bash Variable: assign_0.tmp_0 - lod: {} - place: CPUPlace - shape: [1] - layout: NCHW - dtype: double - data: [1] Here call print function. ``` ## Log Printing ProgramTranslator can log additional debugging information to help you know whether the function was successfully transformed or not. You can call `paddle.jit.set_verbosity(level)` or set environment variable `TRANSLATOR_VERBOSITY=level` to enable logging and view logs of different levels. The argument `level` varies from 0 to 3: - 0: no logging - 1: includes the information in Dynamic-to-Static tranformation process, such as the source code not transformed, the callable object to transform and so on - 2: includes above and more detailed function transformation logs - 3: includes above and extremely verbose logging > **WARNING:** > > The logs includes information such as source code. Please make sure logs don't contain any sensitive information before sharing them. You can call `paddle.jit.set_verbosity` to control the verbosity level of logs: ```python paddle.jit.set_verbosity(3) ``` or use the environment variable `TRANSLATOR_VERBOSITY`: ```python import os os.environ["TRANSLATOR_VERBOSITY"] = '3' ``` ```bash 2020-XX-XX 00:00:00,123-Level 1: Source code: @paddle.jit.to_static def func(x): x = paddle.to_tensor(x) if len(x) > 3: x = x - 1 else: x = paddle.ones(shape=[1]) return x 2020-XX-XX 00:00:00,152-Level 1: Convert callable object: convert .