Skip to content
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

test fix for multiprecision 562 #1015

Merged
merged 3 commits into from
Aug 23, 2023

Conversation

ryanelandt
Copy link
Contributor

@ryanelandt ryanelandt commented Aug 20, 2023

According to this, if a floating point type T supports subnormal numbers, then std::numeric_limits<T>::denorm_min() is a subnormal number. If support is absent, then std::numeric_limits<T>::denorm_min() is std::numeric_limits<T>::min().

There is a test in test_autodiff_7.cpp that checks that std::numeric_limits<T>::denorm_min() is not a normal number. This test passes even though the statement is sometimes false. This result is due to an oversight in Boost Multiplication to be corrected by this PR.

This PR updates this incorrect test so that Boost Math doesn't breaking when the above mentioned Boost Multiprecision PR gets merged.

@ckormanyos
Copy link
Member

I'm not the expert here, but somehow my feeling might be to handle/agree to this one, when/if possible. After that, then boostorg/multiprecision#562

Thoughts?

@ryanelandt
Copy link
Contributor Author

ryanelandt commented Aug 20, 2023

As to the order of the two PRs, there are two schools of thoughts:

  1. The purpose of unit tests is not that they pass, but that they check for correctness. If Boost Math tests require incorrect values values of std::numeric_limits<T>::denorm_min() to pass, then having these tests fail is the desired result. Enforcing correctness in Boost Multiprecision is the responsibility of that library's CI. Holding up a PR because it may/will break tests in external libraries is not sensible. If it broke test in private libraries, how would we even know?
  2. Libraries should avoid making changes that break the code of downstream users. Mediating steps can be taking that include deprecation warnings. In extreme cases, this means depreciating a library, and creating a new one. I think this is what happened when https://github.com/boostorg/signals was depreciated in favor of https://github.com/boostorg/signals2.

I think that approach 2 is sensible when it comes to API changes, but not so much in this situation. I don't know which approach is the Boost way. Hopefully someone in the know can weight in. In any case, this may be a moot point. I think this is a good candidate for a speedy merge.

@pulver
Copy link
Collaborator

pulver commented Aug 20, 2023

Can the type T be checked with has_denorm in order to verify the applicability of tests such as

    BOOST_CHECK(
        !isnormal(make_fvar<T, m>(std::numeric_limits<T>::denorm_min())));

?

I see has_denorm is marked deprecated in C++23 but perhaps an equivalent test can be used for later compilers?

If not, it might be useful to instead comment out the test with a reference back to this discussion in case someone wonders about this issue.

@ryanelandt
Copy link
Contributor Author

Can the type T be checked with has_denorm in order to verify the applicability of tests such as

I think that's what's going on in this PR. The if statement on line 52 checks has_denorm:

if (std::numeric_limits<T>::has_denorm != std::denorm_absent) {

I added an else statement to this and moved the relevant test inside the else block. Addressing future deprecation issues may be out of the scope of this PR.

In a future without has_denorm, I think the relevant test is 0 < denorm_min() <= min().

@ckormanyos
Copy link
Member

ckormanyos commented Aug 21, 2023

Hi John (@jzmaddock) or Matt (@mborland), could you take a quick look?

Looks trivial and as soon as a tiny review is finished, we can handle both this PR as well as the one in Multiprecision.

@jzmaddock
Copy link
Collaborator

I think we're over-thinking this a bit, we know the two libraries are a little entangled, lets just get the multiprecision version merged/fixed, then fix this one properly rather than messing about with #if's.

@pulver
Copy link
Collaborator

pulver commented Aug 21, 2023

Can the type T be checked with has_denorm in order to verify the applicability of tests such as

I think that's what's going on in this PR. The if statement on line 52 checks has_denorm:

if (std::numeric_limits<T>::has_denorm != std::denorm_absent) {

I added an else statement to this and moved the relevant test inside the else block.

In that case, it seems to make sense to move the existing test

    BOOST_CHECK(
        !isnormal(make_fvar<T, m>(std::numeric_limits<T>::denorm_min())));

into the existing if block above that checks has_denorm, rather than deleting it. I believe this applies irrespective of the multiprecision changes.

@ryanelandt
Copy link
Contributor Author

@jzmaddock

I think we're over-thinking this a bit, we know the two libraries are a little entangled, lets just get the multiprecision version merged/fixed, then fix this one properly rather than messing about with #if's.

I agree, sounds great.

@ryanelandt
Copy link
Contributor Author

@pulver

In that case, it seems to make sense to move the existing test

    BOOST_CHECK(
        !isnormal(make_fvar<T, m>(std::numeric_limits<T>::denorm_min())));

into the existing if block above that checks has_denorm, rather than deleting it. I believe this applies irrespective of the multiprecision changes.

I looked at this file more carefully to understand what it is trying to do. It seems that it is testing to see if fpclassify.hpp operates correctly for an autodiff type. I think that fpclassify.hpp is currently tested for various types in the file test_classify.cpp. Would testing the autodiff type in test_classify.cpp cover the same things as the tests in this file?

@pulver
Copy link
Collaborator

pulver commented Aug 21, 2023

I looked at this file more carefully to understand what it is trying to do. It seems that it is testing to see if fpclassify.hpp operates correctly for an autodiff type. I think that fpclassify.hpp is currently tested for various types in the file test_classify.cpp. Would testing the autodiff type in test_classify.cpp cover the same things as the tests in this file?

That sounds like a good idea for both autodiff as well as multiprecision types. Though I can't speak to how best to setup the dependencies (i.e. Add test_classify tests to autodiff/multiprecision tests, or insert autodiff/multiprecision tests into test_classify.cpp?)

@ryanelandt
Copy link
Contributor Author

I added the autodiff types to the classify test, which seems cleaner to me. Does this seem like the correct thing to you?

@pulver
Copy link
Collaborator

pulver commented Aug 21, 2023

I added the autodiff types to the classify test, which seems cleaner to me. Does this seem like the correct thing to you?

Yes, seems that's how it should have originally been done, assuming it's ok w/ @jzmaddock et al.

Thank you!

@ryanelandt
Copy link
Contributor Author

@jzmaddock The failures seem unrelated.

@mborland
Copy link
Member

This looks good to me. Math and Multiprecision are pretty tightly coupled so this is not the first time that we have had to make changes in one that impacts the test results in another.

@mborland mborland merged commit 3d8e1d5 into boostorg:develop Aug 23, 2023
@ryanelandt
Copy link
Contributor Author

Thanks @mborland

@ryanelandt ryanelandt deleted the denorm_min_is_not_zero branch August 23, 2023 13:22
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.

5 participants