Skip to content

Commit 470d68b

Browse files
committed
Add the OPAMSOLVERTOLERANCE environment variable to allow users to fix solver timeouts for good
1 parent f80c027 commit 470d68b

13 files changed

+42
-11
lines changed

doc/pages/Tricks.md

+1
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ The following sequence of commands tries to install as much packages as possible
150150
opam update
151151
opam switch create . ocaml-base-compiler.$(VERSION)
152152
export OPAMSOLVERTIMEOUT=3600
153+
export OPAMSOLVERTOLERANCE=1.0
153154
opam list --available -s | xargs opam install --best-effort --yes
154155
# Be patient
155156
```

src/client/opamArg.ml

+10
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,16 @@ let environment_variables =
186186
"change the time allowance of the solver. Default is %.1f, set to 0 \
187187
for unlimited. Note that all solvers may not support this option."
188188
(OpamStd.Option.default 0. OpamSolverConfig.(default.solver_timeout)));
189+
"SOLVERTOLERANCE", cli_from cli2_4, (fun v -> SOLVERTOLERANCE (env_float v)),
190+
(Printf.sprintf
191+
"changes the tolerance towards the solver choosing an unoptimized \
192+
solution (i.e. might pull outdated packages). Typical values range \
193+
from 0.0 (best solution known to the solver) to 1.0 (unoptimized \
194+
solution). Default is %.1f. This option is useful in case the solver \
195+
can't find a solution in a reasonable time \
196+
(see $(b,\\$OPAMSOLVERTIMEOUT)). Note that all solvers may not \
197+
support this option."
198+
(OpamStd.Option.default 0. OpamSolverConfig.default.solver_tolerance));
189199
"UPGRADECRITERIA", cli_original,
190200
(fun v -> UPGRADECRITERIA (env_string v)),
191201
"specifies user $(i,preferences) for dependency solving when performing \

src/client/opamClientConfig.mli

+1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ val opam_init:
146146
?solver_preferences_fixup:string option Lazy.t ->
147147
?solver_preferences_best_effort_prefix: string option Lazy.t ->
148148
?solver_timeout:float option ->
149+
?solver_tolerance:float option ->
149150
?solver_allow_suboptimal:bool ->
150151
?cudf_trim:string option ->
151152
?dig_depth:int ->

src/solver/opamBuiltin0install.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ let parse_criteria criteria =
123123
in
124124
parse default (OpamCudfCriteria.of_string criteria)
125125

126-
let call ~criteria ?timeout:_ (preamble, universe, request) =
126+
let call ~criteria ?timeout:_ ?tolerance:_ (preamble, universe, request) =
127127
let {
128128
drop_installed_packages;
129129
prefer_oldest;

src/solver/opamBuiltinMccs.dummy.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ module S = struct
2828
crit_best_effort_prefix = None;
2929
}
3030

31-
let call ~criteria:_ ?timeout:_ _cudf =
31+
let call ~criteria:_ ?timeout:_ ?tolerance:_ _cudf =
3232
failwith "This opam was compiled without a solver built in"
3333
end
3434

src/solver/opamBuiltinMccs.real.ml

+3-2
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,16 @@ let default_criteria = {
3131
crit_best_effort_prefix = Some "+count[opam-query:,false],";
3232
}
3333

34-
let call solver_backend ext ~criteria ?timeout cudf =
34+
let call solver_backend ext ~criteria ?timeout ?tolerance cudf =
3535
let solver = match solver_backend, ext with
3636
| `LP _, Some ext -> `LP ext
3737
| _ -> solver_backend
3838
in
3939
match
4040
Mccs.resolve_cudf
4141
~solver
42-
~verbose:OpamCoreConfig.(abs !r.debug_level >= 2)
42+
?mip_gap:tolerance
43+
~verbosity:(!OpamCoreConfig.r.debug_level - 1) (* *)
4344
?timeout criteria cudf
4445
with
4546
| None -> raise Dose_common.CudfSolver.Unsat

src/solver/opamBuiltinZ3.dummy.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ let default_criteria = {
2727
crit_best_effort_prefix = None;
2828
}
2929

30-
let call ~criteria:_ ?timeout:_ _cudf =
30+
let call ~criteria:_ ?timeout:_ ?tolerance:_ _cudf =
3131
failwith "This opam was compiled without the Z3 solver built in"

src/solver/opamBuiltinZ3.real.ml

+2-1
Original file line numberDiff line numberDiff line change
@@ -382,13 +382,14 @@ let extract_solution_packages universe opt =
382382
[]
383383
| None -> failwith "no model ??"
384384

385-
let call ~criteria ?timeout (preamble, universe, _ as cudf) =
385+
let call ~criteria ?timeout ?tolerance:_ (preamble, universe, _ as cudf) =
386386
(* try *)
387387
log "Generating problem...";
388388
let cfg = match timeout with
389389
| None -> []
390390
| Some secs -> ["timeout", string_of_int (int_of_float (1000. *. secs))]
391391
in
392+
(* TODO: use tolerance. Maybe the rlimit cfg option + intermediate solution could be used *)
392393
let ctx = {
393394
z3 = Z3.mk_context cfg;
394395
pkgs = Hashtbl.create 2731;

src/solver/opamCudf.ml

+5-2
Original file line numberDiff line numberDiff line change
@@ -1595,9 +1595,12 @@ let call_external_solver ~version_map univ req =
15951595
let msg =
15961596
Printf.sprintf
15971597
"Sorry, resolution of the request timed out.\n\
1598-
Try to specify a more precise request, use a different solver, or \
1599-
increase the allowed time by setting OPAMSOLVERTIMEOUT to a bigger \
1598+
Try to specify a more precise request, use a different solver, \
1599+
increase the tolerance for unoptimized solutions by setting \
1600+
OPAMSOLVERTOLERANCE to a bigger value (currently, it is set to %.1f) \
1601+
or increase the allowed time by setting OPAMSOLVERTIMEOUT to a bigger \
16001602
value (currently, it is set to %.1f seconds)."
1603+
OpamSolverConfig.(OpamStd.Option.default 0. !r.solver_tolerance)
16011604
OpamSolverConfig.(OpamStd.Option.default 0. !r.solver_timeout)
16021605
in
16031606
raise (Solver_failure msg)

src/solver/opamCudfSolver.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ module type ExternalArg = sig
2727
val default_criteria: criteria_def
2828
end
2929

30-
let call_external_solver command ~criteria ?timeout (_, universe,_ as cudf) =
30+
let call_external_solver command ~criteria ?timeout ?tolerance:_ (_, universe,_ as cudf) =
3131
let solver_in =
3232
OpamFilename.of_string (OpamSystem.temp_file "solver-in") in
3333
let solver_out =

src/solver/opamCudfSolverSig.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ module type S = sig
3838
it's only run if the solver returns unsat, to extract the explanations. *)
3939

4040
val call:
41-
criteria:string -> ?timeout:float -> Cudf.cudf ->
41+
criteria:string -> ?timeout:float -> ?tolerance:float -> Cudf.cudf ->
4242
Cudf.preamble option * Cudf.universe
4343

4444
end

src/solver/opamSolverConfig.ml

+12-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ module E = struct
2323
| PREPRO of bool option
2424
| SOLVERALLOWSUBOPTIMAL of bool option
2525
| SOLVERTIMEOUT of float option
26+
| SOLVERTOLERANCE of float option
2627
| UPGRADECRITERIA of string option
2728
| USEINTERNALSOLVER of bool option
2829
| VERSIONLAGPOWER of int option
@@ -42,6 +43,7 @@ module E = struct
4243
let solverallowsuboptimal =
4344
value (function SOLVERALLOWSUBOPTIMAL b -> b | _ -> None)
4445
let solvertimeout = value (function SOLVERTIMEOUT f -> f | _ -> None)
46+
let solvertolerance = value (function SOLVERTOLERANCE f -> f | _ -> None)
4547
let useinternalsolver = value (function USEINTERNALSOLVER b -> b | _ -> None)
4648
let upgradecriteria = value (function UPGRADECRITERIA s -> s | _ -> None)
4749
let versionlagpower = value (function VERSIONLAGPOWER i -> i | _ -> None)
@@ -59,6 +61,7 @@ type t = {
5961
solver_preferences_fixup: string option Lazy.t;
6062
solver_preferences_best_effort_prefix: string option Lazy.t;
6163
solver_timeout: float option;
64+
solver_tolerance: float option;
6265
solver_allow_suboptimal: bool;
6366
cudf_trim: string option;
6467
dig_depth: int;
@@ -75,6 +78,7 @@ type 'a options_fun =
7578
?solver_preferences_fixup:string option Lazy.t ->
7679
?solver_preferences_best_effort_prefix:string option Lazy.t ->
7780
?solver_timeout:float option ->
81+
?solver_tolerance:float option ->
7882
?solver_allow_suboptimal:bool ->
7983
?cudf_trim:string option ->
8084
?dig_depth:int ->
@@ -95,6 +99,7 @@ let default =
9599
solver_preferences_fixup = lazy None;
96100
solver_preferences_best_effort_prefix = lazy None;
97101
solver_timeout = Some 60.;
102+
solver_tolerance = Some 0.0;
98103
solver_allow_suboptimal = true;
99104
cudf_trim = None;
100105
dig_depth = 2;
@@ -111,6 +116,7 @@ let setk k t
111116
?solver_preferences_fixup
112117
?solver_preferences_best_effort_prefix
113118
?solver_timeout
119+
?solver_tolerance
114120
?solver_allow_suboptimal
115121
?cudf_trim
116122
?dig_depth
@@ -133,6 +139,8 @@ let setk k t
133139
solver_preferences_best_effort_prefix;
134140
solver_timeout =
135141
t.solver_timeout + solver_timeout;
142+
solver_tolerance =
143+
t.solver_tolerance + solver_tolerance;
136144
solver_allow_suboptimal =
137145
t.solver_allow_suboptimal + solver_allow_suboptimal;
138146
cudf_trim = t.cudf_trim + cudf_trim;
@@ -193,6 +201,8 @@ let initk k =
193201
E.besteffortprefixcriteria () >>| fun c -> (lazy (Some c)) in
194202
let solver_timeout =
195203
E.solvertimeout () >>| fun f -> if f <= 0. then None else Some f in
204+
let solver_tolerance =
205+
E.solvertolerance () >>| fun f -> if f <= 0. then None else Some f in
196206
setk (setk (fun c -> r := with_auto_criteria c; k)) !r
197207
~cudf_file:(E.cudffile ())
198208
~solver
@@ -202,6 +212,7 @@ let initk k =
202212
?solver_preferences_fixup:fixup_criteria
203213
?solver_preferences_best_effort_prefix:best_effort_prefix_criteria
204214
?solver_timeout
215+
?solver_tolerance
205216
?solver_allow_suboptimal:(E.solverallowsuboptimal ())
206217
~cudf_trim:(E.cudftrim ())
207218
?dig_depth:(E.digdepth ())
@@ -253,6 +264,6 @@ let call_solver ~criteria cudf =
253264
OpamConsole.log "SOLVER" "Calling solver %s with criteria %s"
254265
(OpamCudfSolver.get_name (module S)) criteria;
255266
let chrono = OpamConsole.timer () in
256-
let r = S.call ~criteria ?timeout:(!r.solver_timeout) cudf in
267+
let r = S.call ~criteria ?timeout:(!r.solver_timeout) ?tolerance:(!r.solver_tolerance) cudf in
257268
OpamConsole.log "SOLVER" "External solver took %.3fs" (chrono ());
258269
r

src/solver/opamSolverConfig.mli

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ module E : sig
2525
| PREPRO of bool option
2626
| SOLVERALLOWSUBOPTIMAL of bool option
2727
| SOLVERTIMEOUT of float option
28+
| SOLVERTOLERANCE of float option
2829
| UPGRADECRITERIA of string option
2930
| USEINTERNALSOLVER of bool option
3031
| VERSIONLAGPOWER of int option
@@ -40,6 +41,7 @@ type t = private {
4041
solver_preferences_fixup: string option Lazy.t;
4142
solver_preferences_best_effort_prefix: string option Lazy.t;
4243
solver_timeout: float option;
44+
solver_tolerance: float option;
4345
solver_allow_suboptimal: bool;
4446
cudf_trim: string option;
4547
dig_depth: int;
@@ -56,6 +58,7 @@ type 'a options_fun =
5658
?solver_preferences_fixup:string option Lazy.t ->
5759
?solver_preferences_best_effort_prefix:string option Lazy.t ->
5860
?solver_timeout:float option ->
61+
?solver_tolerance:float option ->
5962
?solver_allow_suboptimal:bool ->
6063
?cudf_trim:string option ->
6164
?dig_depth:int ->

0 commit comments

Comments
 (0)