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 bug handling Adjoints in macros #1698

Merged
merged 6 commits into from Dec 29, 2018
Merged

Fix bug handling Adjoints in macros #1698

merged 6 commits into from Dec 29, 2018

Conversation

odow
Copy link
Member

@odow odow commented Dec 20, 2018

Not sure if this is the best way to achieve this, but it seems to work.

Closes #1667.

@odow odow requested a review from blegat December 20, 2018 20:29
@codecov
Copy link

codecov bot commented Dec 20, 2018

Codecov Report

Merging #1698 into master will decrease coverage by <.01%.
The diff coverage is 0%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1698      +/-   ##
==========================================
- Coverage   68.52%   68.51%   -0.01%     
==========================================
  Files          30       30              
  Lines        3867     3869       +2     
==========================================
+ Hits         2650     2651       +1     
- Misses       1217     1218       +1
Impacted Files Coverage Δ
src/parse_expr.jl 66.4% <0%> (-0.27%) ⬇️
src/macros.jl 84.18% <0%> (+0.02%) ⬆️

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 d32fce7...ee43d21. Read the comment docs.

@codecov
Copy link

codecov bot commented Dec 20, 2018

Codecov Report

Merging #1698 into master will increase coverage by 0.15%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1698      +/-   ##
==========================================
+ Coverage   68.52%   68.67%   +0.15%     
==========================================
  Files          30       30              
  Lines        3867     3943      +76     
==========================================
+ Hits         2650     2708      +58     
- Misses       1217     1235      +18
Impacted Files Coverage Δ
src/parse_expr.jl 66.66% <100%> (ø) ⬆️
src/quad_expr.jl 70.27% <0%> (-0.49%) ⬇️
src/macros.jl 84.15% <0%> (ø) ⬆️
src/aff_expr.jl 71.92% <0%> (+0.11%) ⬆️
src/objective.jl 95.23% <0%> (+1.48%) ⬆️
src/constraints.jl 71.85% <0%> (+3.35%) ⬆️

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 d32fce7...40a2580. Read the comment docs.

src/parse_expr.jl Outdated Show resolved Hide resolved
@blegat
Copy link
Member

blegat commented Dec 21, 2018

If you replace 0.0 here:
https://github.com/JuliaOpt/JuMP.jl/blob/b78da6727823b594ef020997e6e48c3e7d15ed90/src/parse_expr.jl#L98
By Val(false), the method called is now JuMP.destructive_add_with_reorder!(::Val{false}, ::Adjoint) which calls
https://github.com/JuliaOpt/JuMP.jl/blob/b78da6727823b594ef020997e6e48c3e7d15ed90/src/parse_expr.jl#L295
The broadcast still collects the adjoint into a matrix but overloading this one may be easier.
By the way, it seems like a bug that broadcasting an adjoint lead to collect.

…owering.

This is a work-around for a weird feature of Julia that doesn't propagate
adjoints properly through `.` broadcasts.
@odow
Copy link
Member Author

odow commented Dec 21, 2018

I don't really know what I'm doing because I haven't played around with the broadcasting stuff, but:

julia> f(x) = x' .+ 1
f (generic function with 1 method)

julia> g(x) = Broadcast.materialize(Broadcast.broadcast(+, adjoint(x), 1))
g (generic function with 1 method)

julia> x = [1, 2]
2-element Array{Int64,1}:
1
2

julia> f(x)
1×2 Array{Int64,2}:
2  3

julia> g(x)
1×2 LinearAlgebra.Adjoint{Int64,Array{Int64,1}}:
2  3

julia> @code_lowered f(x)
CodeInfo(
1 1%1 = Base.Broadcast.materialize                                       │
  │   %2 = Base.Broadcast.broadcasted                                       │
  │   %3 = (Base.adjoint)(x)                                                │
  │   %4 = (%2)(Main.:+, %3, 1)                                             │
  │   %5 = (%1)(%4)                                                         │
  └──      return %5                                                        │
)

julia> @code_lowered g(x)
CodeInfo(
1 1%1 = (Base.getproperty)(Main.Broadcast, :materialize)                 │
  │   %2 = (Base.getproperty)(Main.Broadcast, :broadcast)                   │
  │   %3 = (Main.adjoint)(x)                                                │
  │   %4 = (%2)(Main.:+, %3, 1)                                             │
  │   %5 = (%1)(%4)                                                         │
  └──      return %5                                                        │
)

Related issues: JuliaLang/julia#25671, JuliaArrays/AxisArrays.jl#131

src/parse_expr.jl Outdated Show resolved Hide resolved
@blegat
Copy link
Member

blegat commented Dec 21, 2018

It seems to be thank to this:
https://github.com/JuliaLang/julia/blob/163b0196b12a84143388fcc0037873ef68f0beec/stdlib/LinearAlgebra/src/adjtrans.jl#L185-L186
which was introduced in:
JuliaLang/julia#25083
A special method is defined for broadcast with Adjoint vectors and scalars.
However, it seems that .+ is lowered to broadcasted followed by materialize instead of broadcast so the method is not called.
I don't understand why it's not lowered to broadcast since it is basically equivalent:
https://github.com/JuliaLang/julia/blob/163b0196b12a84143388fcc0037873ef68f0beec/base/broadcast.jl#L707

test/macros.jl Outdated Show resolved Hide resolved
test/macros.jl Outdated Show resolved Hide resolved
@odow odow merged commit 00d400b into master Dec 29, 2018
@odow odow deleted the od/objective_bug branch December 29, 2018 03:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants