1*da0073e9SAndroid Build Coastguard Workerimport textwrap 2*da0073e9SAndroid Build Coastguard Workerfrom typing import Any 3*da0073e9SAndroid Build Coastguard Worker 4*da0073e9SAndroid Build Coastguard Workerimport gdb # type: ignore[import] 5*da0073e9SAndroid Build Coastguard Worker 6*da0073e9SAndroid Build Coastguard Worker 7*da0073e9SAndroid Build Coastguard Workerclass DisableBreakpoints: 8*da0073e9SAndroid Build Coastguard Worker """ 9*da0073e9SAndroid Build Coastguard Worker Context-manager to temporarily disable all gdb breakpoints, useful if 10*da0073e9SAndroid Build Coastguard Worker there is a risk to hit one during the evaluation of one of our custom 11*da0073e9SAndroid Build Coastguard Worker commands 12*da0073e9SAndroid Build Coastguard Worker """ 13*da0073e9SAndroid Build Coastguard Worker 14*da0073e9SAndroid Build Coastguard Worker def __enter__(self) -> None: 15*da0073e9SAndroid Build Coastguard Worker self.disabled_breakpoints = [] 16*da0073e9SAndroid Build Coastguard Worker for b in gdb.breakpoints(): 17*da0073e9SAndroid Build Coastguard Worker if b.enabled: 18*da0073e9SAndroid Build Coastguard Worker b.enabled = False 19*da0073e9SAndroid Build Coastguard Worker self.disabled_breakpoints.append(b) 20*da0073e9SAndroid Build Coastguard Worker 21*da0073e9SAndroid Build Coastguard Worker def __exit__(self, etype: Any, evalue: Any, tb: Any) -> None: 22*da0073e9SAndroid Build Coastguard Worker for b in self.disabled_breakpoints: 23*da0073e9SAndroid Build Coastguard Worker b.enabled = True 24*da0073e9SAndroid Build Coastguard Worker 25*da0073e9SAndroid Build Coastguard Worker 26*da0073e9SAndroid Build Coastguard Workerclass TensorRepr(gdb.Command): # type: ignore[misc, no-any-unimported] 27*da0073e9SAndroid Build Coastguard Worker """ 28*da0073e9SAndroid Build Coastguard Worker Print a human readable representation of the given at::Tensor. 29*da0073e9SAndroid Build Coastguard Worker Usage: torch-tensor-repr EXP 30*da0073e9SAndroid Build Coastguard Worker 31*da0073e9SAndroid Build Coastguard Worker at::Tensor instances do not have a C++ implementation of a repr method: in 32*da0073e9SAndroid Build Coastguard Worker pytorch, this is done by pure-Python code. As such, torch-tensor-repr 33*da0073e9SAndroid Build Coastguard Worker internally creates a Python wrapper for the given tensor and call repr() 34*da0073e9SAndroid Build Coastguard Worker on it. 35*da0073e9SAndroid Build Coastguard Worker """ 36*da0073e9SAndroid Build Coastguard Worker 37*da0073e9SAndroid Build Coastguard Worker __doc__ = textwrap.dedent(__doc__).strip() 38*da0073e9SAndroid Build Coastguard Worker 39*da0073e9SAndroid Build Coastguard Worker def __init__(self) -> None: 40*da0073e9SAndroid Build Coastguard Worker gdb.Command.__init__( 41*da0073e9SAndroid Build Coastguard Worker self, "torch-tensor-repr", gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION 42*da0073e9SAndroid Build Coastguard Worker ) 43*da0073e9SAndroid Build Coastguard Worker 44*da0073e9SAndroid Build Coastguard Worker def invoke(self, args: str, from_tty: bool) -> None: 45*da0073e9SAndroid Build Coastguard Worker args = gdb.string_to_argv(args) 46*da0073e9SAndroid Build Coastguard Worker if len(args) != 1: 47*da0073e9SAndroid Build Coastguard Worker print("Usage: torch-tensor-repr EXP") 48*da0073e9SAndroid Build Coastguard Worker return 49*da0073e9SAndroid Build Coastguard Worker name = args[0] 50*da0073e9SAndroid Build Coastguard Worker with DisableBreakpoints(): 51*da0073e9SAndroid Build Coastguard Worker res = gdb.parse_and_eval(f"torch::gdb::tensor_repr({name})") 52*da0073e9SAndroid Build Coastguard Worker print(f"Python-level repr of {name}:") 53*da0073e9SAndroid Build Coastguard Worker print(res.string()) 54*da0073e9SAndroid Build Coastguard Worker # torch::gdb::tensor_repr returns a malloc()ed buffer, let's free it 55*da0073e9SAndroid Build Coastguard Worker gdb.parse_and_eval(f"(void)free({int(res)})") 56*da0073e9SAndroid Build Coastguard Worker 57*da0073e9SAndroid Build Coastguard Worker 58*da0073e9SAndroid Build Coastguard WorkerTensorRepr() 59