Skip to content

Commit e592c17

Browse files
authored
Merge pull request #5062 from google/mizux/julia
julia: export from google3
2 parents e535af6 + 949eece commit e592c17

File tree

12 files changed

+208
-72
lines changed

12 files changed

+208
-72
lines changed

ortools/julia/ORTools.jl/Project.toml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,21 @@ version = "0.0.1"
55
[deps]
66
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
77
ORToolsGenerated = "6b269722-41d3-11ee-be56-0242ac120002"
8-
ORTools_jll = "717719f8-c30c-5086-8f3c-70cd6a1e3a46"
98
ProtoBuf = "3349acd9-ac6a-5e09-bcdb-63829b23a429"
109
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1110

11+
[weakdeps]
12+
ORTools_jll = "717719f8-c30c-5086-8f3c-70cd6a1e3a46"
13+
ORToolsBinaries = "594ad865-6a17-49ee-8f22-76ed020c7c08"
14+
15+
[extensions]
16+
ORToolsJllExt = "ORTools_jll"
17+
ORToolsBinariesExt = "ORToolsBinaries"
18+
1219
[compat]
1320
julia = "1.9"
1421
ORTools_jll = "9.14.0"
22+
ORToolsBinaries = "0.0.1"
1523
ORToolsGenerated = "0.0.2"
1624
ProtoBuf = "1.0.15"
1725
MathOptInterface = "1.42.0"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module ORToolsBinariesExt
2+
3+
using ORTools
4+
using ORToolsBinaries
5+
6+
function __init__()
7+
ORTools.set_library(ORToolsBinaries.libortools)
8+
@info "ORTools.jl loaded ORToolsBinaries: $(ORToolsBinaries.libortools)"
9+
end
10+
11+
end
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module ORToolsJllExt
2+
3+
using ORTools
4+
using ORTools_jll
5+
6+
function __init__()
7+
ORTools.set_library(ORTools_jll.libortools)
8+
@info "ORTools.jl loaded ORTools_jll: $(ORTools_jll.libortools)"
9+
end
10+
11+
end

ortools/julia/ORTools.jl/src/ORTools.jl

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,39 @@
11
module ORTools
22

33
import MathOptInterface as MOI
4-
using ORTools_jll
4+
5+
# Path to the OR-Tools shared library.
6+
const libortools = Ref{String}("")
7+
8+
# Set the library path to be used by the C wrapper. This function is mostly
9+
# intended for use by the extension packages.
10+
#
11+
# If you want to use a custom library, call this function with the path to the
12+
# library before using any other function in this package (technically, any
13+
# function that uses the C APIs like `solve`).
14+
function set_library(path::String)
15+
libortools[] = path
16+
return
17+
end
18+
19+
function __init__()
20+
if Base.find_package("ORTools_jll") === nothing &&
21+
Base.find_package("ORToolsBinaries") === nothing
22+
# TODO(user): update when we support remote solves, it should still be
23+
# a warning, but the package will work (albeit only locally).
24+
@warn "Neither ORTools_jll nor ORToolsBinaries is installed. Install one " *
25+
"of them to use OR-Tools. ORTools.jl will not work without either. " *
26+
"Import one of these two packages."
27+
# For the reader: when the two are installed and imported, the one that gets
28+
# used is the last one.
29+
end
30+
end
531

632
# Lower level C-dependency.
7-
include("c_wrapper/c_wrapper.jl")
8-
# MOI Wrappers and related utils.
33+
include("c_wrapper/utils.jl")
34+
include("c_wrapper/cpsat.jl")
35+
include("c_wrapper/math_opt.jl")
36+
# MOI-level wrappers.
937
include("moi_wrapper/utils.jl")
1038
include("moi_wrapper/Type_wrappers.jl")
1139
include("moi_wrapper/MOI_wrapper.jl")

ortools/julia/ORTools.jl/src/c_wrapper/c_wrapper.jl

Lines changed: 0 additions & 59 deletions
This file was deleted.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Keep this file in sync with sat/c_api/cp_solver_c.h.
2+
3+
function SolveCpModelWithParameters(
4+
creq, creq_len, cparams, cparams_len, cres, cres_len
5+
)
6+
_check_lib_loaded()
7+
return ccall(
8+
(:SolveCpModelWithParameters, libortools[]),
9+
Cvoid,
10+
(
11+
Ptr{Cvoid},
12+
Cint,
13+
Ptr{Cvoid},
14+
Cint,
15+
Ptr{Ptr{Cvoid}},
16+
Ptr{Cint},
17+
),
18+
creq,
19+
creq_len,
20+
cparams,
21+
cparams_len,
22+
cres,
23+
cres_len,
24+
)
25+
end
26+
27+
function SolveCpNewEnv()
28+
_check_lib_loaded()
29+
return ccall((:SolveCpNewEnv, libortools[]), Ptr{Cvoid}, ())
30+
end
31+
32+
function SolveCpDestroyEnv(cenv)
33+
_check_lib_loaded()
34+
return ccall((:SolveCpDestroyEnv, libortools[]), Cvoid, (Ptr{Cvoid},), cenv)
35+
end
36+
37+
function SolveCpStopSearch(cenv)
38+
_check_lib_loaded()
39+
return ccall((:SolveCpStopSearch, libortools[]), Cvoid, (Ptr{Cvoid},), cenv)
40+
end
41+
42+
function SolveCpInterruptible(
43+
cenv, creq, creq_len, cparams, cparams_len, cres, cres_len
44+
)
45+
_check_lib_loaded()
46+
return ccall(
47+
(:SolveCpInterruptible, libortools[]),
48+
Cvoid,
49+
(
50+
Ptr{Cvoid},
51+
Ptr{Cvoid},
52+
Cint,
53+
Ptr{Cvoid},
54+
Cint,
55+
Ptr{Ptr{Cvoid}},
56+
Ptr{Cint},
57+
),
58+
cenv,
59+
creq,
60+
creq_len,
61+
cparams,
62+
cparams_len,
63+
cres,
64+
cres_len,
65+
)
66+
end
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Keep this file in sync with math_opt/core/c_api/solver.h.
2+
3+
# There is no need to explicitly have a `mutable struct MathOptInterrupter`
4+
# on the Julia side, as it's only an opaque pointer for this API.
5+
6+
function MathOptNewInterrupter()
7+
_check_lib_loaded()
8+
return ccall((:MathOptNewInterrupter, libortools[]), Ptr{Cvoid}, ())
9+
end
10+
11+
function MathOptFreeInterrupter(ptr)
12+
_check_lib_loaded()
13+
return ccall(
14+
(:MathOptFreeInterrupter, libortools[]), Cvoid, (Ptr{Cvoid},), ptr)
15+
end
16+
17+
function MathOptInterrupt(ptr)
18+
_check_lib_loaded()
19+
return ccall((:MathOptInterrupt, libortools[]), Cvoid, (Ptr{Cvoid},), ptr)
20+
end
21+
22+
function MathOptIsInterrupted(ptr)
23+
_check_lib_loaded()
24+
return ccall((:MathOptIsInterrupted, libortools[]), Cint, (Ptr{Cvoid},), ptr)
25+
end
26+
27+
function MathOptFree(ptr)
28+
_check_lib_loaded()
29+
return ccall((:MathOptFree, libortools[]), Cvoid, (Ptr{Cvoid},), ptr)
30+
end
31+
32+
function MathOptSolve(
33+
model,
34+
model_size,
35+
solver_type,
36+
interrupter,
37+
solve_result,
38+
solve_result_size,
39+
status_msg,
40+
)
41+
_check_lib_loaded()
42+
return ccall(
43+
(:MathOptSolve, libortools[]),
44+
Cint,
45+
(
46+
Ptr{Cvoid},
47+
Csize_t,
48+
Cint,
49+
Ptr{Cvoid},
50+
Ptr{Ptr{Cvoid}},
51+
Ptr{Csize_t},
52+
Ptr{Ptr{Cchar}},
53+
),
54+
model,
55+
model_size,
56+
solver_type,
57+
interrupter,
58+
solve_result,
59+
solve_result_size,
60+
status_msg,
61+
)
62+
end
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
function _check_lib_loaded()
2+
# If `libortools[]` returns an invalid path, `ccall` will fail, with an
3+
# error message along the lines of:
4+
# ERROR: could not load library "something"
5+
# This should not be possible with `ORTools_jll.jl` or `ORToolsBinaries.jl`,
6+
# but entirely possible if the user is using `ORTools.set_library` directly.
7+
# Hence, no specific check for the library that is loaded.
8+
if libortools[] == ""
9+
@error(
10+
"No ORTools binaries loaded. Call `import ORTools_jll` or " *
11+
"`import ORToolsBinaries` first to load the OR-Tools binaries.",
12+
)
13+
end
14+
end

ortools/julia/ORTools.jl/src/moi_wrapper/CPSat_wrapper.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ function MOI.get(optimizer::CPSATOptimizer, param::MOI.RawOptimizerAttribute)
157157
return getfield!(optimizer.parameters, Symbol(param.name))
158158
end
159159

160-
MOI.supports(model::Optimizer, param::MOI.RawOptimizerAttribute) = true
160+
MOI.supports(model::CPSATOptimizer, param::MOI.RawOptimizerAttribute) = true
161161

162162

163163
"""

ortools/julia/ORTools.jl/src/moi_wrapper/MathOpt_wrapper.jl

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,22 +2038,17 @@ function MOI.get(model::Optimizer, ::MOI.TerminationStatus)::MOI.TerminationStat
20382038
elseif model.solve_result.termination.limit == LimitProto.LIMIT_UNDETERMINED
20392039
# TODO: b/411325865 Follow up on support for LIMIT_UNDETERMINED in MOI.jl
20402040
# A fallback as there's currently no associated MOI.LIMIT_* that can represent this.
2041-
@info "The underlying solver does not expose which limit was reached and the actual limit is LIMIT_UNDETERMINED " \
2042-
"However, LIMIT_UNDETERMINED is not associated with a MOI.LIMIT_* hence the returned LIMIT is MOI.OTHER_LIMIT."
2041+
@info "The underlying solver does not expose which limit was reached and the actual limit is LIMIT_UNDETERMINED. However, LIMIT_UNDETERMINED is not associated with a MOI.LIMIT_* hence the returned LIMIT is MOI.OTHER_LIMIT."
20432042
return MOI.OTHER_LIMIT
20442043
elseif model.solve_result.termination.limit == LimitProto.LIMIT_CUTOFF
20452044
# TODO: b/411328356 Follow up on support for LIMIT_CUTOFF in MOI.jl
20462045
# A fallback as there's currently no associated MOI.LIMIT_* that can represent this.
2047-
@info "The solver was run with a cutoff on the objective, indicating that the user did not want any solution " \
2048-
"worse than the cutoff, and the solver concluded there were no solutions at least as good as the cutoff. " \
2049-
"Typically no further solution information is provided. The actual limit is LIMIT_CUTOFF. " \
2050-
"However, LIMIT_CUTOFF is not associated with a MOI.LIMIT_* hence the returned LIMIT is MOI.OTHER_LIMIT."
2046+
@info "The solver was run with a cutoff on the objective, indicating that the user did not want any solution worse than the cutoff, and the solver concluded there were no solutions at least as good as the cutoff. Typically no further solution information is provided. The actual limit is LIMIT_CUTOFF. However, LIMIT_CUTOFF is not associated with a MOI.LIMIT_* hence the returned LIMIT is MOI.OTHER_LIMIT."
20512047
return MOI.OTHER_LIMIT
20522048
else
20532049
# TODO: b/411328207 Add attribute to capture more information about the limit when LIMIT_UNSPECIFIED is the returned limit.
20542050
# The else bit falls back to MOI.LIMIT_UNSPECIFIED if the termination reason wasn't TERMINATION_REASON_OPTIMAL
2055-
@info "The solver terminated but not from a limit and the actual limit is LIMIT_UNSPECIFIED, which is used as a null. " \
2056-
"However, LIMIT_UNSPECIFIED is not associated with a MOI.LIMIT_* hence the returned LIMIT is MOI.OTHER_LIMIT."
2051+
@info "The solver terminated but not from a limit and the actual limit is LIMIT_UNSPECIFIED, which is used as a null. However, LIMIT_UNSPECIFIED is not associated with a MOI.LIMIT_* hence the returned LIMIT is MOI.OTHER_LIMIT."
20572052
return MOI.OTHER_LIMIT
20582053
end
20592054
end

0 commit comments

Comments
 (0)