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

Fix mapwindow for offset arrays #160

Merged
merged 6 commits into from
Jul 9, 2020

Conversation

yha
Copy link
Contributor

@yha yha commented Mar 23, 2020

The deleted assertions fail due to JuliaArrays/OffsetArrays.jl#104. As a workaround, I tried

@assert (imgr .+ kmin)[idx] ⊆ fullimgr
@assert (imgr .+ kmax)[idx] ⊆ fullimgr

instead, but that fails due to JuliaLang/julia#35225 when idx turns out empty.

@codecov
Copy link

codecov bot commented Mar 23, 2020

Codecov Report

Merging #160 into master will increase coverage by 0.07%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #160      +/-   ##
==========================================
+ Coverage   90.99%   91.06%   +0.07%     
==========================================
  Files           9        9              
  Lines        1232     1231       -1     
==========================================
  Hits         1121     1121              
+ Misses        111      110       -1     
Impacted Files Coverage Δ
src/mapwindow.jl 85.50% <100.00%> (+0.41%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 14f174d...5bab482. Read the comment docs.

@johnnychen94
Copy link
Member

johnnychen94 commented Mar 23, 2020

I think the assertation makes sense and should not be removed. The fact that the tests pass is more concerning IMO...

With JuliaArrays/OffsetArrays.jl#105 and the following patch, the assertation passes, but there're some new errors in the added tests.

https://github.com/JuliaImages/ImageFiltering.jl/blob/master/src/mapwindow.jl#L200

function _indexof(r::AbstractRange, x)
    T = eltype(r)
    @assert x ∈ r
-	i = ont(T) + T((x - first(r)) / step(r))
+   i = first(axes(r)[1]) + T((x - first(r)) / step(r))
    @assert r[i] == x
    i
end

Update: Perhaps TiledIterations also needs some more update for OffsetArray 1.0

@yha
Copy link
Contributor Author

yha commented May 25, 2020

Updated version, which should work assuming JuliaArrays/OffsetArrays.jl#105 (and includes the assertions).
(I believe the previous version without the assertions was also technically correct, but in a weird way, with methods not doing exactly what their name suggests for offset arrays, and relying subtly on JuliaArrays/OffsetArrays.jl#104).

This version has axes(mapwindow(..., indices=2:7),1) == 1:6, which is what the docs says it should do, rather than 2:7 as before. This is also more consistent the behavior of non-unit-ranges, e.g., indices=2:2:8. I changed one test as a result, which previously tested for behavior which contradict the docs.

(dim,a) in enumerate(arrays)
offsets = ntuple(_->offset,dim)
windows = ntuple(_->window,dim)
@test OffsetArray(mapwindow(f,a,windows),offsets) == mapwindow(f,OffsetArray(a,offsets),windows)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this is a good test and we should have it. Just asking, is this test different from behavior on master? Could also add a case where there is no handcrafted version for f. E.g. f = x -> sum(x)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The behavior on master is an assertion error when the input array has non-zero offset.
The original version of this PR simply removed these assertions and loosened some type checks, which happens to work "accidentally", but would stop working once JuliaArrays/OffsetArrays.jl#104 is fixed (e.g. JuliaArrays/OffsetArrays.jl#105 is merged).
The current version is the opposite: it depends on JuliaArrays/OffsetArrays.jl#105 to work.

Not sure what you mean about handcrafted version for f. AFAICT there is no specialized implementation of mapwindow for minimum or maximum.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks for clarifying. I do not remember for which functions there is a specialized implementation. Even if there is none for minimum/maximum right now, it could potentially be added in future, so I believe adding a lambda f won't hurt.

@@ -115,7 +129,7 @@ using ImageFiltering: IdentityUnitRange
@test expected == @inferred mapwindow!(f,out,img,window,indices=imginds)
end
for (inds, kw) ∈ [((Base.OneTo(3),), (border="replicate", indices=2:2:7)),
((2:7,), (indices=2:7,)),
(axes(2:7), (indices=2:7,)),
Copy link
Collaborator

Choose a reason for hiding this comment

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

I do not have an opinion on whether this is a bug fix or breaking change.

Copy link
Collaborator

@jw3126 jw3126 left a comment

Choose a reason for hiding this comment

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

Basically looks good to me, see comments above.

@yha
Copy link
Contributor Author

yha commented May 25, 2020

Basically looks good to me, see comments above.

Note this should probably be merged only after JuliaArrays/OffsetArrays.jl#105, with a corresponding compat entry.

@johnnychen94
Copy link
Member

Sorry that I was too busy these days to take care of this PR. I'll find some time to work on JuliaArrays/OffsetArrays.jl#105 this later.

@yha
Copy link
Contributor Author

yha commented May 26, 2020

Added tests for anonymous functions and various border styles. Also fixed the axes for Inner() which I apparently broke.
Caught some new failure cases which already fail in master. I'll open a new issue for those.

@yha yha mentioned this pull request May 26, 2020
Copy link
Member

@johnnychen94 johnnychen94 left a comment

Choose a reason for hiding this comment

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

The changes look reasonable and unharmful to me and the test passes locally

Reviewing ImageFiltering.jl is still quite challenging to me, it would be the best if we can get @timholy involved before merging this.

@johnnychen94
Copy link
Member

reopen to retrigger the test

@johnnychen94
Copy link
Member

johnnychen94 commented Jun 18, 2020

The failure in nightly is because I retriggered the CI too quickly that PkgServer (enabled by default since Julia 1.5) didn't get updated and thus didn't found OffsetArrays v1.1.0.

There seem to be other issues in the nightly test: https://github.com/JuliaCI/NanosoldierReports/blob/master/pkgeval/by_date/2020-06/13/logs/ImageFiltering/1.6.0-DEV-6b2ffd3913.log

@yha
Copy link
Contributor Author

yha commented Jun 18, 2020

There seem to be other issues in the nightly test: https://github.com/JuliaCI/NanosoldierReports/blob/master/pkgeval/by_date/2020-06/13/logs/ImageFiltering/1.6.0-DEV-6b2ffd3913.log

This seems to be before the fix in #174.

@johnnychen94
Copy link
Member

johnnychen94 commented Jun 18, 2020

It seems to be only an CI issue, the test passes locally for nightly build (mac and Linux).

I believe this PR is ready to merge and it's being unfairly delayed for quite a long time, so I plan to merge this next Monday if there are no further comments.

@timholy
Copy link
Member

timholy commented Jun 18, 2020

Let's try re-running CI

@timholy timholy closed this Jun 18, 2020
@timholy timholy reopened this Jun 18, 2020
Copy link
Member

@timholy timholy left a comment

Choose a reason for hiding this comment

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

I haven't independently dug into the causes of the failures, so I am not fully up-to-speed on this, but by the weekend I'll try to take a more care. Meanwhile, the test alone here is fantastic!

@@ -72,14 +73,18 @@ function mapwindow(f, img, window; border="replicate",
resolve_imginds(indices))
end

# a unit range `r` having `r == axes(r)` which keeps its axes with
# broadcasting (e.g., `axes(r.+1) == axes(r)`), unlike Base.IdentityUnitRange
self_offset(r::AbstractUnitRange) = OffsetArrays.IdOffsetRange(1:length(r), first(r)-one(eltype(r)))
Copy link
Member

Choose a reason for hiding this comment

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

I'm not exactly sure I understand what you're trying to do. It doesn't quite do what it claims in the comment, for example

julia> r2 = OffsetArrays.IdOffsetRange(5:10, -3)
2:7

julia> r3 = self_offset(r2)
2:7

julia> first(r3)
2

julia> first(axes(r2, 1))
-2

What's the underlying goal? Would you like to create a range that preserves the values and indices of an original AbstractUnitRange but which behaves as described under broadcasting?

Or is this a situation where we can essentially ignore certain axes? For instance, we might imagine ignoring the axes of imginds, although alternatively they might specify the axes of the output.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I suppose the comment is confusing because it uses the name r for the output of the function when it's also as the name of the function parameter. It should really say that s = self_offset(r) has the same values as r but has itself as indices: collect(s) == collect(r) and axes(s) == (s,) (in your example, axes(r3) == (2:7,) == (r3,)).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed the comment

src/mapwindow.jl Outdated Show resolved Hide resolved
test/mapwindow.jl Show resolved Hide resolved
@yha
Copy link
Contributor Author

yha commented Jun 29, 2020

Bump

@johnnychen94
Copy link
Member

Hmmm... I'll merge this in days if there are no further comments

@johnnychen94
Copy link
Member

johnnychen94 commented Jul 9, 2020

Given that @timholy is quite busy these days for a second-round comment, I'm merging this.

@yha This is really a nice and tough job! I trust you know how things going internally. Also, the test looks great to me, so let's test this patch in the wild.

Sorry again for the long delay here, once the test passes in master, I'll tag a release for this.

@johnnychen94 johnnychen94 merged commit b58b139 into JuliaImages:master Jul 9, 2020
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.

4 participants