r""" Unlike torch.allocse which only handles Tensor arguments, allclose handles list, tuple, dict and nesting of these as well.
(lhs, rhs, rtol=1e-5, atol=1e-8)
| 401 | |
| 402 | |
| 403 | def allclose(lhs, rhs, rtol=1e-5, atol=1e-8): |
| 404 | r""" |
| 405 | Unlike torch.allocse which only handles Tensor arguments, allclose handles |
| 406 | list, tuple, dict and nesting of these as well. |
| 407 | """ |
| 408 | if isinstance(lhs, torch.Tensor) and isinstance(rhs, torch.Tensor): |
| 409 | return torch.allclose(lhs, rhs, rtol, atol) |
| 410 | if isinstance(lhs, (tuple, list)) and isinstance(rhs, (tuple, list)): |
| 411 | return len(lhs) == len(rhs) and all( |
| 412 | allclose(a, b, rtol, atol) for a, b in zip(lhs, rhs) |
| 413 | ) |
| 414 | if isinstance(lhs, dict) and isinstance(rhs, dict): |
| 415 | lhs_keys = set(lhs.keys()) |
| 416 | rhs_keys = set(rhs.keys()) |
| 417 | if lhs_keys != rhs_keys: |
| 418 | return False |
| 419 | return all(allclose(lhs[k], rhs[k], rtol, atol) for k in lhs) |
| 420 | else: |
| 421 | raise RuntimeError( |
| 422 | f"Unexpected types: lhs type {type(lhs)}, rhs type {type(rhs)}" |
| 423 | ) |
| 424 | |
| 425 | |
| 426 | def validate_contiguous_tensors(program): |