Use Pytorch Benchmark on the forward+backward pass of an arbitrary function.
(
fn,
*inputs,
grad=None,
repeats=10,
desc="",
verbose=True,
amp=False,
amp_dtype=torch.float16,
**kwinputs,
)
| 70 | |
| 71 | |
| 72 | def benchmark_combined( |
| 73 | fn, |
| 74 | *inputs, |
| 75 | grad=None, |
| 76 | repeats=10, |
| 77 | desc="", |
| 78 | verbose=True, |
| 79 | amp=False, |
| 80 | amp_dtype=torch.float16, |
| 81 | **kwinputs, |
| 82 | ): |
| 83 | """Use Pytorch Benchmark on the forward+backward pass of an arbitrary function.""" |
| 84 | if verbose: |
| 85 | print(desc, "- Forward + Backward pass") |
| 86 | with torch.autocast(device_type="cuda", dtype=amp_dtype, enabled=amp): |
| 87 | y = fn(*inputs, **kwinputs) |
| 88 | if type(y) is tuple: |
| 89 | y = y[0] |
| 90 | if grad is None: |
| 91 | grad = torch.randn_like(y) |
| 92 | else: |
| 93 | if grad.shape != y.shape: |
| 94 | raise RuntimeError("Grad shape does not match output shape") |
| 95 | |
| 96 | def f(grad, *inputs, **kwinputs): |
| 97 | for x in inputs: |
| 98 | if isinstance(x, torch.Tensor): |
| 99 | x.grad = None |
| 100 | with torch.autocast(device_type="cuda", dtype=amp_dtype, enabled=amp): |
| 101 | y = fn(*inputs, **kwinputs) |
| 102 | if type(y) is tuple: |
| 103 | y = y[0] |
| 104 | y.backward(grad, retain_graph=True) |
| 105 | |
| 106 | t = benchmark.Timer( |
| 107 | stmt="f(grad, *inputs, **kwinputs)", |
| 108 | globals={"f": f, "fn": fn, "inputs": inputs, "grad": grad, "kwinputs": kwinputs}, |
| 109 | num_threads=torch.get_num_threads(), |
| 110 | ) |
| 111 | m = t.timeit(repeats) |
| 112 | if verbose: |
| 113 | print(m) |
| 114 | return t, m |
| 115 | |
| 116 | |
| 117 | def benchmark_fwd_bwd( |
no outgoing calls
no test coverage detected