Compare commits

...

3 Commits

Author SHA1 Message Date
Gregory Becker
a542b0cfc0 flake 2023-02-16 19:29:35 -08:00
Gregory Becker
0d02262bbc docs 2023-02-16 19:13:04 -08:00
Gregory Becker
9beac03142 SpecList: enforce ordering of matrices on constructed specs 2023-02-16 19:12:52 -08:00
5 changed files with 58 additions and 36 deletions

View File

@@ -346,7 +346,7 @@ the Environment and then install the concretized specs.
(see :ref:`build-jobs`). To speed up environment builds further, independent
packages can be installed in parallel by launching more Spack instances. For
example, the following will build at most four packages in parallel using
three background jobs:
three background jobs:
.. code-block:: console
@@ -394,7 +394,7 @@ version (and other constraints) passed as the spec argument to the
For packages with ``git`` attributes, git branches, tags, and commits can
also be used as valid concrete versions (see :ref:`version-specifier`).
This means that for a package ``foo``, ``spack develop foo@git.main`` will clone
This means that for a package ``foo``, ``spack develop foo@git.main`` will clone
the ``main`` branch of the package, and ``spack install`` will install from
that git clone if ``foo`` is in the environment.
Further development on ``foo`` can be tested by reinstalling the environment,
@@ -630,6 +630,35 @@ The following two Environment manifests are identical:
Spec matrices can be used to install swaths of software across various
toolchains.
Note that ordering of matrices is important. For example, the
following environments are identical:
.. code-block:: yaml
spack:
specs:
- matrix:
- [hdf5@1.10.2+mpi]
- [^mpich, ^openmpi]
- ['%gcc']
- matrix:
- [hdf5@1.12.1+mpi]
- ['%gcc']
- [^mpich, ^openmpi]
spack:
specs:
- hdf5@1.10.2+mpi ^mpich%gcc
- hdf5@1.10.2+mpi ^openmpi%gcc
- hdf5@1.12.1+mpi %gcc ^mpich
- hdf5@1.12.1+mpi %gcc ^openmpi
Notice how the first matrix applies the compiler constraints to the
mpi dependencies, whereas the second matrix applies the compiler
constraints directly to the root hdf5 node. This gives users the full
breadth of expressiveness of the spec syntax through the matrix
interface.
^^^^^^^^^^^^^^^^^^^^
Spec List References
^^^^^^^^^^^^^^^^^^^^
@@ -1120,19 +1149,19 @@ index once every package is pushed. Note how this target uses the generated
SPACK ?= spack
BUILDCACHE_DIR = $(CURDIR)/tarballs
.PHONY: all
all: push
include env.mk
example/push/%: example/install/%
@mkdir -p $(dir $@)
$(info About to push $(SPEC) to a buildcache)
$(SPACK) -e . buildcache create --allow-root --only=package --directory $(BUILDCACHE_DIR) /$(HASH)
@touch $@
push: $(addprefix example/push/,$(example/SPACK_PACKAGE_IDS))
$(info Updating the buildcache index)
$(SPACK) -e . buildcache update-index --directory $(BUILDCACHE_DIR)

View File

@@ -2265,15 +2265,12 @@ def _concretize_from_constraints(spec_constraints, tests=False):
m += "concretization target. all specs must have a single name "
m += "constraint for concretization."
raise InvalidSpecConstraintError(m)
spec_constraints.remove(root_spec[0])
invalid_constraints = []
while True:
# Attach all anonymous constraints to one named spec
s = root_spec[0].copy()
for c in spec_constraints:
if c not in invalid_constraints:
s.constrain(c)
# Combine constraints into a single spec
s = Spec(" ".join([str(c) for c in spec_constraints if c not in invalid_constraints]))
try:
return s.concretized(tests=tests)
except spack.spec.InvalidDependencyError as e:

View File

@@ -51,7 +51,9 @@ def specs_as_constraints(self):
constraints = []
for item in self.specs_as_yaml_list:
if isinstance(item, dict): # matrix of specs
constraints.extend(_expand_matrix_constraints(item))
expanded = _expand_matrix_constraints(item)
for e in expanded:
constraints.append([Spec(x) for x in e])
else: # individual spec
constraints.append([Spec(item)])
self._constraints = constraints
@@ -62,13 +64,11 @@ def specs_as_constraints(self):
def specs(self):
if self._specs is None:
specs = []
# This could be slightly faster done directly from yaml_list,
# but this way is easier to maintain.
for constraint_list in self.specs_as_constraints:
spec = constraint_list[0].copy()
for const in constraint_list[1:]:
spec.constrain(const)
specs.append(spec)
for item in self.specs_as_yaml_list:
if isinstance(item, dict): # matrix of specs
specs.extend([Spec(" ".join(x)) for x in _expand_matrix_constraints(item)])
else: # individual spec
specs.append(Spec(item))
self._specs = specs
return self._specs
@@ -193,11 +193,7 @@ def _expand_matrix_constraints(matrix_config):
for combo in itertools.product(*expanded_rows):
# Construct a combined spec to test against excludes
flat_combo = [constraint for constraint_list in combo for constraint in constraint_list]
flat_combo = [Spec(x) for x in flat_combo]
test_spec = flat_combo[0].copy()
for constraint in flat_combo[1:]:
test_spec.constrain(constraint)
test_spec = Spec(" ".join(flat_combo))
# Abstract variants don't have normal satisfaction semantics
# Convert all variants to concrete types.
@@ -213,7 +209,7 @@ def _expand_matrix_constraints(matrix_config):
continue
if sigil:
flat_combo[0] = Spec(sigil + str(flat_combo[0]))
flat_combo[0] = sigil + flat_combo[0]
# Add to list of constraints
results.append(flat_combo)

View File

@@ -75,8 +75,8 @@ def test_env_change_spec(tmpdir, mock_packages, config):
- desired_specs: ["mpileaks@2.1"]
specs:
- matrix:
- [$compilers]
- [$desired_specs]
- [$compilers]
"""

View File

@@ -61,25 +61,25 @@ def test_spec_list_expansions(self):
@pytest.mark.parametrize(
"specs,expected",
[
# Constraints are ordered randomly
# Constraints are ordered carefully to apply to appropriate node
(
[
{
"matrix": [
["^zmpi"],
["%gcc@4.5.0"],
["hypre", "libelf"],
["~shared"],
["cflags=-O3", 'cflags="-g -O0"'],
["^foo"],
["^zmpi"],
["%gcc@4.5.0"],
["cflags=-O3", 'cflags="-g -O0"'],
]
}
],
[
"hypre cflags=-O3 ~shared %gcc@4.5.0 ^foo ^zmpi",
'hypre cflags="-g -O0" ~shared %gcc@4.5.0 ^foo ^zmpi',
"libelf cflags=-O3 ~shared %gcc@4.5.0 ^foo ^zmpi",
'libelf cflags="-g -O0" ~shared %gcc@4.5.0 ^foo ^zmpi',
"hypre ~shared ^foo ^zmpi cflags=-O3 %gcc@4.5.0",
'hypre ~shared ^foo ^zmpi cflags="-g -O0" %gcc@4.5.0',
"libelf ~shared ^foo ^zmpi cflags=-O3 %gcc@4.5.0",
'libelf ~shared ^foo ^zmpi cflags="-g -O0" %gcc@4.5.0',
],
),
# A constraint affects both the root and a dependency