summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2024-11-19 15:00:26 +0100
committerGitHub <noreply@github.com>2024-11-19 15:00:26 +0100
commit68aa712a3e51b2fb8596ba245dd440739be205c5 (patch)
tree509df7b21b3d4c55fd3c6fad5a4e210bdeb457c0
parent2e71bc640c1ccc273b7bc71f5791316ec1832157 (diff)
downloadspack-68aa712a3e51b2fb8596ba245dd440739be205c5.tar.gz
spack-68aa712a3e51b2fb8596ba245dd440739be205c5.tar.bz2
spack-68aa712a3e51b2fb8596ba245dd440739be205c5.tar.xz
spack-68aa712a3e51b2fb8596ba245dd440739be205c5.zip
solver: add a timeout handle for users (#47661)
This PR adds a configuration setting to allow setting time limits for concretization. For backward compatibility, the default is to set no time limit.
-rw-r--r--etc/spack/defaults/concretizer.yaml8
-rw-r--r--lib/spack/spack/schema/concretizer.py2
-rw-r--r--lib/spack/spack/solver/asp.py17
3 files changed, 26 insertions, 1 deletions
diff --git a/etc/spack/defaults/concretizer.yaml b/etc/spack/defaults/concretizer.yaml
index 8cce19ebab..eda51c09be 100644
--- a/etc/spack/defaults/concretizer.yaml
+++ b/etc/spack/defaults/concretizer.yaml
@@ -55,3 +55,11 @@ concretizer:
splice:
explicit: []
automatic: false
+ # Maximum time, in seconds, allowed for the 'solve' phase. If set to 0, there is no time limit.
+ timeout: 0
+ # If set to true, exceeding the timeout will always result in a concretization error. If false,
+ # the best (suboptimal) model computed before the timeout is used.
+ #
+ # Setting this to false yields unreproducible results, so we advise to use that value only
+ # for debugging purposes (e.g. check which constraints can help Spack concretize faster).
+ error_on_timeout: true
diff --git a/lib/spack/spack/schema/concretizer.py b/lib/spack/spack/schema/concretizer.py
index 4fba79fece..a81962a926 100644
--- a/lib/spack/spack/schema/concretizer.py
+++ b/lib/spack/spack/schema/concretizer.py
@@ -88,6 +88,8 @@ properties: Dict[str, Any] = {
"strategy": {"type": "string", "enum": ["none", "minimal", "full"]}
},
},
+ "timeout": {"type": "integer", "minimum": 0},
+ "error_on_timeout": {"type": "boolean"},
"os_compatible": {"type": "object", "additionalProperties": {"type": "array"}},
},
}
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index 5310c4e3a8..4b35a093b8 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -885,7 +885,22 @@ class PyclingoDriver:
solve_kwargs["on_unsat"] = cores.append
timer.start("solve")
- solve_result = self.control.solve(**solve_kwargs)
+ time_limit = spack.config.CONFIG.get("concretizer:timeout", -1)
+ error_on_timeout = spack.config.CONFIG.get("concretizer:error_on_timeout", True)
+ # Spack uses 0 to set no time limit, clingo API uses -1
+ if time_limit == 0:
+ time_limit = -1
+ with self.control.solve(**solve_kwargs, async_=True) as handle:
+ finished = handle.wait(time_limit)
+ if not finished:
+ specs_str = ", ".join(llnl.util.lang.elide_list([str(s) for s in specs], 4))
+ header = f"Spack is taking more than {time_limit} seconds to solve for {specs_str}"
+ if error_on_timeout:
+ raise UnsatisfiableSpecError(f"{header}, stopping concretization")
+ warnings.warn(f"{header}, using the best configuration found so far")
+ handle.cancel()
+
+ solve_result = handle.get()
timer.stop("solve")
# once done, construct the solve result