reduce input variants to only _used_ input variants#1968
reduce input variants to only _used_ input variants#1968minrk wants to merge 13 commits intoconda-forge:mainfrom
Conversation
before recomputing output metadata reduces get_used_vars time dramatically because input_variants can be several thousand items long to produce 10s of variants
4601c1e to
d4e0c9b
Compare
|
Thanks for this. I don't quite follow it and need to think on it a bit so I understand. I'm concerned the test suite may not catch all of the edge cases. |
|
Looks like it doesn't quite work in every case and tests catch it, despite working in all of the recipes I tested. I think perhaps conda-smithy needs to do its own detection of used vars and reduce them before passing them to cond-build's render. Because the vast majority of variants are never used in all conda-forge recipes (every recipe computes every variant for every input parameter across all of conda-forge before checking if anything will be used, and then caries this exploded matrix through the whole render process, accounting for ~90% of the remaining render time). I think the upstream PR is probably not going to work either: conda/conda-build#5392 In general, conda-build seems to assume that every input variant will be used, which doesn't match conda-forge where the input config is used for every package and has numerous unused dimensions which should eventually be dropped. |
|
Thanks. The detection of used variables is itself expensive and so we'll need to think on this a bit. |
saves a lot of time in render_recipe
just remove unused variants that add dimensionality, don't try to remove anything else
468c631 to
cd985dd
Compare
9b1a9a6 to
ffc2a07
Compare
|
The tests pass now, but reading carefully, I think this reduction must do exactly what But it's not all keys where it matters. The only case where this should be able to get the wrong answer requires:
The consequences of getting it wrong, however, are a missing pin and missing matrix dimension. There is a workaround where recipes can artificially ensure that the key is consumed at the top-level. I've actually had to do exactly this a number of times over the years in multi-output feedstocks, so I know it's doable, but it's not very nice when it is required. I'm not sure it happens anymore, so reintroducing a potential source of it isn't great. |
|
The upstream PR conda/conda-build#5392 no longer reduces the variant list because I don't understand what conda-build promises to do with unused variants. Instead it reduces the cost of a very large variant list, so I think it has a better chance of being acceptable. |
8520223 to
15e4e0f
Compare
beckermr
left a comment
There was a problem hiding this comment.
Looking good. Do we have a test that covers a multidimensional key only in an output? This seems like the relevant corner case given the discussion.
yes, I believe I have found a case where this will miss a variant: if a variable is only used in the build script of an output in a multi-output recipe, but nowhere in meta.yaml, it will be missed by |
beckermr
left a comment
There was a problem hiding this comment.
Looking at this again, I think in order to merge we need to do either one of the following two things
- Fix the code getting all used vars check so it is reliable
- Add a test showing exactly what fails and ensure we are ok with ignoring that case
|
Updated timings rerendering petsc4py (220 variants):
(The savings in conda/conda-build#5392 are mostly redundant with this PR, which applies the same reduction earlier, getting the benefit in more places). So this saves a lot less now that other optimizations have landed, if that enters into the decision for whether this is worth doing. |
|
Given the latest change, I think we can discard the len(1) > 1 check. Also, we need to add |
df502f9 to
471104c
Compare
|
I haven't removed the host:
- { mpi }does not result in the pin for the value of host:
- mpich # { mpi == 'mpich' }I can try to add a test for that tomorrow, if you think we should, or if that means we should hold off on this. One minute is a lot less dire to optimize than 30. |
before recomputing output metadata, which involves a number of expensive$O(\texttt{len(inputvariants)})$ operations.
reduces
get_used_varsandMetadata.copy()time dramatically becauseinput_variantscan be several thousand items long to produce 10s of variants, since it is the cartesian product of all possible variants across conda-forge, including every single unused combination.Combining this PR and the following upcoming optimizations to conda-build 24.7:
render time for the petsc4py feedstock, which has 13,824 input variants to produce 72 linux-64 builds, is reduced from over 30 minutes to 55 seconds to produce the same result:
Checklist
newsentry