[functorch] no_grad fix (pytorch/functorch#179)
Fixes https://github.com/facebookresearch/functorch/issues/13
Case 1: grad gets called inside torch.no_grad.
- grad should ignore torch.no_grad because it's "creating a new level of
autograd above the current level"
- Another way to think about this is that grad(f) is a "function
transform": its result should not be affected by context managers that
are outside of the function f
Case 2: torch.no_grad gets called inside `grad`
- grad should respect torch.no_grad
See NOTE [grad and vjp interaction with no_grad] for implementation
strategy. It unfortunately involves a mode.
Test Plan:
- Many tests