Improve inferrability#28
Conversation
Julia isn't good at type-inference when broadcasting on containers with non-concrete eltypes.
This uses lispy tuple programming to avoid heterogenous broadcasts. It also breaks the computation into two pieces: promoting the eltypes of the arrays, and then adding the fill. This does require changing the result of one test, but the change appears to increase consistency.
This doesn't make it inferrable to a single concrete type, but it often gets it to a union of two such types.
| promote_type_withcolor(::Type{T}, ::Type{S}) where {T, S} = promote_type(T, S) | ||
| promote_type_withcolor(::Type{T}, ::Type{Union{}}) where T = T | ||
| promote_type_withcolor(::Type{Union{}}, ::Type{S}) where S = S | ||
| promote_type_withcolor(::Type{Union{}}, ::Type{Union{}}) = Union{} |
There was a problem hiding this comment.
These are designed to be specialized by ImageCore. Because CI runs ImageCore's tests, this will have test failures until ImageCore gets updated.
There was a problem hiding this comment.
I'm not sure the name is great, perhaps that should be changed.
Perhaps heterogeneous_promote_type or wrapped_promote_type (Colorant as a wrapper of number, and Union{Missing, T} as a wrapper of T)?
When called with different input array types, it doesn't seem necessary to specialize since the inference quality will be poor.
eed7153 to
93ff551
Compare
|
This drops the time to run the tests from ~18s to ~14s on my machine. |
93ff551 to
bf9eddc
Compare
|
For the test failures, note that it failed on the ImageCore test, which isn't surprising since ImageCore isn't compatible with version 0.3 of this package. It installed an old version of ImageCore (0.8.12) from before it depended on this package. |
|
I'm happy to separate |
|
I don't think it's necessary, as long as it's solid---we don't have to have zero inference failures (we can't), but I'd like to get rid of "egregious" cases. As long as we've done that, I'm fine having this in ImageCore if you think it makes sense. That said, can you briefly remind me of why it's better in ImageCore than ImageShow? I'm not sure I was paying attention when that decision was made. With regards to what should go in ImageCore, there's also this request: JuliaImages/ImageTransformations.jl#69 What do you think of these changes? Does it make it good enough? The part to check most carefully is this section: MosaicViews.jl/src/MosaicViews.jl Lines 418 to 436 in 861b20c The key change, aside from inferrability, is "opt-in" with respect to fixing any issue that |
There was a problem hiding this comment.
Everything looks good to me. My original version is not ideal(it simply works for common cases JuliaImages/ImageCore.jl#135) and I like your "sentinel" version more; it is easier to understand and maintain/extend. Thanks for the fix.
That said, can you briefly remind me of why it's better in ImageCore than ImageShow? I'm not sure I was paying attention when that decision was made.
I decided to move mosaicview into ImageCore because:
PaddedViewsis used byImageCoreto support color promotion(JuliaImages/ImageCore.jl#126), so addingMosaicViewsdoesn't add too much latency there.MosaicViewsis an enhanced version ofcats and is something "basic". (Or, enhanced version of Matlab'smontageandimshowpair)MosaicViewis a view, andImageCoreis a collection of traits and views.
| promote_type_withcolor(::Type{T}, ::Type{S}) where {T, S} = promote_type(T, S) | ||
| promote_type_withcolor(::Type{T}, ::Type{Union{}}) where T = T | ||
| promote_type_withcolor(::Type{Union{}}, ::Type{S}) where S = S | ||
| promote_type_withcolor(::Type{Union{}}, ::Type{Union{}}) = Union{} |
There was a problem hiding this comment.
I'm not sure the name is great, perhaps that should be changed.
Perhaps heterogeneous_promote_type or wrapped_promote_type (Colorant as a wrapper of number, and Union{Missing, T} as a wrapper of T)?
|
All that sounds good. Initially I was wondering if the view part was mostly fake ( OK, I'll finish this off and merge. Then on to ImageCore! |
|
One last thought: I think Should we call it EDIT: I'm talking specifically about the signatures EDIT2: the most recent commit adds that deprecation |
johnnychen94
left a comment
There was a problem hiding this comment.
After modifying the examples in README.md, it would be good enough to merge.
This package is part of ImageCore, and because ImageCore is essentially the foundation of JuliaImages my overall goal is to set a high bar on the "engineering quality" of all packages up through ImageCore. Good inferrability = good precompilability = low latency (and good runtime performance, of course) for anyone who is building stuff based on ImageCore.
This package was the source of the large majority of inference failures while running ImageCore's test suite. This doesn't eliminate all failures but it's a pretty huge step forward: in this package's tests, it cuts it from >350 inference failures to around 100. Splatting a vector-of-arrays accounts for a good chunk of the rest, and of course no one actually has to do that (just leave as a vector-of-arrays, or construct as a tuple in the first place), so overall this seems pretty solid now. The eltype inferrability in particular is much better.
This PR is the motivation for JuliaArrays/OffsetArrays.jl#189