bugfix: spec_dict_to_json caches bottom-up; disable caching spliced specs#52665
Conversation
|
I'm not a fan of the iterative I would either write a proper DFS implementation in this module that treats Now it's a weird hybrid, and there shouldn't be comments about "bottom up" cause that's misleading. |
becker33
left a comment
There was a problem hiding this comment.
- _compute_specs_from_answer_set already has to figure out what the roots of the solve are. If we make the logic from there reusable (and still cache it on the Result object) we get the roots “for free”
- Spec._to_dict and friends are already compute hashes bottom-up and include build specs. To whatever extent they aren't bottom-up that's a performance problem in the non-forcing case that we should fix, instead of working around it here duplicating work.
Is there a reason we can't rework this to reuse that existing infrastructure, maybe with some additional arguments to pass the force argument to dependencies in Spec hashing methods?
I would think any performance work we need to do on the hashing ordering there would be good to do anyway (e.g. if we need to do a post-order traversal instead of a pre-order traversal to avoid needing to pass the force argument and then reverse the nodes into the dict).
|
Another option is to disable the feature for spliced specs and backport that. |
spec_dict_to_json should cache hashes bottom-upspec_dict_to_json caches bottom-up; disable caching spliced specs
d2af432 to
e34fce4
Compare
e34fce4 to
20779ce
Compare
20779ce to
b635297
Compare
|
@haampie ok, caching is disabled for spliced specs, and the traversal logic is simpler. I think this is a decent backport. the diff looks big but some code just moved into a try/finally block.
I looked at this, and it seemed very invasive given the number of places that need to be updated to pass along I am not convinced that hashing is the right way to key abstract specs in serialization, so that's another reason I didn't do the necessary surgery when refactoring the concretization cache. It would be nice if we could just use
I'm not sure I see where this relates to concretization caching (which needs to pair up specs and node ids).
I think the right near-term refactor here is to make |
b635297 to
3552060
Compare
3552060 to
ab72dba
Compare
… specs `spec_dict_to_json` avoids making yet another node identifier for specs by using DAG hashes, but it neglected to cache them bottom-up. If there are many abstract specs in a DAG/env/etc., this means we get exponential recomputation of hashes. This could cause extremely long concretization times for large DAGs. Also, spliced specs can potentially encounter a traversal bug where reused spliced specs can have dangling hashes. Avoid spliced specs for now and just disable caching for them since they are rare. `spec_dict_to_json` time for diamond DAGs before, with recomputation issues: ``` depth= 1 nodes= 4 paths=2 0.001s depth=14 nodes= 43 paths=16384 9.629s ... 😬 ``` After: ``` depth= 1 nodes= 4 paths=2 0.000s depth=14 nodes= 43 paths=16384 0.001s depth=39 nodes=118 paths=549755813888 0.004s ``` This is a minimal backport; a full refactor of `traverse_*` can go on `develop`, but this is intended to be low-risk for `1.2.2`. - [x] Cache hashes bottom-up in ``spec_dict_to_json`` using `traverse_nodes()` - [x] ``spec_dict_to_json`` now raises if it encounters spliced specs, and the result is not cached. - [x] Add a test. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Todd Gamblin <tgamblin@llnl.gov>
ab72dba to
98a25b4
Compare
|
Bit odd that SpecSyntaxError is not a SpecError 🤔 |
spec_dict_to_jsonavoids making yet another node identifier for specs by using DAG hashes, but it neglected to cache them bottom-up. If there are many abstract specs in a DAG/env/etc., this means we get exponential recomputation of hashes. This could cause extremely long concretization times for large DAGs.Also, spliced specs can potentially encounter a traversal bug where reused spliced specs can have dangling hashes. Avoid spliced specs for now and just disable caching for them since they are rare.
Effect on the E4S stack in CI:
See spack/spack-packages#5097.
spec_dict_to_jsontime for diamond DAGs before, with recomputation issues:After:
This is a minimal backport; a full refactor of
traverse_*can go ondevelop, but this is intended to be low-risk for1.2.2.spec_dict_to_jsonusingtraverse_nodes()spec_dict_to_jsonnow raises if it encounters spliced specs, and the result is not cached.