Debugging your Transforms

PADL provides a customized debugger to inspect and diagnose errors raised when applying a Pipeline.

For using this functionality, call pd_debug after the execution failed, such as

# train_apply, eval_apply or infer_apply that produced a RuntimeError

from padl import pd_debug

pd_debug()

This way, we get a debugger where we can interact with the different parts of the Pipeline and inspect relevant information on each level.

The debugger console has defined the following commands:

* u(p): go one abstraction level up on the {class}`~padl.transforms.Pipeline`.
* d(own): go one abstraction level down on the {class}`~padl.transforms.Pipeline`.
* w(here am I?): show code position where the {class}`~padl.transforms.Transform` was defined.
* i(nput): show input to this level.
* r(epeat): repeat the execution from here (it will produce the same Exception).
* t(ransform): display the current Transform.
* h(elp): print help about the commands.
* q(uit): quit the debugger.

On top of this, it incorporates an in-line co:mpiler so the user can define and inspect variables, check attributes, import packages…

Example

Let t be the following Pipeline.

import torch
from padl import transform, batch

to_tensor = transform(lambda x: torch.LongTensor(x))
emb = transform(torch.nn.Embedding)(10, 8)
linear =  transform(torch.nn.Linear)(5, 5)
t = to_tensor >> batch >> emb >> linear

Then, if we run

list(t.train_apply([[9,8,8], [4, 4, 4], [5, 5, 5], [6, 6, 6]], batch_size=2, num_workers=0))

we get an error since the shape of the embeddings does not match with the one expected by the linear layer. Calling pd_debug after this will retrieve a console where we can make some checks.

At the starting level of the debugger, we interact with the entire Transform and its absolute input. When going down one level by entering d , the debugger switches to the {ref} stage that got the Exception (preprocess, forward or postprocess), and each level deeper moves recursively inside the element that failed until the AtomicTransform that failed is reached.

Below, some commands and statements are shown:

> i

[[9, 8, 8], [4, 4, 4]]

> t

Compose - "t":

      │
      ▼ x
   0: lambda x: torch.LongTensor(x)                
      │
      ▼ args
   1: Batchify(dim=0)                              
      │
      ▼ input
   2: Embedding(num_embeddings=10, embedding_dim=8)
      │
      ▼ input
   3: Linear(in_features=5, out_features=5)          <---- error here 

> w
    
----> 7    t = to_tensor >> batch >> emb >> linear

> d

Compose:

      │
      ▼ input
   0: Embedding(num_embeddings=10, embedding_dim=8)
      │
      ▼ input
   1: Linear(in_features=5, out_features=5)          <---- error here 

> d

Linear(in_features=5, out_features=5) - "linear":

   Linear(in_features=5, out_features=5, bias=True)  <---- error here 

> w

----> 6    linear = transform(torch.nn.Linear)(5, 5)

> i.shape

torch.Size([2, 3, 8])

> a = 4
> a + 1

5

> q