Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better support for multi-compiler environments. #188

Merged
merged 4 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,10 @@ jobs:
- name: Install Tools
run: |
python -m pip install --upgrade pip
python -m pip install black flake8 isort mypy
python -m pip install black flake8 mypy
- name: Black
run: |
black --check --verbose stackinator unittests
- name: isort
run: |
isort --check --skip stackinator/repo --diff .
- name: flake8
run: |
flake8 --count --show-source --statistics .
29 changes: 23 additions & 6 deletions docs/recipes.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ The `compiler` field describes a list compilers to use to build the software sta
Each compiler toolchain is specified using toolchain and spec

```yaml title="compile all packages with [email protected]"
compiler
compiler:
- toolchain: gcc
spec: [email protected]
```
Expand All @@ -110,20 +110,37 @@ Sometimes two compiler toolchains are required, for example when using the `nvhp
The example below uses the `nvhpc` compilers with [email protected].

```yaml title="compile all packages with [email protected]"
compiler
- toolchain: llvm
spec: [email protected]
compiler:
- toolchain: gcc
spec: [email protected]
- toolchain: llvm
spec: [email protected]
```

!!! note
If more than one version of gcc has been installed, use the same version that was used to install `nvhpc`.

!!! warning
As a rule, use a single compiler wherever possible - keep it simple!
Stackinator does not test or support using two versions of gcc in the same toolchain.

We don't test or support using two versions of gcc in the same toolchain.
The order of the compilers is significant. The first compiler is the default, and the other compilers will only be used to build packages when explicitly added to a spec.
For example, in the recipe below, only `netcdf-fortran` will be built with the `nvhpc` toolchain, while the root specs `cmake` and `netcdf-c` and all dependencies will be built using the `gcc` toolchain.


```yaml title="compile all packages with [email protected]"
compiler:
- toolchain: gcc
spec: gcc
- toolchain: llvm
spec: nvhpc
specs
- cmake
- netcdf-c
- netcdf-fortran%nvhpc
```

!!! note
This approach is typically used to build Fortran applications and packages with one toolchain (e.g. `nvhpc`), and all of the C/C++ dependencies with a different toolchain (e.g. `gcc`).

### MPI

Expand Down
14 changes: 14 additions & 0 deletions stackinator/recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,20 @@ def generate_environment_specs(self, raw):
# TODO: Create a custom exception type
raise Exception(f"Unsupported mpi: {mpi_impl}")

# set constraints that ensure the the main compiler is always used to build packages
# that do not explicitly request a compiler.
for name, config in environments.items():
compilers = config["compiler"]
if len(compilers) == 1:
config["toolchain_constraints"] = []
continue
requires = [f"%{compilers[0]['spec']}"]
for spec in config["specs"]:
if "%" in spec:
requires.append(spec)

config["toolchain_constraints"] = requires

# An awkward hack to work around spack not supporting creating activation
# scripts for each file system view in an environment: it only generates them
# for the "default" view.
Expand Down
17 changes: 9 additions & 8 deletions stackinator/templates/environments.spack.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{% set separator = joiner(', ') %}
spack:
include:
{% if config.packages %}
Expand All @@ -13,20 +12,22 @@ spack:
reuse: false
specs:
{% for spec in config.specs %}
- {{ spec }}
- '{{ spec }}'
{% endfor %}
packages:
all:
compiler: [{% for c in config.compiler %}{{ separator() }}{{ c.spec }}{% endfor %}]
{% set separator = joiner(', ') %}
compiler: [{% for c in config.compiler %}{{ separator() }}'{{ c.spec }}'{% endfor %}]
require:
{% set separator = joiner(', ') %}
- one_of: [{% for c in config.toolchain_constraints %}{{ separator() }}'{{ c }}'{% endfor %}]
{% if config.variants %}
variants:
{% for variant in config.variants %}
- {{ variant }}
{% endfor %}
{% set separator = joiner(', ') %}
variants: [{% for v in config.variants %}{{ separator() }}'{{ v }}'{% endfor %}]
{% endif %}
{% if config.mpi.spec %}
mpi:
require: {{ config.mpi.spec }}
require: '{{ config.mpi.spec }}'
{% endif %}
{% if config.view %}
view:
Expand Down
Loading