Skip to content

Deprecate redefinition of np.testing.assert_allclose #784

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

Dhruvanshu-Joshi
Copy link
Member

@Dhruvanshu-Joshi Dhruvanshu-Joshi commented May 27, 2024

Description

Replaced all instances of assert_allclose with corresponding np.testing.assert_allclose.

Related Issue

Checklist

Type of change

  • New feature / enhancement
  • Bug fix
  • Documentation
  • Maintenance
  • Other (please specify):

@Dhruvanshu-Joshi Dhruvanshu-Joshi force-pushed the deprecate_testingnp branch 5 times, most recently from 94bdd55 to ba18c65 Compare June 3, 2024 06:48
Copy link

codecov bot commented Jun 3, 2024

Codecov Report

Attention: Patch coverage is 33.33333% with 4 lines in your changes missing coverage. Please review.

Project coverage is 80.96%. Comparing base (5c8afae) to head (87c6ee6).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #784      +/-   ##
==========================================
- Coverage   80.97%   80.96%   -0.02%     
==========================================
  Files         169      169              
  Lines       47015    47011       -4     
  Branches    11497    11497              
==========================================
- Hits        38072    38061      -11     
- Misses       6728     6729       +1     
- Partials     2215     2221       +6     
Files Coverage Δ
pytensor/tensor/math.py 90.09% <ø> (-0.34%) ⬇️
pytensor/tensor/type.py 93.73% <33.33%> (-0.81%) ⬇️

... and 3 files with indirect coverage changes

@Dhruvanshu-Joshi Dhruvanshu-Joshi force-pushed the deprecate_testingnp branch 3 times, most recently from 135ff93 to 87c6ee6 Compare July 2, 2024 19:08
Copy link
Member

@ricardoV94 ricardoV94 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Asking whether we can remove one more helper from the non-test codebase

Comment on lines +665 to +670
atol_, rtol_ = pytensor.tensor.math._get_atol_rtol(a, b)
if rtol is not None:
rtol_ = rtol
if atol is not None:
atol_ = atol
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage says this is not being used, can we just remove?

@@ -85,7 +85,15 @@ def test_variable_only(self):
z = dot(x, y)
assert hasattr(z.tag, "test_value")
f = pytensor.function([x, y], z)
assert _allclose(f(x.tag.test_value, y.tag.test_value), z.tag.test_value)
atol_, rtol_ = _get_atol_rtol(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this ends up only being used in the tests here, we can remove from math and include only in the test file?

@Dhruvanshu-Joshi
Copy link
Member Author

So what is to be done here. Here's what is changing. So originally in pytensor.tensor.type, the function def values_eq_approx uses _allclose function from pytensor.tensor.math. Here if atol and rtol values are not provided, _allclose makes a call to _get_atol_rtol_values which calculates them. Now since we are removing the _allclose function altogether, I used the _get_atol_rtol_values directly in pytensor.tensor.type. And because _get_atol_rtol_values is used in pytensor.tensor.type, we cannot move it into unittest_tools.py in tests.

@Dhruvanshu-Joshi Dhruvanshu-Joshi force-pushed the deprecate_testingnp branch 2 times, most recently from 81a97df to 26782d2 Compare October 2, 2024 17:19
@Dhruvanshu-Joshi
Copy link
Member Author

Hi @ricardoV94
Is there something left here? I don't understand why the coverage test is failing.

@@ -607,7 +607,7 @@ def test_mul_div_cases(self):
f = function(list(sym_inputs), g, mode=mode)
out = f(*val_inputs)
assert out_dtype == out.dtype
utt.assert_allclose(out, val_inputs[1])
np.allclose(out, val_inputs[1])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be np.testing.assert_allclose

@@ -627,7 +627,7 @@ def test_mul_div_cases(self):
):
f = function(list(sym_inputs), g, mode=mode)
out = f(*val_inputs)
utt.assert_allclose(out, (1 / val_inputs[1]))
np.allclose(out, (1 / val_inputs[1]))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also

out, expected_out, atol=1e-6 if config.floatX == "float32" else 0
out,
expected_out,
atol=1e-08 if config.floatX == "float32" else 0,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did this change?

Comment on lines +688 to +691
atol_, rtol_ = _get_atol_rtol(np.asarray(t_binv), n_binv)
assert np.allclose(t_binv, n_binv, atol=atol_, rtol=rtol_)
atol_, rtol_ = _get_atol_rtol(np.asarray(t_binv1), n_binv1)
assert np.allclose(t_binv1, n_binv1, atol=atol_, rtol=rtol_)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is too much code to recreate every time it's used. The question is whether we really need the inner logic. Seems like it has some special way of deciding tolerances for float16/32 complex64. If the tests are covering these types we can hardcode the tolerances, the same way we usually do atol = x if config.floatX else y. But I suspect many of these tests don't even make use of these specific types (I could be wrong).

Otherwise we should keep the original function and not repeat the code so many times in the tests. These functions that are only used in tests should be moved to the tests package, out of the main pytensor package (if we end up keeping it).

Also always use np.testing.assert_allclose and not np.allclose, as it has a nicer output when it fails.

@ricardoV94
Copy link
Member

ricardoV94 commented Oct 15, 2024

@Dhruvanshu-Joshi This PR is already a pretty good improvement, so I don't want to block it much longer. The main question is what to do with that _allclose that we removed. If we keep using the inner logic everywhere it was used we should keep it. Doesn't make sense to repeat the same code 50 times. Hopefully, however, we don't really need it and can just do np.testing.assert_allclose with hardcoded tolerances based on the types that are actually being tested in each test.

If this is too laborious let's revert and address allclose in another PR

@Dhruvanshu-Joshi
Copy link
Member Author

in an

Yep what you mentioned makes complete sense. I try hardcoding the tolerances wherever possible to reduce this unwanted repetitiveness and update whether it is better to go with it or revert this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Remove reimplementation of np.testing.assert_allclose
2 participants