-
Notifications
You must be signed in to change notification settings - Fork 17
Overhall equality checks, to give better failure messages #57
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
Conversation
src/iterator.jl
Outdated
# To make it a valid differential: needs at very least `zero` and `+` | ||
Base.zero(::Type{<:TestIterator}) = Zero() | ||
function Base.:+(iter1::TestIterator{T,IS,IE}, iter2::TestIterator{T,IS,IE}) where {T,IS,IE} | ||
return TestIterator{T,IS,IE}(map(+, iter1, iter2)) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We were using this like a differential, without these being defined,
which ment that testing accumulation errored.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm you're right. The idea with TestIterator
is for it to behave like some generic iterator. For most iterators, we will not be able to define e.g. zero(::SomeIterator)
without type piracy, so maybe the type of TestIterator
's differential should not be TestIterator
but instead a Composite
?
But then again, I guess most iterators won't have isapprox
defined on them, so we're already not super consistent here.
src/testers.jl
Outdated
frule((Zero(), Δx), f, z; fkwargs...)[2], | ||
check_equal( | ||
frule((Zero(), real(Δx)), f, z; fkwargs...)[2]::Number, | ||
frule((Zero(), Δx), f, z; fkwargs...)[2]::Number, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scalar rules shout return Numbers
.
but maybe this should be moved out of this part of the test and be somewhere else
tested explictly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree that this should have an explicit isa Number
test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can leave this for now, I have removed this from the test
I don't really love this PR. though I like it more than the code it replaces i think. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't followed the accumulation PR(s?), so take this review with that caveat. In general I like the introduction of more human-readable errors (can you actually add a test that check_equal
produces human-readable errors for a case where isapprox
would not have?), and I don't see a problem with the accumulation part (can you add a test for the testers for an accumulating function?)
src/iterator.jl
Outdated
# To make it a valid differential: needs at very least `zero` and `+` | ||
Base.zero(::Type{<:TestIterator}) = Zero() | ||
function Base.:+(iter1::TestIterator{T,IS,IE}, iter2::TestIterator{T,IS,IE}) where {T,IS,IE} | ||
return TestIterator{T,IS,IE}(map(+, iter1, iter2)) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm you're right. The idea with TestIterator
is for it to behave like some generic iterator. For most iterators, we will not be able to define e.g. zero(::SomeIterator)
without type piracy, so maybe the type of TestIterator
's differential should not be TestIterator
but instead a Composite
?
But then again, I guess most iterators won't have isapprox
defined on them, so we're already not super consistent here.
src/testers.jl
Outdated
frule((Zero(), Δx), f, z; fkwargs...)[2], | ||
check_equal( | ||
frule((Zero(), real(Δx)), f, z; fkwargs...)[2]::Number, | ||
frule((Zero(), Δx), f, z; fkwargs...)[2]::Number, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree that this should have an explicit isa Number
test.
I have come back to this because i an sick of bad messages around thunks Example change:
|
) | ||
_, real_tangent = frule((Zero(), real(Δx)), f, z; fkwargs...) | ||
_, embedded_tangent = frule((Zero(), Δx), f, z; fkwargs...) | ||
_check_equal(real_tangent, embedded_tangent; isapprox_kwargs...) | ||
end | ||
end | ||
if z isa Complex |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to move the 4 sections of this function that happen only for complex out into 2 helper functions.
(one for forward on one for reverse)
but that should be a follow up PR as it will make this hard to read.
src/check_result.jl
Outdated
are shown on failures. | ||
All keyword arguments are passed to `isapprox`. | ||
""" | ||
function _check_equal( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should export this, (and rename it)
for people who need to write special tests?
Might make it feel more safe to remove isapprox
as there is a handy subsitution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I think we're probably committed to maintaining some functionality of this form, I agree that we should export it.
) where {T1,T2,IS,IE} | ||
return isapprox(iter1.data, iter2.data; kwargs...) | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically this is breaking, but I am pretty sure they are not used except in this package.
But I could keep them and move them to deprecated, do you think?
Co-authored-by: willtebbutt <wt0881@my.bristol.ac.uk>
Yes, this closes #7 (technically would need to wait for next breaking change when
#56 was actually closed by the follow up to this PR that was more minimal #59, but I forgot to close it |
I wanted to add accumulation checks,but to do that
I felt it was good to refactor away from using
isapprox
as much as we do,I am not entirely sure this PR is a great idea,
the accumulation stuff is easy enough to put in another PR, if we don't like the rest of it.
This PR is a great idea.
To deal with giving useful error messages an not things about thunks not being equal.
and getting rid of all the hacks with
extern
,collect
, andisapprox
.effectively closes #7 as we will be able to delete
isapprox
on differentials with the next major release