Skip to content

concretizer: option to disable compiler mixing between runtime deps#51135

Merged
scheibelp merged 69 commits intospack:developfrom
scheibelp:disable-compiler-mixing2
Oct 30, 2025
Merged

concretizer: option to disable compiler mixing between runtime deps#51135
scheibelp merged 69 commits intospack:developfrom
scheibelp:disable-compiler-mixing2

Conversation

@scheibelp
Copy link
Copy Markdown
Member

@scheibelp scheibelp commented Aug 10, 2025

You can set

concretizer:
  compiler_mixing: false

then e.g.:

$ spack spec chai%c=oneapi ^umpire%c=gcc
==> Error: failed to concretize `chai %c=oneapi ^umpire %c=gcc` for the following reasons:
     1. Compiler mixing is disabled

(even with this setting on, mixing is allowed when a dependency is an external, and only enforced within transitive link run/tree, i.e. the root unification set)

TODOs

@scheibelp scheibelp changed the title Disable compiler mixing Disable compiler mixing between link deps Aug 11, 2025
@haampie
Copy link
Copy Markdown
Member

haampie commented Aug 11, 2025

This is quite elegant 👍

Should also work in the future with LLVM-based compilers using libstdc++ as a runtime library because of how gcc-runtime is (or happens to be) modeled: it has a build dep on gcc and makes a copy of its compiler runtime libraries; there's no c, cxx or fortran dependency.

Not necessary for this PR, but maybe good to think ahead how this can be extended for other use cases:

  1. For certain Fortran and (soon) C++ packages that produce modules, it's probably better if the package itself declares that its dependents need a matching fortran and cxx compiler resp. Is it easy to extend the rules for that? I guess a more advanced compiler_mixing rule works. Or is this too constraining for users who know what they're doing when mixing compilers?
  2. I can imagine that users care more about a single compiler for Fortran, but don't care about mixing compilers for C and prefer reuse there. Should this option be per language? If so shouldn't the config option go in packages.yaml? Or is this just a symptom of (1) and should we only fix (1).

@alalazo
Copy link
Copy Markdown
Member

alalazo commented Aug 11, 2025

I'll post benchmark results asap.

Signed-off-by: Peter Scheibel <[email protected]>
Signed-off-by: Peter Scheibel <[email protected]>
@scheibelp scheibelp force-pushed the disable-compiler-mixing2 branch from 28bc1d6 to 69af7dd Compare August 11, 2025 16:48
@scheibelp
Copy link
Copy Markdown
Member Author

Should also work in the future with LLVM-based compilers .
.. there's no c, cxx or fortran dependency.

I'm not clear how this PR would work with that change: there would still be virtual_on_edge...c/cxx/fortran even if there's no c/cxx/fortran dep? If you have a link to this PR (if it's in progress) or discussion I could read it

For certain Fortran and (soon) C++ packages that produce modules, it's probably better if the package itself declares that
... Is it easy to extend the rules for that?

For things that can't mix (i.e. where this is mandatory), package directives would be better than config (this PR is about both preference and need); I think it would be easy to generate the asp dynamically (i.e. where the ParentNode or ChildNode check against package names).

I can imagine that users care more about a single compiler for Fortran, but don't care about mixing compilers for C and prefer reuse there. Should this option be per language?

I think that would be a good extension but I think some people would still want to turn it off entirely (so the schema would support boolean or a dictionary of lang->boolean).

@scheibelp
Copy link
Copy Markdown
Member Author

Should also work in the future with LLVM-based compilers .
.. there's no c, cxx or fortran dependency.

I'm not clear how this PR would work with that change: there would still be virtual_on_edge...c/cxx/fortran even if there's no c/cxx/fortran dep? If you have a link to this PR (if it's in progress) or discussion I could read it

I think I understand better now:

  • Most packages will have c/cxx/fortran dependencies
  • llvm will be injecting gcc-runtime in the future
  • While gcc-runtime will depend on gcc, it won't be a language dependency, so the check added here wont trip on X->gcc-runtime

Copy link
Copy Markdown
Member

@alalazo alalazo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I benchmarked this against:

radiuss.disable_mixing_on.csv
radiuss.disable_mixing_no_disabling.csv
radiuss.develop.csv

When mixing is disabled the same spec can be 30% slower to concretize, otherwise there is no difference. For the record I had a configuration with 4 gcc and 2 llvm compilers

radiuss

Grounding doesn't seem much of an issue, as it is solving in this case.

@scheibelp
Copy link
Copy Markdown
Member Author

scheibelp commented Aug 22, 2025

Significant changes from earlier, for a dag like

  W
 / \
X   Y
 \ /
  Z

(All edges are link deps)

  • If W and Z need fortran (but X/Y don't) then I want to enforce fortran consistency between W and Z
  • If X/Y depend on fortran (but W/Z don't) I want to enforce matching between X and Y
    • (Max: there is maximum 1 fortran compiler per dag right now)
    • For the use case, if the user says W%[virtuals=fortran] oneapi that X/Y use %oneapi
  • I want to be able to disable matching for a given package by name (e.g. allow X to use whatever compiler it wants)

New statements added, plus tests for them (although not comprehensive)

…icient.

Revert "bypass mutable_database entirely and strip test_disable_mixing_reuse down to minimum infrastructure setup"

This reverts commit ea9f71d.
Copy link
Copy Markdown
Member

@alalazo alalazo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few comments. Did anybody ever worked out if there are edge cases with splicing that would not be covered?

I don't think we should deal with them here, in case there are, but it would be good to know if we have them.

@alalazo
Copy link
Copy Markdown
Member

alalazo commented Oct 20, 2025

@scheibelp Am I correct if I say that this:

Screenshot from 2025-10-20 19-29-03

is meant to be fixed by #51383 and it's just the description of the PR that is slightly outdated?

@scheibelp
Copy link
Copy Markdown
Member Author

Am I correct if I say that this:
...
is meant to be fixed by #51383 and it's just the description of the PR that is slightly outdated?

In short, I don't think so:

  • solver: set preferences from input specs using %% #51383 would allow propagating a preference for fortran transitively
  • Because of other constraints in the concretizer, Fortran already has to be consistent (even without this PR and solver: set preferences from input specs using %% #51383)
  • %% is a preference, so doesn't guarantee that you get the Fortran compiler you want (e.g. when %%% would cause an error)
  • So overall I still think this particular issue isn't resolved until %%%, which then also provides an encompassing mechanism for doing everything this PR achieves
    • (But I've mentioned elsewhere I think users would like the configuration directives provided in this PR either way)

(I think it was already understood, but the problem this is referring to is if you use this PR and then say spack spec foo %X , where X is the "foo needs to use C as the fortran compiler if foo needs Fortran" syntax, the PR won't guarantee that you get C as your fortran compiler if foo doesn't actually depend on Fortran).

@alalazo
Copy link
Copy Markdown
Member

alalazo commented Oct 21, 2025

In short, I don't think so:

Sure, the main question for me was if this problem is meant to be fixed in this PR (I was a bit perplexed seeing that in the TODO list). I guess we are on the same page:

  • This PR deals only with compiler mixing in the root unification set
  • Other PRs will introduce the %% and %%% syntax to solve the other issue

@tgamblin tgamblin changed the title Disable compiler mixing between link deps concretizer: option to disable compiler mixing between link deps Oct 27, 2025
@alalazo
Copy link
Copy Markdown
Member

alalazo commented Oct 27, 2025

I just benchmarked this against:

When compiler mixing is allowed, this has no impact on concretization time for that benchmark:

radiuss.mixing-true.csv
radiuss.develop.csv

comparison

When we forbid compiler mixing, there's just a slight regression in solve time, but the total time is not affected:

radiuss.mixing-false.csv

comparison

Copy link
Copy Markdown
Member

@alalazo alalazo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this PR is basically ready. The only polishing remaining is imo to:

  • Update the PR title and description
  • Add some default configuration for the new option to our YAML files

The last point in particular is needed so that users could know what is the default if they use:

$ spack config [get|blame] concretizer

Right now that command shows no value for concretize:compiler_mixing.

@scheibelp
Copy link
Copy Markdown
Member Author

@alalazo I believe review requests are now addressed:

  • spack config blame concretizer now shows default setting (compiler_mixing: true)
  • Minor updates to PR description: i.e. second TODO is punted, and this applies to root unifications set

@alalazo alalazo changed the title concretizer: option to disable compiler mixing between link deps concretizer: option to disable compiler mixing between runtime deps Oct 27, 2025
@scheibelp scheibelp merged commit 856a303 into spack:develop Oct 30, 2025
30 of 32 checks passed
kshea21 pushed a commit to kshea21/spack that referenced this pull request Nov 4, 2025
…pack#51135)

You can set

`concretizer:compiler_mixing:false`

to ensure that any compiler assigned to a root spec will be used
consistently by all of its dependencies; more generally, that
all packages in the link/run DAG that includes the root will use
the same c compiler, and likewise for c++ and Fortran.

This setting defaults to true, i.e. this PR will have no affect on
concretizations unless a user changes the configuration setting
from the default.

`compiler_mixing:` can also be a list of package names: in that case
the named packages will be allowed to use any compiler; all other
packages (including parents/children of those named packages) will
need to be consistent.

---------

Signed-off-by: Peter Scheibel <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants