Compare two tensors and raise AssertionError if their difference is outside of tolerance.
(a, b, rtol=1e-7, atol=1e-6, ctol=1e-6)
| 71 | dst.load_state_dict(dst_state_dict) |
| 72 | |
| 73 | def compare(a, b, rtol=1e-7, atol=1e-6, ctol=1e-6): |
| 74 | """Compare two tensors and raise AssertionError if their difference is outside of tolerance.""" |
| 75 | if torch.isinf(a).any(): |
| 76 | raise ValueError("a contains infs") |
| 77 | if torch.isinf(b).any(): |
| 78 | raise ValueError("b contains infs") |
| 79 | |
| 80 | a = a.detach().cpu().numpy().flatten() |
| 81 | b = b.detach().cpu().numpy().flatten() |
| 82 | |
| 83 | # compare elements of a and b relative to the max value in b |
| 84 | # large fp32 values may cause quantization errors that propagate to small values |
| 85 | rel_diff = np.abs(a-b)/np.linalg.norm(b) |
| 86 | abs_diff = np.abs(a-b) |
| 87 | cos_diff = distance.cosine(a, b) |
| 88 | try: |
| 89 | if rel_diff.max() > rtol: |
| 90 | raise AssertionError("Tensor relative error > %.2e (%.2e)" % (rtol, rel_diff.max())) |
| 91 | if abs_diff.max() > atol: |
| 92 | raise AssertionError("Tensor absolute error > %.2e (%.2e)" % (atol, abs_diff.max())) |
| 93 | if cos_diff > ctol: |
| 94 | raise AssertionError("Tensor cosine distance > %.2e (%.2e)" % (ctol, cos_diff)) |
| 95 | # np.testing.assert_allclose(a, b, rtol=rtol, atol=atol) |
| 96 | # np.testing.assert_array_almost_equal_nulp(a, b) |
| 97 | except AssertionError as e: |
| 98 | print('norm(a) =', np.linalg.norm(a)) |
| 99 | print('norm(b) =', np.linalg.norm(b)) |
| 100 | print('Largest relative difference = %.2e' % rel_diff.max()) |
| 101 | idx = np.argmax(rel_diff) |
| 102 | print('a[%d] = %.10f' % (idx, a[idx])) |
| 103 | print('b[%d] = %.10f' % (idx, b[idx])) |
| 104 | print('Largest absolute difference = %.2e' % abs_diff.max()) |
| 105 | idx = np.argmax(abs_diff) |
| 106 | print('a[%d] = %.10f' % (idx, a[idx])) |
| 107 | print('b[%d] = %.10f' % (idx, b[idx])) |
| 108 | print('Cosine distance = %.2e' % cos_diff) |
| 109 | raise e |
| 110 | |
| 111 | def assert_min_mse(a, b, tol=1e-20): |
| 112 | """Assert that the mean squared error between a and b is at least tol.""" |