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

Add support for generic number type #3385

Merged
merged 2 commits into from
Jul 23, 2023
Merged

Add support for generic number type #3385

merged 2 commits into from
Jul 23, 2023

Conversation

odow
Copy link
Member

@odow odow commented May 24, 2023

I figured I'd leave #3191 alone so we have a baseline in case anything got mucked up during the split of the PRs and all the various rebasing.

Tutorial: https://jump.dev/JuMP.jl/previews/PR3385/tutorials/conic/arbitrary_precision/

Closes #2025

@odow
Copy link
Member Author

odow commented May 24, 2023

@blegat this is a lot easier to review and see what is going on.

@odow odow added the Status: Needs developer call This should be discussed on a monthly developer call label May 24, 2023
@codecov
Copy link

codecov bot commented May 24, 2023

Codecov Report

Patch coverage: 98.80% and project coverage change: -0.06 ⚠️

Comparison is base (f220e9b) 97.97% compared to head (38e2d24) 97.91%.

❗ Current head 38e2d24 differs from pull request most recent head d5f9a7d. Consider uploading reports for the commit d5f9a7d to get more accurate results

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3385      +/-   ##
==========================================
- Coverage   97.97%   97.91%   -0.06%     
==========================================
  Files          34       34              
  Lines        4979     4993      +14     
==========================================
+ Hits         4878     4889      +11     
- Misses        101      104       +3     
Impacted Files Coverage Δ
src/copy.jl 96.19% <93.33%> (ø)
src/JuMP.jl 93.58% <93.75%> (-1.29%) ⬇️
src/macros.jl 98.40% <95.00%> (-0.23%) ⬇️
src/aff_expr.jl 97.28% <100.00%> (ø)
src/callbacks.jl 100.00% <100.00%> (ø)
src/constraints.jl 96.57% <100.00%> (+0.01%) ⬆️
src/feasibility_checker.jl 100.00% <100.00%> (ø)
src/file_formats.jl 100.00% <100.00%> (ø)
src/lp_sensitivity2.jl 97.79% <100.00%> (ø)
src/mutable_arithmetics.jl 88.34% <100.00%> (ø)
... and 9 more

... and 2 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

docs/src/manual/constraints.md Outdated Show resolved Hide resolved
@@ -587,7 +587,7 @@ function test_extension_SDP_errors(
"In `@constraint(model, [x 1; 1 -y] >= [1 x; x -2], PSDCone(), unknown_kw = 1)`:" *
" Unrecognized constraint building format. Tried to invoke " *
"`build_constraint(error, $(aff_str)[x - " *
"1 -x + 1; -x + 1 -y + 2], $(MOI.GreaterThan(0.0)), $(PSDCone()); unknown_kw = 1)`, but no " *
"1 -x + 1; -x + 1 -y + 2], $(MOI.GreaterThan(false)), $(PSDCone()); unknown_kw = 1)`, but no " *
Copy link
Member Author

Choose a reason for hiding this comment

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

Breaking feature 2: the fallback for a >= b is now a - b in GreaterThan(false) instead of a - b in GreaterThan(0.0). But I don't know if anyone is actually intercepting this method. And changes to the method dispatch are already potentially breaking. Extensions should be intercepting things higher up the call stack.

@odow odow mentioned this pull request May 25, 2023
4 tasks
@odow
Copy link
Member Author

odow commented May 25, 2023

docs/src/reference/variables.md Outdated Show resolved Hide resolved
src/nlp.jl Outdated Show resolved Hide resolved
src/nlp.jl Outdated Show resolved Hide resolved
docs/src/reference/variables.md Outdated Show resolved Hide resolved
@odow
Copy link
Member Author

odow commented May 25, 2023

LaTeX printing is broken

image

@odow
Copy link
Member Author

odow commented May 25, 2023

cc @goulart-paul, here's a demo with Clarabel's BigFloat arithmetic via JuMP:

https://jump.dev/JuMP.jl/previews/PR3385/tutorials/conic/arbitrary_precision/

@goulart-paul
Copy link

@odow : thanks for doing that. Should work also for BigFloat SDPs as of v0.5 too.

I suspect we could get it to work also with Rational{BigInt} types as in the subsequent example. It probably doesn't work now only because we have a lot of where{T <: AbstractFloat} bounds in the code, probably unnecessarily.

Would that be of interest?

@odow
Copy link
Member Author

odow commented May 25, 2023

It probably doesn't work now only because we have a lot of where{T <: AbstractFloat} bounds in the code, probably unnecessarily.

Yes. That was the next thing I tried, and I got stopped at AbstractFloat. That's the only reason I pulled in CDDLib, so if Clarabel can support rational then great!

(I'm not sure it's that simple though? The rational simplex walks the vertices, so everything is always rational. An interior point type thing in rational arithmetic seems much harder? Maybe I'm missing something obvious.)

@goulart-paul
Copy link

goulart-paul commented May 25, 2023

Good point - entirely possible that the solver would misbehave. I was thinking only at the "will it crash" sort of level.

We will give it at a try anyway.

Edit: I could get it to work in the sense that it would do an iteration and not crash, but the results are ugly and it's extremely slow. I think it is not really useable with Rationals for the reason posited by @odow above.

@odow
Copy link
Member Author

odow commented May 26, 2023

Another data point: this works with MiniZinc and Int coefficients:

julia> using JuMP

julia> import MiniZinc

julia> model = GenericModel{Int}(() -> MiniZinc.Optimizer{Int}(MiniZinc.Chuffed()))
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: EMPTY_OPTIMIZER
Solver name: MiniZinc

julia> @variable(model, 1 <= x[1:3] <= 3, Int)
3-element Vector{GenericVariableRef{Int64}}:
 x[1]
 x[2]
 x[3]

julia> @variable(model, z[1:2], Bin)
2-element Vector{GenericVariableRef{Int64}}:
 z[1]
 z[2]

julia> @constraint(model, z[1] <--> {[x[1], x[2]] in MOI.AllDifferent(2)})
z[1] <--> {[x[1], x[2]]  MathOptInterface.AllDifferent(2)}

julia> @constraint(model, z[2] <--> {[x[2], x[3]] in MOI.AllDifferent(2)})
z[2] <--> {[x[2], x[3]]  MathOptInterface.AllDifferent(2)}

julia> @constraint(model, z[1] + z[2] == 1)
z[1] + z[2] = 1

julia> optimize!(model)
Warning: included file "count.mzn" overrides a global constraint file from the standard library. This is deprecated. For a solver-specific redefinition of a global constraint, override "fzn_<global>.mzn" instead.

Warning: included file "global_cardinality_low_up.mzn" overrides a global constraint file from the standard library. This is deprecated. For a solver-specific redefinition of a global constraint, override "fzn_<global>.mzn" instead.


julia> value.(x)
3-element Vector{Int64}:
 2
 3
 3

julia> value.(z)
2-element Vector{Int64}:
 1
 0

Base automatically changed from bl/test_boiler_generic to bl/nonbreaking_generic_number_type June 2, 2023 03:59
@odow odow force-pushed the bl/nonbreaking_generic_number_type branch 2 times, most recently from 4d59a40 to 34a9b14 Compare June 2, 2023 04:36
@odow odow force-pushed the bl/nonbreaking_generic_number_type branch from 34a9b14 to 036d014 Compare June 4, 2023 23:51
@odow odow force-pushed the bl/nonbreaking_generic_number_type branch 2 times, most recently from 372f638 to ebe5b47 Compare June 11, 2023 21:54
@odow odow force-pushed the bl/nonbreaking_generic_number_type branch 3 times, most recently from 1661808 to af1eda9 Compare June 26, 2023 04:39
@odow odow force-pushed the bl/nonbreaking_generic_number_type branch from af1eda9 to e9bdd50 Compare June 26, 2023 22:20
@odow odow force-pushed the bl/nonbreaking_generic_number_type branch from 7718087 to 43178a1 Compare June 26, 2023 23:33
@odow
Copy link
Member Author

odow commented Jun 27, 2023

Okay, I've reverted to the GenericModel{T}() syntax.

@odow odow requested review from blegat and mlubin June 27, 2023 01:35
@odow
Copy link
Member Author

odow commented Jun 27, 2023

Base automatically changed from bl/nonbreaking_generic_number_type to master June 28, 2023 02:45
@odow odow force-pushed the od/generic-number-type branch 2 times, most recently from 80957a6 to e504b55 Compare June 28, 2023 02:49
@odow
Copy link
Member Author

odow commented Jun 28, 2023

This is ready for review now that it is rebased on master.

@odow
Copy link
Member Author

odow commented Jul 20, 2023

@mlubin this would be nice to get in before JuMP-dev?

Copy link
Member

@mlubin mlubin left a comment

Choose a reason for hiding this comment

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

That was easy to review. Good idea splitting into smaller parts.

end

function model_convert(model::AbstractModel, α::Number)
T = value_type(typeof(model))
Copy link
Member

Choose a reason for hiding this comment

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

Is querying value_type in these functions as efficient as explicitly grabbing T from the from the AbstractModel{T}? This code is in the hot path from what I can tell.

Copy link
Member Author

Choose a reason for hiding this comment

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

Note that this is AbstractModel, not GenericModel{T}.

This is a little slower (extra function calls, etc), but not by much.

julia> using JuMP

julia> model = Model();

julia> f(m) = value_type(typeof(model))
f (generic function with 1 method)

julia> g(m::GenericModel{T}) where {T} = T
g (generic function with 1 method)

julia> @code_native f(model)
	.section	__TEXT,__text,regular,pure_instructions
; ┌ @ REPL[3]:1 within `f'
	subq	$24, %rsp
	movq	%rsi, 16(%rsp)
	movabsq	$5387182984, %rax               ## imm = 0x14119E388
	movq	(%rax), %rax
	movq	-8(%rax), %rax
	andq	$-16, %rax
	movq	%rax, 8(%rsp)
	movabsq	$jl_apply_generic, %rax
	movabsq	$5686588464, %rdi               ## imm = 0x152F27430
	leaq	8(%rsp), %rsi
	movl	$1, %edx
	callq	*%rax
	addq	$24, %rsp
	retq
; └

julia> @code_native g(model)
	.section	__TEXT,__text,regular,pure_instructions
; ┌ @ REPL[9]:1 within `g'
	movq	%rsi, -8(%rsp)
	movabsq	$jl_system_image_data, %rax
	retq
; └

julia> @time f(model)
  0.000007 seconds (2 allocations: 128 bytes)
Float64

julia> @time f(model)
  0.000006 seconds (2 allocations: 128 bytes)
Float64

julia> @time g(model)
  0.000003 seconds
Float64

julia> @time g(model)
  0.000003 seconds
Float64

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh. I can't type. They're exactly the same:

julia> using JuMP

julia> model = Model();

julia> f(m) = value_type(typeof(m))
f (generic function with 1 method)

julia> g(m::GenericModel{T}) where {T} = T
g (generic function with 1 method)

julia> @code_native f(model)
	.section	__TEXT,__text,regular,pure_instructions
; ┌ @ REPL[10]:1 within `f'
	movq	%rsi, -8(%rsp)
	movabsq	$jl_system_image_data, %rax
	retq
; └

julia> @code_native g(model)
	.section	__TEXT,__text,regular,pure_instructions
; ┌ @ REPL[11]:1 within `g'
	movq	%rsi, -8(%rsp)
	movabsq	$jl_system_image_data, %rax
	retq
; └

blegat and others added 2 commits July 21, 2023 10:27
Co-authored-by: Benoît Legat <benoit.legat@gmail.com>
@odow
Copy link
Member Author

odow commented Jul 22, 2023

@blegat it's been a couple of weeks, so still good to go?

Copy link
Member

@blegat blegat left a comment

Choose a reason for hiding this comment

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

Yes I'm good with the changes since my last review

@mlubin mlubin merged commit d0be19b into master Jul 23, 2023
9 of 11 checks passed
@mlubin mlubin deleted the od/generic-number-type branch July 23, 2023 16:48
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.

Generic numeric type in JuMP
4 participants