Cherry-picking virtual dependencies (#35322)
This PR makes it possible to select only a subset of virtual dependencies from a spec that _may_ provide more. To select providers, a syntax to specify edge attributes is introduced: ``` hdf5 ^[virtuals=mpi] mpich ``` With that syntax we can concretize specs like: ```console $ spack spec strumpack ^[virtuals=mpi] intel-parallel-studio+mkl ^[virtuals=lapack] openblas ``` On `develop` this would currently fail with: ```console $ spack spec strumpack ^intel-parallel-studio+mkl ^openblas ==> Error: Spec cannot include multiple providers for virtual 'blas' Requested 'intel-parallel-studio' and 'openblas' ``` In package recipes, virtual specs that are declared in the same `provides` directive need to be provided _together_. This means that e.g. `openblas`, which has: ```python provides("blas", "lapack") ``` needs to provide both `lapack` and `blas` when requested to provide at least one of them. ## Additional notes This capability is needed to model compilers. Assuming that languages are treated like virtual dependencies, we might want e.g. to use LLVM to compile C/C++ and Gnu GCC to compile Fortran. This can be accomplished by the following[^1]: ``` hdf5 ^[virtuals=c,cxx] llvm ^[virtuals=fortran] gcc ``` [^1]: We plan to add some syntactic sugar around this syntax, and reuse the `%` sigil to avoid having a lot of boilerplate around compilers. Modifications: - [x] Add syntax to interact with edge attributes from spec literals - [x] Add concretization logic to be able to cherry-pick virtual dependencies - [x] Extend semantic of the `provides` directive to express when virtuals need to be provided together - [x] Add unit-tests and documentation
This commit is contained in:
parent
6cd2241e49
commit
16fa3b9f07
29 changed files with 1123 additions and 150 deletions
|
@ -1526,6 +1526,30 @@ any MPI implementation will do. If another package depends on
|
||||||
error. Likewise, if you try to plug in some package that doesn't
|
error. Likewise, if you try to plug in some package that doesn't
|
||||||
provide MPI, Spack will raise an error.
|
provide MPI, Spack will raise an error.
|
||||||
|
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Explicit binding of virtual dependencies
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
There are packages that provide more than just one virtual dependency. When interacting with them, users
|
||||||
|
might want to utilize just a subset of what they could provide, and use other providers for virtuals they
|
||||||
|
need.
|
||||||
|
|
||||||
|
It is possible to be more explicit and tell Spack which dependency should provide which virtual, using a
|
||||||
|
special syntax:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ spack spec strumpack ^[virtuals=mpi] intel-parallel-studio+mkl ^[virtuals=lapack] openblas
|
||||||
|
|
||||||
|
Concretizing the spec above produces the following DAG:
|
||||||
|
|
||||||
|
.. figure:: images/strumpack_virtuals.svg
|
||||||
|
:scale: 60 %
|
||||||
|
:align: center
|
||||||
|
|
||||||
|
where ``intel-parallel-studio`` *could* provide ``mpi``, ``lapack``, and ``blas`` but is used only for the former. The ``lapack``
|
||||||
|
and ``blas`` dependencies are satisfied by ``openblas``.
|
||||||
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
Specifying Specs by Hash
|
Specifying Specs by Hash
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
534
lib/spack/docs/images/strumpack_virtuals.svg
Normal file
534
lib/spack/docs/images/strumpack_virtuals.svg
Normal file
|
@ -0,0 +1,534 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||||
|
--><!-- Title: G Pages: 1 --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="3044pt" height="1683pt" viewBox="0.00 0.00 3043.65 1682.80">
|
||||||
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 1678.8)">
|
||||||
|
<title>G</title>
|
||||||
|
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-1678.8 3039.6456,-1678.8 3039.6456,4 -4,4"/>
|
||||||
|
<!-- hkcrbrtf2qex6rvzuok5tzdrbam55pdn -->
|
||||||
|
<g id="node1" class="node">
|
||||||
|
<title>hkcrbrtf2qex6rvzuok5tzdrbam55pdn</title>
|
||||||
|
<path fill="#add8e6" stroke="#000000" stroke-width="4" d="M2407.965,-1198.3002C2407.965,-1198.3002 1948.1742,-1198.3002 1948.1742,-1198.3002 1942.1742,-1198.3002 1936.1742,-1192.3002 1936.1742,-1186.3002 1936.1742,-1186.3002 1936.1742,-1123.6998 1936.1742,-1123.6998 1936.1742,-1117.6998 1942.1742,-1111.6998 1948.1742,-1111.6998 1948.1742,-1111.6998 2407.965,-1111.6998 2407.965,-1111.6998 2413.965,-1111.6998 2419.965,-1117.6998 2419.965,-1123.6998 2419.965,-1123.6998 2419.965,-1186.3002 2419.965,-1186.3002 2419.965,-1192.3002 2413.965,-1198.3002 2407.965,-1198.3002"/>
|
||||||
|
<text text-anchor="middle" x="2178.0696" y="-1147.8" font-family="Monaco" font-size="24.00" fill="#000000">netlib-scalapack@2.2.0%gcc@9.4.0/hkcrbrt</text>
|
||||||
|
</g>
|
||||||
|
<!-- o524gebsxavobkte3k5fglgwnedfkadf -->
|
||||||
|
<g id="node8" class="node">
|
||||||
|
<title>o524gebsxavobkte3k5fglgwnedfkadf</title>
|
||||||
|
<path fill="#add8e6" stroke="#000000" stroke-width="4" d="M901.2032,-1039.5002C901.2032,-1039.5002 486.936,-1039.5002 486.936,-1039.5002 480.936,-1039.5002 474.936,-1033.5002 474.936,-1027.5002 474.936,-1027.5002 474.936,-964.8998 474.936,-964.8998 474.936,-958.8998 480.936,-952.8998 486.936,-952.8998 486.936,-952.8998 901.2032,-952.8998 901.2032,-952.8998 907.2032,-952.8998 913.2032,-958.8998 913.2032,-964.8998 913.2032,-964.8998 913.2032,-1027.5002 913.2032,-1027.5002 913.2032,-1033.5002 907.2032,-1039.5002 901.2032,-1039.5002"/>
|
||||||
|
<text text-anchor="middle" x="694.0696" y="-989" font-family="Monaco" font-size="24.00" fill="#000000">openblas@0.3.21%gcc@9.4.0/o524geb</text>
|
||||||
|
</g>
|
||||||
|
<!-- hkcrbrtf2qex6rvzuok5tzdrbam55pdn->o524gebsxavobkte3k5fglgwnedfkadf -->
|
||||||
|
<g id="edge10" class="edge">
|
||||||
|
<title>hkcrbrtf2qex6rvzuok5tzdrbam55pdn->o524gebsxavobkte3k5fglgwnedfkadf</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1936.1981,-1113.832C1933.0949,-1113.4088 1930.0059,-1112.9948 1926.9392,-1112.5915 1575.405,-1066.3348 1485.3504,-1074.0879 1131.9752,-1040.5955 1064.2267,-1034.1713 990.6114,-1026.9648 923.4066,-1020.2975"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M1936.4684,-1111.8504C1933.3606,-1111.4265 1930.2716,-1111.0125 1927.2,-1110.6085 1575.2335,-1064.3422 1485.1789,-1072.0953 1132.164,-1038.6045 1064.4216,-1032.1808 990.8062,-1024.9744 923.604,-1018.3073"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="923.505,-1015.7853 913.2081,-1018.2801 922.8133,-1022.751 923.505,-1015.7853"/>
|
||||||
|
<text text-anchor="middle" x="1368.79" y="-1067.6346" font-family="Times,serif" font-size="14.00" fill="#000000">virtuals=blas,lapack</text>
|
||||||
|
</g>
|
||||||
|
<!-- 2w3nq3n3hcj2tqlvcpewsryamltlu5tw -->
|
||||||
|
<g id="node23" class="node">
|
||||||
|
<title>2w3nq3n3hcj2tqlvcpewsryamltlu5tw</title>
|
||||||
|
<path fill="#add8e6" stroke="#000000" stroke-width="4" d="M2767.3081,-1039.5002C2767.3081,-1039.5002 2166.8311,-1039.5002 2166.8311,-1039.5002 2160.8311,-1039.5002 2154.8311,-1033.5002 2154.8311,-1027.5002 2154.8311,-1027.5002 2154.8311,-964.8998 2154.8311,-964.8998 2154.8311,-958.8998 2160.8311,-952.8998 2166.8311,-952.8998 2166.8311,-952.8998 2767.3081,-952.8998 2767.3081,-952.8998 2773.3081,-952.8998 2779.3081,-958.8998 2779.3081,-964.8998 2779.3081,-964.8998 2779.3081,-1027.5002 2779.3081,-1027.5002 2779.3081,-1033.5002 2773.3081,-1039.5002 2767.3081,-1039.5002"/>
|
||||||
|
<text text-anchor="middle" x="2467.0696" y="-989" font-family="Monaco" font-size="24.00" fill="#000000">intel-parallel-studio@cluster.2020.4%gcc@9.4.0/2w3nq3n</text>
|
||||||
|
</g>
|
||||||
|
<!-- hkcrbrtf2qex6rvzuok5tzdrbam55pdn->2w3nq3n3hcj2tqlvcpewsryamltlu5tw -->
|
||||||
|
<g id="edge29" class="edge">
|
||||||
|
<title>hkcrbrtf2qex6rvzuok5tzdrbam55pdn->2w3nq3n3hcj2tqlvcpewsryamltlu5tw</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M2256.5586,-1110.7308C2294.3103,-1089.9869 2339.6329,-1065.083 2378.4976,-1043.7276"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M2257.5217,-1112.4836C2295.2735,-1091.7397 2340.5961,-1066.8358 2379.4607,-1045.4804"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="2381.116,-1047.4235 2388.1946,-1039.5403 2377.745,-1041.2886 2381.116,-1047.4235"/>
|
||||||
|
<text text-anchor="middle" x="2286.6606" y="-1079.8414" font-family="Times,serif" font-size="14.00" fill="#000000">virtuals=mpi</text>
|
||||||
|
</g>
|
||||||
|
<!-- gguve5icmo5e4cw5o3hvvfsxremc46if -->
|
||||||
|
<g id="node27" class="node">
|
||||||
|
<title>gguve5icmo5e4cw5o3hvvfsxremc46if</title>
|
||||||
|
<path fill="#add8e6" stroke="#000000" stroke-width="4" d="M1539.1928,-1039.5002C1539.1928,-1039.5002 1152.9464,-1039.5002 1152.9464,-1039.5002 1146.9464,-1039.5002 1140.9464,-1033.5002 1140.9464,-1027.5002 1140.9464,-1027.5002 1140.9464,-964.8998 1140.9464,-964.8998 1140.9464,-958.8998 1146.9464,-952.8998 1152.9464,-952.8998 1152.9464,-952.8998 1539.1928,-952.8998 1539.1928,-952.8998 1545.1928,-952.8998 1551.1928,-958.8998 1551.1928,-964.8998 1551.1928,-964.8998 1551.1928,-1027.5002 1551.1928,-1027.5002 1551.1928,-1033.5002 1545.1928,-1039.5002 1539.1928,-1039.5002"/>
|
||||||
|
<text text-anchor="middle" x="1346.0696" y="-989" font-family="Monaco" font-size="24.00" fill="#000000">cmake@3.25.1%gcc@9.4.0/gguve5i</text>
|
||||||
|
</g>
|
||||||
|
<!-- hkcrbrtf2qex6rvzuok5tzdrbam55pdn->gguve5icmo5e4cw5o3hvvfsxremc46if -->
|
||||||
|
<g id="edge17" class="edge">
|
||||||
|
<title>hkcrbrtf2qex6rvzuok5tzdrbam55pdn->gguve5icmo5e4cw5o3hvvfsxremc46if</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1950.9968,-1111.6597C1829.5529,-1088.4802 1680.8338,-1060.0949 1561.2457,-1037.2697"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1561.7091,-1033.795 1551.2303,-1035.3581 1560.3967,-1040.6709 1561.7091,-1033.795"/>
|
||||||
|
</g>
|
||||||
|
<!-- i4avrindvhcamhurzbfdaggbj2zgsrrh -->
|
||||||
|
<g id="node2" class="node">
|
||||||
|
<title>i4avrindvhcamhurzbfdaggbj2zgsrrh</title>
|
||||||
|
<path fill="#ff7f50" stroke="#000000" stroke-width="4" d="M1536.3649,-86.7002C1536.3649,-86.7002 1155.7743,-86.7002 1155.7743,-86.7002 1149.7743,-86.7002 1143.7743,-80.7002 1143.7743,-74.7002 1143.7743,-74.7002 1143.7743,-12.0998 1143.7743,-12.0998 1143.7743,-6.0998 1149.7743,-.0998 1155.7743,-.0998 1155.7743,-.0998 1536.3649,-.0998 1536.3649,-.0998 1542.3649,-.0998 1548.3649,-6.0998 1548.3649,-12.0998 1548.3649,-12.0998 1548.3649,-74.7002 1548.3649,-74.7002 1548.3649,-80.7002 1542.3649,-86.7002 1536.3649,-86.7002"/>
|
||||||
|
<text text-anchor="middle" x="1346.0696" y="-36.2" font-family="Monaco" font-size="24.00" fill="#000000">pkgconf@1.8.0%gcc@9.4.0/i4avrin</text>
|
||||||
|
</g>
|
||||||
|
<!-- ywrpvv2hgooeepdke33exkqrtdpd5gkl -->
|
||||||
|
<g id="node3" class="node">
|
||||||
|
<title>ywrpvv2hgooeepdke33exkqrtdpd5gkl</title>
|
||||||
|
<path fill="#ff7f50" stroke="#000000" stroke-width="4" d="M849.3673,-721.9002C849.3673,-721.9002 480.7719,-721.9002 480.7719,-721.9002 474.7719,-721.9002 468.7719,-715.9002 468.7719,-709.9002 468.7719,-709.9002 468.7719,-647.2998 468.7719,-647.2998 468.7719,-641.2998 474.7719,-635.2998 480.7719,-635.2998 480.7719,-635.2998 849.3673,-635.2998 849.3673,-635.2998 855.3673,-635.2998 861.3673,-641.2998 861.3673,-647.2998 861.3673,-647.2998 861.3673,-709.9002 861.3673,-709.9002 861.3673,-715.9002 855.3673,-721.9002 849.3673,-721.9002"/>
|
||||||
|
<text text-anchor="middle" x="665.0696" y="-671.4" font-family="Monaco" font-size="24.00" fill="#000000">perl@5.36.0%gcc@9.4.0/ywrpvv2</text>
|
||||||
|
</g>
|
||||||
|
<!-- h3ujmb3ts4kxxxv77knh2knuystuerbx -->
|
||||||
|
<g id="node7" class="node">
|
||||||
|
<title>h3ujmb3ts4kxxxv77knh2knuystuerbx</title>
|
||||||
|
<path fill="#ff7f50" stroke="#000000" stroke-width="4" d="M392.4016,-563.1002C392.4016,-563.1002 19.7376,-563.1002 19.7376,-563.1002 13.7376,-563.1002 7.7376,-557.1002 7.7376,-551.1002 7.7376,-551.1002 7.7376,-488.4998 7.7376,-488.4998 7.7376,-482.4998 13.7376,-476.4998 19.7376,-476.4998 19.7376,-476.4998 392.4016,-476.4998 392.4016,-476.4998 398.4016,-476.4998 404.4016,-482.4998 404.4016,-488.4998 404.4016,-488.4998 404.4016,-551.1002 404.4016,-551.1002 404.4016,-557.1002 398.4016,-563.1002 392.4016,-563.1002"/>
|
||||||
|
<text text-anchor="middle" x="206.0696" y="-512.6" font-family="Monaco" font-size="24.00" fill="#000000">bzip2@1.0.8%gcc@9.4.0/h3ujmb3</text>
|
||||||
|
</g>
|
||||||
|
<!-- ywrpvv2hgooeepdke33exkqrtdpd5gkl->h3ujmb3ts4kxxxv77knh2knuystuerbx -->
|
||||||
|
<g id="edge9" class="edge">
|
||||||
|
<title>ywrpvv2hgooeepdke33exkqrtdpd5gkl->h3ujmb3ts4kxxxv77knh2knuystuerbx</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M539.3189,-636.1522C477.7157,-614.8394 403.4197,-589.1353 340.5959,-567.4002"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M539.9728,-634.2622C478.3696,-612.9494 404.0736,-587.2452 341.2498,-565.5101"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="341.9365,-563.1023 331.3417,-563.1403 339.6478,-569.7176 341.9365,-563.1023"/>
|
||||||
|
</g>
|
||||||
|
<!-- uabgssx6lsgrevwbttslldnr5nzguprj -->
|
||||||
|
<g id="node19" class="node">
|
||||||
|
<title>uabgssx6lsgrevwbttslldnr5nzguprj</title>
|
||||||
|
<path fill="#ff7f50" stroke="#000000" stroke-width="4" d="M1298.2296,-563.1002C1298.2296,-563.1002 937.9096,-563.1002 937.9096,-563.1002 931.9096,-563.1002 925.9096,-557.1002 925.9096,-551.1002 925.9096,-551.1002 925.9096,-488.4998 925.9096,-488.4998 925.9096,-482.4998 931.9096,-476.4998 937.9096,-476.4998 937.9096,-476.4998 1298.2296,-476.4998 1298.2296,-476.4998 1304.2296,-476.4998 1310.2296,-482.4998 1310.2296,-488.4998 1310.2296,-488.4998 1310.2296,-551.1002 1310.2296,-551.1002 1310.2296,-557.1002 1304.2296,-563.1002 1298.2296,-563.1002"/>
|
||||||
|
<text text-anchor="middle" x="1118.0696" y="-512.6" font-family="Monaco" font-size="24.00" fill="#000000">gdbm@1.23%gcc@9.4.0/uabgssx</text>
|
||||||
|
</g>
|
||||||
|
<!-- ywrpvv2hgooeepdke33exkqrtdpd5gkl->uabgssx6lsgrevwbttslldnr5nzguprj -->
|
||||||
|
<g id="edge44" class="edge">
|
||||||
|
<title>ywrpvv2hgooeepdke33exkqrtdpd5gkl->uabgssx6lsgrevwbttslldnr5nzguprj</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M788.523,-634.2635C849.3209,-612.9507 922.6457,-587.2465 984.6483,-565.5114"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M789.1847,-636.1509C849.9825,-614.8381 923.3073,-589.1339 985.3099,-567.3988"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="986.1559,-569.7515 994.435,-563.1403 983.8402,-563.1456 986.1559,-569.7515"/>
|
||||||
|
</g>
|
||||||
|
<!-- gkw4dg2p7rdnhru3m6lcnsjbzyr7g3hb -->
|
||||||
|
<g id="node20" class="node">
|
||||||
|
<title>gkw4dg2p7rdnhru3m6lcnsjbzyr7g3hb</title>
|
||||||
|
<path fill="#ff7f50" stroke="#000000" stroke-width="4" d="M896.1744,-563.1002C896.1744,-563.1002 433.9648,-563.1002 433.9648,-563.1002 427.9648,-563.1002 421.9648,-557.1002 421.9648,-551.1002 421.9648,-551.1002 421.9648,-488.4998 421.9648,-488.4998 421.9648,-482.4998 427.9648,-476.4998 433.9648,-476.4998 433.9648,-476.4998 896.1744,-476.4998 896.1744,-476.4998 902.1744,-476.4998 908.1744,-482.4998 908.1744,-488.4998 908.1744,-488.4998 908.1744,-551.1002 908.1744,-551.1002 908.1744,-557.1002 902.1744,-563.1002 896.1744,-563.1002"/>
|
||||||
|
<text text-anchor="middle" x="665.0696" y="-512.6" font-family="Monaco" font-size="24.00" fill="#000000">berkeley-db@18.1.40%gcc@9.4.0/gkw4dg2</text>
|
||||||
|
</g>
|
||||||
|
<!-- ywrpvv2hgooeepdke33exkqrtdpd5gkl->gkw4dg2p7rdnhru3m6lcnsjbzyr7g3hb -->
|
||||||
|
<g id="edge23" class="edge">
|
||||||
|
<title>ywrpvv2hgooeepdke33exkqrtdpd5gkl->gkw4dg2p7rdnhru3m6lcnsjbzyr7g3hb</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M664.0696,-635.2072C664.0696,-616.1263 664.0696,-593.5257 664.0696,-573.4046"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M666.0696,-635.2072C666.0696,-616.1263 666.0696,-593.5257 666.0696,-573.4046"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="668.5697,-573.1403 665.0696,-563.1403 661.5697,-573.1404 668.5697,-573.1403"/>
|
||||||
|
</g>
|
||||||
|
<!-- nizxi5u5bbrzhzwfy2qb7hatlhuswlrz -->
|
||||||
|
<g id="node24" class="node">
|
||||||
|
<title>nizxi5u5bbrzhzwfy2qb7hatlhuswlrz</title>
|
||||||
|
<path fill="#add8e6" stroke="#000000" stroke-width="4" d="M2195.2248,-563.1002C2195.2248,-563.1002 1840.9144,-563.1002 1840.9144,-563.1002 1834.9144,-563.1002 1828.9144,-557.1002 1828.9144,-551.1002 1828.9144,-551.1002 1828.9144,-488.4998 1828.9144,-488.4998 1828.9144,-482.4998 1834.9144,-476.4998 1840.9144,-476.4998 1840.9144,-476.4998 2195.2248,-476.4998 2195.2248,-476.4998 2201.2248,-476.4998 2207.2248,-482.4998 2207.2248,-488.4998 2207.2248,-488.4998 2207.2248,-551.1002 2207.2248,-551.1002 2207.2248,-557.1002 2201.2248,-563.1002 2195.2248,-563.1002"/>
|
||||||
|
<text text-anchor="middle" x="2018.0696" y="-512.6" font-family="Monaco" font-size="24.00" fill="#000000">zlib@1.2.13%gcc@9.4.0/nizxi5u</text>
|
||||||
|
</g>
|
||||||
|
<!-- ywrpvv2hgooeepdke33exkqrtdpd5gkl->nizxi5u5bbrzhzwfy2qb7hatlhuswlrz -->
|
||||||
|
<g id="edge4" class="edge">
|
||||||
|
<title>ywrpvv2hgooeepdke33exkqrtdpd5gkl->nizxi5u5bbrzhzwfy2qb7hatlhuswlrz</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M861.3292,-654.5584C1116.9929,-624.5514 1561.4447,-572.3867 1818.5758,-542.2075"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M861.5624,-656.5447C1117.2261,-626.5378 1561.6778,-574.373 1818.8089,-544.1939"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1819.373,-546.6449 1828.8968,-542.003 1818.5569,-539.6926 1819.373,-546.6449"/>
|
||||||
|
</g>
|
||||||
|
<!-- idvshq5nqmygzd4uo62mdispwgxsw7id -->
|
||||||
|
<g id="node4" class="node">
|
||||||
|
<title>idvshq5nqmygzd4uo62mdispwgxsw7id</title>
|
||||||
|
<path fill="#add8e6" stroke="#000000" stroke-width="4" d="M2383.212,-1674.7002C2383.212,-1674.7002 1972.9272,-1674.7002 1972.9272,-1674.7002 1966.9272,-1674.7002 1960.9272,-1668.7002 1960.9272,-1662.7002 1960.9272,-1662.7002 1960.9272,-1600.0998 1960.9272,-1600.0998 1960.9272,-1594.0998 1966.9272,-1588.0998 1972.9272,-1588.0998 1972.9272,-1588.0998 2383.212,-1588.0998 2383.212,-1588.0998 2389.212,-1588.0998 2395.212,-1594.0998 2395.212,-1600.0998 2395.212,-1600.0998 2395.212,-1662.7002 2395.212,-1662.7002 2395.212,-1668.7002 2389.212,-1674.7002 2383.212,-1674.7002"/>
|
||||||
|
<text text-anchor="middle" x="2178.0696" y="-1624.2" font-family="Monaco" font-size="24.00" fill="#000000">strumpack@7.0.1%gcc@9.4.0/idvshq5</text>
|
||||||
|
</g>
|
||||||
|
<!-- idvshq5nqmygzd4uo62mdispwgxsw7id->hkcrbrtf2qex6rvzuok5tzdrbam55pdn -->
|
||||||
|
<g id="edge33" class="edge">
|
||||||
|
<title>idvshq5nqmygzd4uo62mdispwgxsw7id->hkcrbrtf2qex6rvzuok5tzdrbam55pdn</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M2177.0696,-1587.8598C2177.0696,-1500.5185 2177.0696,-1304.1624 2177.0696,-1208.8885"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M2179.0696,-1587.8598C2179.0696,-1500.5185 2179.0696,-1304.1624 2179.0696,-1208.8885"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="2181.5697,-1208.611 2178.0696,-1198.611 2174.5697,-1208.611 2181.5697,-1208.611"/>
|
||||||
|
<text text-anchor="middle" x="2125.9224" y="-1397.5399" font-family="Times,serif" font-size="14.00" fill="#000000">virtuals=scalapack</text>
|
||||||
|
</g>
|
||||||
|
<!-- idvshq5nqmygzd4uo62mdispwgxsw7id->o524gebsxavobkte3k5fglgwnedfkadf -->
|
||||||
|
<g id="edge8" class="edge">
|
||||||
|
<title>idvshq5nqmygzd4uo62mdispwgxsw7id->o524gebsxavobkte3k5fglgwnedfkadf</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1960.6199,-1629.1097C1600.5855,-1621.4505 897.1143,-1596.5054 662.748,-1516.9469 459.8544,-1447.9506 281.1117,-1289.236 401.2427,-1111.0377 418.213,-1086.3492 472.759,-1062.01 530.3793,-1041.9698"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M1960.6625,-1627.1101C1600.6564,-1619.4517 897.1852,-1594.5067 663.3912,-1515.0531 461.1823,-1446.4551 282.4397,-1287.7405 402.8965,-1112.1623 419.028,-1088.1757 473.574,-1063.8364 531.0362,-1043.8589"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="532.0142,-1046.1665 540.3395,-1039.6137 529.7449,-1039.5445 532.0142,-1046.1665"/>
|
||||||
|
<text text-anchor="middle" x="1175.5163" y="-1600.8866" font-family="Times,serif" font-size="14.00" fill="#000000">virtuals=blas,lapack</text>
|
||||||
|
</g>
|
||||||
|
<!-- imopnxjmv7cwzyiecdw2saq42qvpnauh -->
|
||||||
|
<g id="node12" class="node">
|
||||||
|
<title>imopnxjmv7cwzyiecdw2saq42qvpnauh</title>
|
||||||
|
<path fill="#add8e6" stroke="#000000" stroke-width="4" d="M3003.3872,-1357.1002C3003.3872,-1357.1002 2606.752,-1357.1002 2606.752,-1357.1002 2600.752,-1357.1002 2594.752,-1351.1002 2594.752,-1345.1002 2594.752,-1345.1002 2594.752,-1282.4998 2594.752,-1282.4998 2594.752,-1276.4998 2600.752,-1270.4998 2606.752,-1270.4998 2606.752,-1270.4998 3003.3872,-1270.4998 3003.3872,-1270.4998 3009.3872,-1270.4998 3015.3872,-1276.4998 3015.3872,-1282.4998 3015.3872,-1282.4998 3015.3872,-1345.1002 3015.3872,-1345.1002 3015.3872,-1351.1002 3009.3872,-1357.1002 3003.3872,-1357.1002"/>
|
||||||
|
<text text-anchor="middle" x="2805.0696" y="-1306.6" font-family="Monaco" font-size="24.00" fill="#000000">parmetis@4.0.3%gcc@9.4.0/imopnxj</text>
|
||||||
|
</g>
|
||||||
|
<!-- idvshq5nqmygzd4uo62mdispwgxsw7id->imopnxjmv7cwzyiecdw2saq42qvpnauh -->
|
||||||
|
<g id="edge51" class="edge">
|
||||||
|
<title>idvshq5nqmygzd4uo62mdispwgxsw7id->imopnxjmv7cwzyiecdw2saq42qvpnauh</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M2393.6993,-1587.0809C2455.3565,-1569.7539 2521.1771,-1546.2699 2577.5864,-1515.1245 2649.1588,-1475.6656 2717.4141,-1409.6691 2759.9512,-1363.9364"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M2394.2404,-1589.0062C2456.0286,-1571.6376 2521.8491,-1548.1536 2578.5528,-1516.8755 2650.5491,-1477.1034 2718.8043,-1411.107 2761.4156,-1365.2986"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="2763.3454,-1366.8938 2767.5512,-1357.1695 2758.1992,-1362.1485 2763.3454,-1366.8938"/>
|
||||||
|
</g>
|
||||||
|
<!-- ern66gyp6qmhmpod4jaynxx4weoberfm -->
|
||||||
|
<g id="node13" class="node">
|
||||||
|
<title>ern66gyp6qmhmpod4jaynxx4weoberfm</title>
|
||||||
|
<path fill="#add8e6" stroke="#000000" stroke-width="4" d="M2928.3784,-1198.3002C2928.3784,-1198.3002 2563.7608,-1198.3002 2563.7608,-1198.3002 2557.7608,-1198.3002 2551.7608,-1192.3002 2551.7608,-1186.3002 2551.7608,-1186.3002 2551.7608,-1123.6998 2551.7608,-1123.6998 2551.7608,-1117.6998 2557.7608,-1111.6998 2563.7608,-1111.6998 2563.7608,-1111.6998 2928.3784,-1111.6998 2928.3784,-1111.6998 2934.3784,-1111.6998 2940.3784,-1117.6998 2940.3784,-1123.6998 2940.3784,-1123.6998 2940.3784,-1186.3002 2940.3784,-1186.3002 2940.3784,-1192.3002 2934.3784,-1198.3002 2928.3784,-1198.3002"/>
|
||||||
|
<text text-anchor="middle" x="2746.0696" y="-1147.8" font-family="Monaco" font-size="24.00" fill="#000000">metis@5.1.0%gcc@9.4.0/ern66gy</text>
|
||||||
|
</g>
|
||||||
|
<!-- idvshq5nqmygzd4uo62mdispwgxsw7id->ern66gyp6qmhmpod4jaynxx4weoberfm -->
|
||||||
|
<g id="edge25" class="edge">
|
||||||
|
<title>idvshq5nqmygzd4uo62mdispwgxsw7id->ern66gyp6qmhmpod4jaynxx4weoberfm</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M2371.6269,-1587.103C2443.5875,-1567.249 2513.691,-1542.0963 2537.3223,-1515.3355 2611.3482,-1433.6645 2525.4748,-1364.8484 2585.2274,-1269.8608 2602.2478,-1243.3473 2627.3929,-1221.1402 2652.8797,-1203.3777"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M2372.1589,-1589.0309C2444.2629,-1569.1315 2514.3664,-1543.9788 2538.8169,-1516.6645 2612.5989,-1432.1038 2526.7255,-1363.2878 2586.9118,-1270.9392 2603.5717,-1244.8464 2628.7168,-1222.6393 2654.0229,-1205.0188"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="2655.7411,-1206.8749 2662.0621,-1198.3722 2651.8184,-1201.0773 2655.7411,-1206.8749"/>
|
||||||
|
</g>
|
||||||
|
<!-- nqiyrxlid6tikfpvoqdpvsjt5drs2obf -->
|
||||||
|
<g id="node14" class="node">
|
||||||
|
<title>nqiyrxlid6tikfpvoqdpvsjt5drs2obf</title>
|
||||||
|
<path fill="#add8e6" stroke="#000000" stroke-width="4" d="M1964.017,-1357.1002C1964.017,-1357.1002 1532.1222,-1357.1002 1532.1222,-1357.1002 1526.1222,-1357.1002 1520.1222,-1351.1002 1520.1222,-1345.1002 1520.1222,-1345.1002 1520.1222,-1282.4998 1520.1222,-1282.4998 1520.1222,-1276.4998 1526.1222,-1270.4998 1532.1222,-1270.4998 1532.1222,-1270.4998 1964.017,-1270.4998 1964.017,-1270.4998 1970.017,-1270.4998 1976.017,-1276.4998 1976.017,-1282.4998 1976.017,-1282.4998 1976.017,-1345.1002 1976.017,-1345.1002 1976.017,-1351.1002 1970.017,-1357.1002 1964.017,-1357.1002"/>
|
||||||
|
<text text-anchor="middle" x="1748.0696" y="-1306.6" font-family="Monaco" font-size="24.00" fill="#000000">butterflypack@2.2.2%gcc@9.4.0/nqiyrxl</text>
|
||||||
|
</g>
|
||||||
|
<!-- idvshq5nqmygzd4uo62mdispwgxsw7id->nqiyrxlid6tikfpvoqdpvsjt5drs2obf -->
|
||||||
|
<g id="edge26" class="edge">
|
||||||
|
<title>idvshq5nqmygzd4uo62mdispwgxsw7id->nqiyrxlid6tikfpvoqdpvsjt5drs2obf</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M2118.5874,-1588.7094C2039.1194,-1530.0139 1897.9154,-1425.72 1814.4793,-1364.0937"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M2119.7757,-1587.1006C2040.3076,-1528.4052 1899.1036,-1424.1112 1815.6675,-1362.485"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1817.0581,-1360.404 1806.9348,-1357.2781 1812.8992,-1366.0347 1817.0581,-1360.404"/>
|
||||||
|
</g>
|
||||||
|
<!-- 4bu62kyfuh4ikdkuyxfxjxanf7e7qopu -->
|
||||||
|
<g id="node16" class="node">
|
||||||
|
<title>4bu62kyfuh4ikdkuyxfxjxanf7e7qopu</title>
|
||||||
|
<path fill="#add8e6" stroke="#000000" stroke-width="4" d="M1106.2192,-1515.9002C1106.2192,-1515.9002 683.92,-1515.9002 683.92,-1515.9002 677.92,-1515.9002 671.92,-1509.9002 671.92,-1503.9002 671.92,-1503.9002 671.92,-1441.2998 671.92,-1441.2998 671.92,-1435.2998 677.92,-1429.2998 683.92,-1429.2998 683.92,-1429.2998 1106.2192,-1429.2998 1106.2192,-1429.2998 1112.2192,-1429.2998 1118.2192,-1435.2998 1118.2192,-1441.2998 1118.2192,-1441.2998 1118.2192,-1503.9002 1118.2192,-1503.9002 1118.2192,-1509.9002 1112.2192,-1515.9002 1106.2192,-1515.9002"/>
|
||||||
|
<text text-anchor="middle" x="895.0696" y="-1465.4" font-family="Monaco" font-size="24.00" fill="#000000">slate@2022.07.00%gcc@9.4.0/4bu62ky</text>
|
||||||
|
</g>
|
||||||
|
<!-- idvshq5nqmygzd4uo62mdispwgxsw7id->4bu62kyfuh4ikdkuyxfxjxanf7e7qopu -->
|
||||||
|
<g id="edge5" class="edge">
|
||||||
|
<title>idvshq5nqmygzd4uo62mdispwgxsw7id->4bu62kyfuh4ikdkuyxfxjxanf7e7qopu</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1960.6663,-1605.4991C1729.5518,-1576.8935 1365.2868,-1531.8075 1128.237,-1502.4673"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M1960.912,-1603.5143C1729.7975,-1574.9086 1365.5325,-1529.8227 1128.4827,-1500.4825"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1128.5789,-1497.9754 1118.2247,-1500.2204 1127.719,-1504.9224 1128.5789,-1497.9754"/>
|
||||||
|
</g>
|
||||||
|
<!-- idvshq5nqmygzd4uo62mdispwgxsw7id->2w3nq3n3hcj2tqlvcpewsryamltlu5tw -->
|
||||||
|
<g id="edge20" class="edge">
|
||||||
|
<title>idvshq5nqmygzd4uo62mdispwgxsw7id->2w3nq3n3hcj2tqlvcpewsryamltlu5tw</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M2395.1113,-1591.5061C2621.5772,-1545.7968 2953.3457,-1462.5053 3023.2362,-1356.6473 3049.986,-1316.785 3021.2047,-1131.5143 3003.3326,-1112.2759 2971.8969,-1077.7826 2884.3944,-1052.6467 2789.1441,-1034.9179"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M2395.507,-1593.4665C2622.0642,-1547.7366 2953.8327,-1464.4452 3024.903,-1357.7527 3051.9623,-1316.478 3023.181,-1131.2073 3004.8066,-1110.9241 2972.4491,-1075.8603 2884.9466,-1050.7244 2789.5102,-1032.9517"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="2789.9449,-1030.4898 2779.4781,-1032.132 2788.6845,-1037.3754 2789.9449,-1030.4898"/>
|
||||||
|
<text text-anchor="middle" x="2611.7445" y="-1537.8321" font-family="Times,serif" font-size="14.00" fill="#000000">virtuals=mpi</text>
|
||||||
|
</g>
|
||||||
|
<!-- 7rzbmgoxhmm2jhellkgcjmn62uklf22x -->
|
||||||
|
<g id="node25" class="node">
|
||||||
|
<title>7rzbmgoxhmm2jhellkgcjmn62uklf22x</title>
|
||||||
|
<path fill="#add8e6" stroke="#000000" stroke-width="4" d="M1749.1952,-1515.9002C1749.1952,-1515.9002 1398.944,-1515.9002 1398.944,-1515.9002 1392.944,-1515.9002 1386.944,-1509.9002 1386.944,-1503.9002 1386.944,-1503.9002 1386.944,-1441.2998 1386.944,-1441.2998 1386.944,-1435.2998 1392.944,-1429.2998 1398.944,-1429.2998 1398.944,-1429.2998 1749.1952,-1429.2998 1749.1952,-1429.2998 1755.1952,-1429.2998 1761.1952,-1435.2998 1761.1952,-1441.2998 1761.1952,-1441.2998 1761.1952,-1503.9002 1761.1952,-1503.9002 1761.1952,-1509.9002 1755.1952,-1515.9002 1749.1952,-1515.9002"/>
|
||||||
|
<text text-anchor="middle" x="1574.0696" y="-1465.4" font-family="Monaco" font-size="24.00" fill="#000000">zfp@0.5.5%gcc@9.4.0/7rzbmgo</text>
|
||||||
|
</g>
|
||||||
|
<!-- idvshq5nqmygzd4uo62mdispwgxsw7id->7rzbmgoxhmm2jhellkgcjmn62uklf22x -->
|
||||||
|
<g id="edge36" class="edge">
|
||||||
|
<title>idvshq5nqmygzd4uo62mdispwgxsw7id->7rzbmgoxhmm2jhellkgcjmn62uklf22x</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M2012.7697,-1588.9743C1930.7903,-1567.4208 1831.729,-1541.3762 1748.4742,-1519.4874"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M2013.2782,-1587.0401C1931.2989,-1565.4866 1832.2376,-1539.442 1748.9827,-1517.5531"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1749.477,-1515.0982 1738.9157,-1515.9403 1747.697,-1521.8681 1749.477,-1515.0982"/>
|
||||||
|
</g>
|
||||||
|
<!-- idvshq5nqmygzd4uo62mdispwgxsw7id->gguve5icmo5e4cw5o3hvvfsxremc46if -->
|
||||||
|
<g id="edge3" class="edge">
|
||||||
|
<title>idvshq5nqmygzd4uo62mdispwgxsw7id->gguve5icmo5e4cw5o3hvvfsxremc46if</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M2229.2864,-1587.9836C2336.2076,-1492.3172 2562.5717,-1260.0833 2429.0696,-1111.6 2372.2327,-1048.3851 1860.8259,-1017.0375 1561.5401,-1003.9799"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1561.5673,-1000.4779 1551.4253,-1003.5421 1561.2645,-1007.4714 1561.5673,-1000.4779"/>
|
||||||
|
</g>
|
||||||
|
<!-- mujlx42xgttdc6u6rmiftsktpsrcmpbs -->
|
||||||
|
<g id="node5" class="node">
|
||||||
|
<title>mujlx42xgttdc6u6rmiftsktpsrcmpbs</title>
|
||||||
|
<path fill="#add8e6" stroke="#000000" stroke-width="4" d="M912.4048,-1198.3002C912.4048,-1198.3002 475.7344,-1198.3002 475.7344,-1198.3002 469.7344,-1198.3002 463.7344,-1192.3002 463.7344,-1186.3002 463.7344,-1186.3002 463.7344,-1123.6998 463.7344,-1123.6998 463.7344,-1117.6998 469.7344,-1111.6998 475.7344,-1111.6998 475.7344,-1111.6998 912.4048,-1111.6998 912.4048,-1111.6998 918.4048,-1111.6998 924.4048,-1117.6998 924.4048,-1123.6998 924.4048,-1123.6998 924.4048,-1186.3002 924.4048,-1186.3002 924.4048,-1192.3002 918.4048,-1198.3002 912.4048,-1198.3002"/>
|
||||||
|
<text text-anchor="middle" x="694.0696" y="-1147.8" font-family="Monaco" font-size="24.00" fill="#000000">blaspp@2022.07.00%gcc@9.4.0/mujlx42</text>
|
||||||
|
</g>
|
||||||
|
<!-- mujlx42xgttdc6u6rmiftsktpsrcmpbs->o524gebsxavobkte3k5fglgwnedfkadf -->
|
||||||
|
<g id="edge16" class="edge">
|
||||||
|
<title>mujlx42xgttdc6u6rmiftsktpsrcmpbs->o524gebsxavobkte3k5fglgwnedfkadf</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M693.0696,-1111.6072C693.0696,-1092.5263 693.0696,-1069.9257 693.0696,-1049.8046"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M695.0696,-1111.6072C695.0696,-1092.5263 695.0696,-1069.9257 695.0696,-1049.8046"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="697.5697,-1049.5403 694.0696,-1039.5403 690.5697,-1049.5404 697.5697,-1049.5403"/>
|
||||||
|
<text text-anchor="middle" x="657.8516" y="-1079.8482" font-family="Times,serif" font-size="14.00" fill="#000000">virtuals=blas</text>
|
||||||
|
</g>
|
||||||
|
<!-- mujlx42xgttdc6u6rmiftsktpsrcmpbs->gguve5icmo5e4cw5o3hvvfsxremc46if -->
|
||||||
|
<g id="edge28" class="edge">
|
||||||
|
<title>mujlx42xgttdc6u6rmiftsktpsrcmpbs->gguve5icmo5e4cw5o3hvvfsxremc46if</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M872.2315,-1111.6072C960.9952,-1089.988 1068.311,-1063.8504 1158.3512,-1041.9204"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1159.2354,-1045.3074 1168.1232,-1039.5403 1157.5789,-1038.5062 1159.2354,-1045.3074"/>
|
||||||
|
</g>
|
||||||
|
<!-- htzjns66gmq6pjofohp26djmjnpbegho -->
|
||||||
|
<g id="node6" class="node">
|
||||||
|
<title>htzjns66gmq6pjofohp26djmjnpbegho</title>
|
||||||
|
<path fill="#ff7f50" stroke="#000000" stroke-width="4" d="M2663.3553,-880.7002C2663.3553,-880.7002 2270.7839,-880.7002 2270.7839,-880.7002 2264.7839,-880.7002 2258.7839,-874.7002 2258.7839,-868.7002 2258.7839,-868.7002 2258.7839,-806.0998 2258.7839,-806.0998 2258.7839,-800.0998 2264.7839,-794.0998 2270.7839,-794.0998 2270.7839,-794.0998 2663.3553,-794.0998 2663.3553,-794.0998 2669.3553,-794.0998 2675.3553,-800.0998 2675.3553,-806.0998 2675.3553,-806.0998 2675.3553,-868.7002 2675.3553,-868.7002 2675.3553,-874.7002 2669.3553,-880.7002 2663.3553,-880.7002"/>
|
||||||
|
<text text-anchor="middle" x="2467.0696" y="-830.2" font-family="Monaco" font-size="24.00" fill="#000000">patchelf@0.16.1%gcc@9.4.0/htzjns6</text>
|
||||||
|
</g>
|
||||||
|
<!-- xm3ldz3y3msfdc3hzshvxpbpg5hnt6o6 -->
|
||||||
|
<g id="node15" class="node">
|
||||||
|
<title>xm3ldz3y3msfdc3hzshvxpbpg5hnt6o6</title>
|
||||||
|
<path fill="#ff7f50" stroke="#000000" stroke-width="4" d="M394.2232,-404.3002C394.2232,-404.3002 17.916,-404.3002 17.916,-404.3002 11.916,-404.3002 5.916,-398.3002 5.916,-392.3002 5.916,-392.3002 5.916,-329.6998 5.916,-329.6998 5.916,-323.6998 11.916,-317.6998 17.916,-317.6998 17.916,-317.6998 394.2232,-317.6998 394.2232,-317.6998 400.2232,-317.6998 406.2232,-323.6998 406.2232,-329.6998 406.2232,-329.6998 406.2232,-392.3002 406.2232,-392.3002 406.2232,-398.3002 400.2232,-404.3002 394.2232,-404.3002"/>
|
||||||
|
<text text-anchor="middle" x="206.0696" y="-353.8" font-family="Monaco" font-size="24.00" fill="#000000">diffutils@3.8%gcc@9.4.0/xm3ldz3</text>
|
||||||
|
</g>
|
||||||
|
<!-- h3ujmb3ts4kxxxv77knh2knuystuerbx->xm3ldz3y3msfdc3hzshvxpbpg5hnt6o6 -->
|
||||||
|
<g id="edge1" class="edge">
|
||||||
|
<title>h3ujmb3ts4kxxxv77knh2knuystuerbx->xm3ldz3y3msfdc3hzshvxpbpg5hnt6o6</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M206.0696,-476.4072C206.0696,-457.3263 206.0696,-434.7257 206.0696,-414.6046"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="209.5697,-414.3403 206.0696,-404.3403 202.5697,-414.3404 209.5697,-414.3403"/>
|
||||||
|
</g>
|
||||||
|
<!-- o524gebsxavobkte3k5fglgwnedfkadf->ywrpvv2hgooeepdke33exkqrtdpd5gkl -->
|
||||||
|
<g id="edge11" class="edge">
|
||||||
|
<title>o524gebsxavobkte3k5fglgwnedfkadf->ywrpvv2hgooeepdke33exkqrtdpd5gkl</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M690.0981,-952.705C684.8522,-895.2533 675.6173,-794.1153 669.9514,-732.0637"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="673.4345,-731.7184 669.0396,-722.0781 666.4635,-732.355 673.4345,-731.7184"/>
|
||||||
|
</g>
|
||||||
|
<!-- 4vsmjofkhntilgzh4zebluqak5mdsu3x -->
|
||||||
|
<g id="node9" class="node">
|
||||||
|
<title>4vsmjofkhntilgzh4zebluqak5mdsu3x</title>
|
||||||
|
<path fill="#ff7f50" stroke="#000000" stroke-width="4" d="M1977.9121,-721.9002C1977.9121,-721.9002 1386.2271,-721.9002 1386.2271,-721.9002 1380.2271,-721.9002 1374.2271,-715.9002 1374.2271,-709.9002 1374.2271,-709.9002 1374.2271,-647.2998 1374.2271,-647.2998 1374.2271,-641.2998 1380.2271,-635.2998 1386.2271,-635.2998 1386.2271,-635.2998 1977.9121,-635.2998 1977.9121,-635.2998 1983.9121,-635.2998 1989.9121,-641.2998 1989.9121,-647.2998 1989.9121,-647.2998 1989.9121,-709.9002 1989.9121,-709.9002 1989.9121,-715.9002 1983.9121,-721.9002 1977.9121,-721.9002"/>
|
||||||
|
<text text-anchor="middle" x="1682.0696" y="-671.4" font-family="Monaco" font-size="24.00" fill="#000000">ca-certificates-mozilla@2023-01-10%gcc@9.4.0/4vsmjof</text>
|
||||||
|
</g>
|
||||||
|
<!-- xiro2z6na56qdd4czjhj54eag3ekbiow -->
|
||||||
|
<g id="node10" class="node">
|
||||||
|
<title>xiro2z6na56qdd4czjhj54eag3ekbiow</title>
|
||||||
|
<path fill="#add8e6" stroke="#000000" stroke-width="4" d="M988.1824,-1357.1002C988.1824,-1357.1002 533.9568,-1357.1002 533.9568,-1357.1002 527.9568,-1357.1002 521.9568,-1351.1002 521.9568,-1345.1002 521.9568,-1345.1002 521.9568,-1282.4998 521.9568,-1282.4998 521.9568,-1276.4998 527.9568,-1270.4998 533.9568,-1270.4998 533.9568,-1270.4998 988.1824,-1270.4998 988.1824,-1270.4998 994.1824,-1270.4998 1000.1824,-1276.4998 1000.1824,-1282.4998 1000.1824,-1282.4998 1000.1824,-1345.1002 1000.1824,-1345.1002 1000.1824,-1351.1002 994.1824,-1357.1002 988.1824,-1357.1002"/>
|
||||||
|
<text text-anchor="middle" x="761.0696" y="-1306.6" font-family="Monaco" font-size="24.00" fill="#000000">lapackpp@2022.07.00%gcc@9.4.0/xiro2z6</text>
|
||||||
|
</g>
|
||||||
|
<!-- xiro2z6na56qdd4czjhj54eag3ekbiow->mujlx42xgttdc6u6rmiftsktpsrcmpbs -->
|
||||||
|
<g id="edge37" class="edge">
|
||||||
|
<title>xiro2z6na56qdd4czjhj54eag3ekbiow->mujlx42xgttdc6u6rmiftsktpsrcmpbs</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M741.8402,-1270.7959C733.6789,-1251.4525 723.9915,-1228.4917 715.4149,-1208.1641"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M743.6829,-1270.0185C735.5216,-1250.675 725.8342,-1227.7143 717.2576,-1207.3866"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="719.4676,-1206.1933 712.3555,-1198.3403 713.0181,-1208.9144 719.4676,-1206.1933"/>
|
||||||
|
</g>
|
||||||
|
<!-- xiro2z6na56qdd4czjhj54eag3ekbiow->o524gebsxavobkte3k5fglgwnedfkadf -->
|
||||||
|
<g id="edge35" class="edge">
|
||||||
|
<title>xiro2z6na56qdd4czjhj54eag3ekbiow->o524gebsxavobkte3k5fglgwnedfkadf</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M597.2326,-1271.3826C534.1471,-1251.0571 472.8527,-1225.5904 454.2471,-1198.9688 432.1275,-1166.6075 433.5639,-1144.2113 454.2226,-1111.0684 472.6194,-1081.8657 500.3255,-1060.004 530.6572,-1043.4601"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M597.8458,-1269.4789C534.9144,-1249.2102 473.6201,-1223.7435 455.8921,-1197.8312 434.1234,-1166.7355 435.5598,-1144.3393 455.9166,-1112.1316 473.8583,-1083.4358 501.5644,-1061.5741 531.6142,-1045.2163"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="532.9062,-1047.362 540.1422,-1039.6231 529.6595,-1041.1605 532.9062,-1047.362"/>
|
||||||
|
<text text-anchor="middle" x="474.3109" y="-1250.2598" font-family="Times,serif" font-size="14.00" fill="#000000">virtuals=blas,lapack</text>
|
||||||
|
</g>
|
||||||
|
<!-- xiro2z6na56qdd4czjhj54eag3ekbiow->gguve5icmo5e4cw5o3hvvfsxremc46if -->
|
||||||
|
<g id="edge45" class="edge">
|
||||||
|
<title>xiro2z6na56qdd4czjhj54eag3ekbiow->gguve5icmo5e4cw5o3hvvfsxremc46if</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M833.5823,-1270.3956C865.3249,-1250.0918 902.2709,-1224.6296 933.0696,-1198.4 973.2414,-1164.1878 969.8532,-1140.395 1014.0696,-1111.6 1058.5051,-1082.6623 1111.0286,-1060.0733 1161.029,-1042.8573"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1162.313,-1046.1177 1170.6621,-1039.5953 1160.0678,-1039.4876 1162.313,-1046.1177"/>
|
||||||
|
</g>
|
||||||
|
<!-- j5rupoqliu7kasm6xndl7ui32wgawkru -->
|
||||||
|
<g id="node11" class="node">
|
||||||
|
<title>j5rupoqliu7kasm6xndl7ui32wgawkru</title>
|
||||||
|
<path fill="#add8e6" stroke="#000000" stroke-width="4" d="M1527.3625,-245.5002C1527.3625,-245.5002 1164.7767,-245.5002 1164.7767,-245.5002 1158.7767,-245.5002 1152.7767,-239.5002 1152.7767,-233.5002 1152.7767,-233.5002 1152.7767,-170.8998 1152.7767,-170.8998 1152.7767,-164.8998 1158.7767,-158.8998 1164.7767,-158.8998 1164.7767,-158.8998 1527.3625,-158.8998 1527.3625,-158.8998 1533.3625,-158.8998 1539.3625,-164.8998 1539.3625,-170.8998 1539.3625,-170.8998 1539.3625,-233.5002 1539.3625,-233.5002 1539.3625,-239.5002 1533.3625,-245.5002 1527.3625,-245.5002"/>
|
||||||
|
<text text-anchor="middle" x="1346.0696" y="-195" font-family="Monaco" font-size="24.00" fill="#000000">ncurses@6.4%gcc@9.4.0/j5rupoq</text>
|
||||||
|
</g>
|
||||||
|
<!-- j5rupoqliu7kasm6xndl7ui32wgawkru->i4avrindvhcamhurzbfdaggbj2zgsrrh -->
|
||||||
|
<g id="edge15" class="edge">
|
||||||
|
<title>j5rupoqliu7kasm6xndl7ui32wgawkru->i4avrindvhcamhurzbfdaggbj2zgsrrh</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1346.0696,-158.8072C1346.0696,-139.7263 1346.0696,-117.1257 1346.0696,-97.0046"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1349.5697,-96.7403 1346.0696,-86.7403 1342.5697,-96.7404 1349.5697,-96.7403"/>
|
||||||
|
<text text-anchor="middle" x="1292.7436" y="-127.0482" font-family="Times,serif" font-size="14.00" fill="#000000">virtuals=pkgconfig</text>
|
||||||
|
</g>
|
||||||
|
<!-- imopnxjmv7cwzyiecdw2saq42qvpnauh->ern66gyp6qmhmpod4jaynxx4weoberfm -->
|
||||||
|
<g id="edge19" class="edge">
|
||||||
|
<title>imopnxjmv7cwzyiecdw2saq42qvpnauh->ern66gyp6qmhmpod4jaynxx4weoberfm</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M2788.0102,-1270.7555C2780.8234,-1251.412 2772.2926,-1228.4513 2764.7402,-1208.1236"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M2789.885,-1270.0589C2782.6982,-1250.7155 2774.1674,-1227.7547 2766.615,-1207.4271"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="2768.9358,-1206.4953 2762.1721,-1198.3403 2762.3741,-1208.9332 2768.9358,-1206.4953"/>
|
||||||
|
</g>
|
||||||
|
<!-- imopnxjmv7cwzyiecdw2saq42qvpnauh->2w3nq3n3hcj2tqlvcpewsryamltlu5tw -->
|
||||||
|
<g id="edge12" class="edge">
|
||||||
|
<title>imopnxjmv7cwzyiecdw2saq42qvpnauh->2w3nq3n3hcj2tqlvcpewsryamltlu5tw</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M2907.2846,-1269.5018C2936.475,-1251.8137 2964.9158,-1228.1116 2981.1904,-1197.9236 2999.477,-1164.2363 3005.2125,-1141.4693 2981.289,-1112.225 2954.5472,-1078.5579 2876.5297,-1053.8974 2789.2983,-1036.3535"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M2908.3216,-1271.2119C2937.7554,-1253.3501 2966.1962,-1229.648 2982.9488,-1198.8764 3001.4164,-1164.7249 3007.1519,-1141.9579 2982.8502,-1110.975 2955.15,-1076.6509 2877.1325,-1051.9904 2789.6927,-1034.3928"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="2790.125,-1031.93 2779.6364,-1033.4269 2788.7692,-1038.7974 2790.125,-1031.93"/>
|
||||||
|
<text text-anchor="middle" x="2836.0561" y="-1059.5023" font-family="Times,serif" font-size="14.00" fill="#000000">virtuals=mpi</text>
|
||||||
|
</g>
|
||||||
|
<!-- imopnxjmv7cwzyiecdw2saq42qvpnauh->gguve5icmo5e4cw5o3hvvfsxremc46if -->
|
||||||
|
<g id="edge49" class="edge">
|
||||||
|
<title>imopnxjmv7cwzyiecdw2saq42qvpnauh->gguve5icmo5e4cw5o3hvvfsxremc46if</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M2883.731,-1270.4691C2909.4451,-1251.9243 2934.9956,-1227.7144 2949.0696,-1198.4 2965.7663,-1163.6227 2975.3506,-1139.841 2949.0696,-1111.6 2925.7161,-1086.5049 1993.0368,-1031.9055 1561.3071,-1007.9103"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1561.3813,-1004.4092 1551.2026,-1007.3492 1560.9931,-1011.3984 1561.3813,-1004.4092"/>
|
||||||
|
</g>
|
||||||
|
<!-- ern66gyp6qmhmpod4jaynxx4weoberfm->gguve5icmo5e4cw5o3hvvfsxremc46if -->
|
||||||
|
<g id="edge50" class="edge">
|
||||||
|
<title>ern66gyp6qmhmpod4jaynxx4weoberfm->gguve5icmo5e4cw5o3hvvfsxremc46if</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M2551.6031,-1113.7387C2547.0531,-1112.9948 2542.537,-1112.2802 2538.0696,-1111.6 2198.5338,-1059.8997 1800.8632,-1026.8711 1561.4583,-1009.9443"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1561.4619,-1006.436 1551.2407,-1009.2249 1560.9702,-1013.4187 1561.4619,-1006.436"/>
|
||||||
|
</g>
|
||||||
|
<!-- nqiyrxlid6tikfpvoqdpvsjt5drs2obf->hkcrbrtf2qex6rvzuok5tzdrbam55pdn -->
|
||||||
|
<g id="edge34" class="edge">
|
||||||
|
<title>nqiyrxlid6tikfpvoqdpvsjt5drs2obf->hkcrbrtf2qex6rvzuok5tzdrbam55pdn</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1865.2226,-1269.4691C1922.6966,-1248.2438 1991.964,-1222.6632 2050.6644,-1200.985"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M1865.9154,-1271.3453C1923.3894,-1250.12 1992.6569,-1224.5394 2051.3572,-1202.8612"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="2052.5441,-1205.088 2060.7123,-1198.3403 2050.119,-1198.5215 2052.5441,-1205.088"/>
|
||||||
|
<text text-anchor="middle" x="1910.9073" y="-1238.6056" font-family="Times,serif" font-size="14.00" fill="#000000">virtuals=scalapack</text>
|
||||||
|
</g>
|
||||||
|
<!-- nqiyrxlid6tikfpvoqdpvsjt5drs2obf->o524gebsxavobkte3k5fglgwnedfkadf -->
|
||||||
|
<g id="edge52" class="edge">
|
||||||
|
<title>nqiyrxlid6tikfpvoqdpvsjt5drs2obf->o524gebsxavobkte3k5fglgwnedfkadf</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1519.9696,-1290.6844C1394.6018,-1273.3057 1237.6631,-1244.7294 1102.7507,-1199.3478 1021.8138,-1171.8729 1008.1992,-1149.8608 932.6248,-1112.4956 887.1715,-1089.9216 836.578,-1065.4054 793.6914,-1044.8018"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M1520.2442,-1288.7034C1394.9601,-1271.3381 1238.0214,-1242.7618 1103.3885,-1197.4522 1023.5148,-1170.8208 1009.9002,-1148.8087 933.5144,-1110.7044 888.0436,-1088.1218 837.4502,-1063.6056 794.5574,-1042.999"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="795.6235,-1040.7377 785.0938,-1039.565 792.5939,-1047.0482 795.6235,-1040.7377"/>
|
||||||
|
<text text-anchor="middle" x="1046.8307" y="-1202.5988" font-family="Times,serif" font-size="14.00" fill="#000000">virtuals=blas,lapack</text>
|
||||||
|
</g>
|
||||||
|
<!-- lfh3aovn65e66cs24qiehq3nd2ddojef -->
|
||||||
|
<g id="node21" class="node">
|
||||||
|
<title>lfh3aovn65e66cs24qiehq3nd2ddojef</title>
|
||||||
|
<path fill="#add8e6" stroke="#000000" stroke-width="4" d="M1547.9922,-1198.3002C1547.9922,-1198.3002 1144.147,-1198.3002 1144.147,-1198.3002 1138.147,-1198.3002 1132.147,-1192.3002 1132.147,-1186.3002 1132.147,-1186.3002 1132.147,-1123.6998 1132.147,-1123.6998 1132.147,-1117.6998 1138.147,-1111.6998 1144.147,-1111.6998 1144.147,-1111.6998 1547.9922,-1111.6998 1547.9922,-1111.6998 1553.9922,-1111.6998 1559.9922,-1117.6998 1559.9922,-1123.6998 1559.9922,-1123.6998 1559.9922,-1186.3002 1559.9922,-1186.3002 1559.9922,-1192.3002 1553.9922,-1198.3002 1547.9922,-1198.3002"/>
|
||||||
|
<text text-anchor="middle" x="1346.0696" y="-1147.8" font-family="Monaco" font-size="24.00" fill="#000000">arpack-ng@3.8.0%gcc@9.4.0/lfh3aov</text>
|
||||||
|
</g>
|
||||||
|
<!-- nqiyrxlid6tikfpvoqdpvsjt5drs2obf->lfh3aovn65e66cs24qiehq3nd2ddojef -->
|
||||||
|
<g id="edge46" class="edge">
|
||||||
|
<title>nqiyrxlid6tikfpvoqdpvsjt5drs2obf->lfh3aovn65e66cs24qiehq3nd2ddojef</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1637.8539,-1271.3373C1584.2332,-1250.1557 1519.6324,-1224.6368 1464.827,-1202.9873"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M1638.5887,-1269.4771C1584.968,-1248.2956 1520.3672,-1222.7767 1465.5618,-1201.1272"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1466.3716,-1198.7592 1455.785,-1198.3403 1463.7998,-1205.2696 1466.3716,-1198.7592"/>
|
||||||
|
</g>
|
||||||
|
<!-- 57joith2sqq6sehge54vlloyolm36mdu -->
|
||||||
|
<g id="node22" class="node">
|
||||||
|
<title>57joith2sqq6sehge54vlloyolm36mdu</title>
|
||||||
|
<path fill="#ff7f50" stroke="#000000" stroke-width="4" d="M1906.2352,-1198.3002C1906.2352,-1198.3002 1589.904,-1198.3002 1589.904,-1198.3002 1583.904,-1198.3002 1577.904,-1192.3002 1577.904,-1186.3002 1577.904,-1186.3002 1577.904,-1123.6998 1577.904,-1123.6998 1577.904,-1117.6998 1583.904,-1111.6998 1589.904,-1111.6998 1589.904,-1111.6998 1906.2352,-1111.6998 1906.2352,-1111.6998 1912.2352,-1111.6998 1918.2352,-1117.6998 1918.2352,-1123.6998 1918.2352,-1123.6998 1918.2352,-1186.3002 1918.2352,-1186.3002 1918.2352,-1192.3002 1912.2352,-1198.3002 1906.2352,-1198.3002"/>
|
||||||
|
<text text-anchor="middle" x="1748.0696" y="-1147.8" font-family="Monaco" font-size="24.00" fill="#000000">sed@4.8%gcc@9.4.0/57joith</text>
|
||||||
|
</g>
|
||||||
|
<!-- nqiyrxlid6tikfpvoqdpvsjt5drs2obf->57joith2sqq6sehge54vlloyolm36mdu -->
|
||||||
|
<g id="edge27" class="edge">
|
||||||
|
<title>nqiyrxlid6tikfpvoqdpvsjt5drs2obf->57joith2sqq6sehge54vlloyolm36mdu</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1748.0696,-1270.4072C1748.0696,-1251.3263 1748.0696,-1228.7257 1748.0696,-1208.6046"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1751.5697,-1208.3403 1748.0696,-1198.3403 1744.5697,-1208.3404 1751.5697,-1208.3403"/>
|
||||||
|
</g>
|
||||||
|
<!-- nqiyrxlid6tikfpvoqdpvsjt5drs2obf->2w3nq3n3hcj2tqlvcpewsryamltlu5tw -->
|
||||||
|
<g id="edge24" class="edge">
|
||||||
|
<title>nqiyrxlid6tikfpvoqdpvsjt5drs2obf->2w3nq3n3hcj2tqlvcpewsryamltlu5tw</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1975.9734,-1301.684C2148.2819,-1288.3961 2365.6859,-1259.5384 2428.3689,-1197.6866 2466.9261,-1160.1438 2472.9783,-1095.7153 2471.5152,-1049.9701"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M1976.1272,-1303.678C2148.5451,-1290.3788 2365.949,-1261.521 2429.7703,-1199.1134 2468.9173,-1160.3309 2474.9695,-1095.9024 2473.5142,-1049.9065"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="2476.0078,-1049.7027 2472.0657,-1039.8686 2469.0147,-1050.0146 2476.0078,-1049.7027"/>
|
||||||
|
<text text-anchor="middle" x="2207.8884" y="-1273.0053" font-family="Times,serif" font-size="14.00" fill="#000000">virtuals=mpi</text>
|
||||||
|
</g>
|
||||||
|
<!-- nqiyrxlid6tikfpvoqdpvsjt5drs2obf->gguve5icmo5e4cw5o3hvvfsxremc46if -->
|
||||||
|
<g id="edge6" class="edge">
|
||||||
|
<title>nqiyrxlid6tikfpvoqdpvsjt5drs2obf->gguve5icmo5e4cw5o3hvvfsxremc46if</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1520.1614,-1301.6771C1362.9712,-1287.992 1173.582,-1259.0928 1123.0696,-1198.4 1098.3914,-1168.7481 1103.0165,-1144.5563 1123.0696,-1111.6 1140.5998,-1082.79 1167.9002,-1060.8539 1197.4647,-1044.2681"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1199.1408,-1047.3408 1206.2789,-1039.5114 1195.8163,-1041.1806 1199.1408,-1047.3408"/>
|
||||||
|
</g>
|
||||||
|
<!-- ogcucq2eod3xusvvied5ol2iobui4nsb -->
|
||||||
|
<g id="node18" class="node">
|
||||||
|
<title>ogcucq2eod3xusvvied5ol2iobui4nsb</title>
|
||||||
|
<path fill="#ff7f50" stroke="#000000" stroke-width="4" d="M400.2088,-245.5002C400.2088,-245.5002 11.9304,-245.5002 11.9304,-245.5002 5.9304,-245.5002 -.0696,-239.5002 -.0696,-233.5002 -.0696,-233.5002 -.0696,-170.8998 -.0696,-170.8998 -.0696,-164.8998 5.9304,-158.8998 11.9304,-158.8998 11.9304,-158.8998 400.2088,-158.8998 400.2088,-158.8998 406.2088,-158.8998 412.2088,-164.8998 412.2088,-170.8998 412.2088,-170.8998 412.2088,-233.5002 412.2088,-233.5002 412.2088,-239.5002 406.2088,-245.5002 400.2088,-245.5002"/>
|
||||||
|
<text text-anchor="middle" x="206.0696" y="-195" font-family="Monaco" font-size="24.00" fill="#000000">libiconv@1.17%gcc@9.4.0/ogcucq2</text>
|
||||||
|
</g>
|
||||||
|
<!-- xm3ldz3y3msfdc3hzshvxpbpg5hnt6o6->ogcucq2eod3xusvvied5ol2iobui4nsb -->
|
||||||
|
<g id="edge47" class="edge">
|
||||||
|
<title>xm3ldz3y3msfdc3hzshvxpbpg5hnt6o6->ogcucq2eod3xusvvied5ol2iobui4nsb</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M205.0696,-317.6072C205.0696,-298.5263 205.0696,-275.9257 205.0696,-255.8046"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M207.0696,-317.6072C207.0696,-298.5263 207.0696,-275.9257 207.0696,-255.8046"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="209.5697,-255.5403 206.0696,-245.5403 202.5697,-255.5404 209.5697,-255.5403"/>
|
||||||
|
<text text-anchor="middle" x="165.5739" y="-285.8482" font-family="Times,serif" font-size="14.00" fill="#000000">virtuals=iconv</text>
|
||||||
|
</g>
|
||||||
|
<!-- 4bu62kyfuh4ikdkuyxfxjxanf7e7qopu->mujlx42xgttdc6u6rmiftsktpsrcmpbs -->
|
||||||
|
<g id="edge42" class="edge">
|
||||||
|
<title>4bu62kyfuh4ikdkuyxfxjxanf7e7qopu->mujlx42xgttdc6u6rmiftsktpsrcmpbs</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M672.6614,-1430.2151C600.7916,-1411.3548 534.1254,-1386.9583 512.2667,-1357.7962 489.0909,-1326.029 493.54,-1304.0273 512.1928,-1269.9192 527.5256,-1242.0821 552.3382,-1220.1508 578.9347,-1203.0434"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M673.169,-1428.2806C601.4789,-1409.4766 534.8127,-1385.0802 513.8725,-1356.6038 491.0512,-1326.4254 495.5003,-1304.4237 513.9464,-1270.8808 528.8502,-1243.5806 553.6627,-1221.6493 580.016,-1204.7259"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="581.46,-1206.7724 588.1193,-1198.532 577.7747,-1200.8211 581.46,-1206.7724"/>
|
||||||
|
</g>
|
||||||
|
<!-- 4bu62kyfuh4ikdkuyxfxjxanf7e7qopu->o524gebsxavobkte3k5fglgwnedfkadf -->
|
||||||
|
<g id="edge43" class="edge">
|
||||||
|
<title>4bu62kyfuh4ikdkuyxfxjxanf7e7qopu->o524gebsxavobkte3k5fglgwnedfkadf</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M680.4783,-1430.2246C600.8632,-1410.3933 522.8724,-1385.2921 493.3877,-1357.9314 411.1392,-1281.1573 374.1678,-1206.1582 435.2305,-1111.0561 454.3431,-1081.6726 482.5021,-1059.8261 513.5088,-1043.3725"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M680.9617,-1428.2839C601.476,-1408.4895 523.4851,-1383.3883 494.7515,-1356.4686 412.9331,-1280.273 375.9616,-1205.2739 436.9087,-1112.1439 455.569,-1083.2528 483.728,-1061.4063 514.4455,-1045.1396"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="515.8631,-1047.2236 523.1893,-1039.5699 512.6893,-1040.9844 515.8631,-1047.2236"/>
|
||||||
|
<text text-anchor="middle" x="453.0969" y="-1356.92" font-family="Times,serif" font-size="14.00" fill="#000000">virtuals=blas</text>
|
||||||
|
</g>
|
||||||
|
<!-- 4bu62kyfuh4ikdkuyxfxjxanf7e7qopu->xiro2z6na56qdd4czjhj54eag3ekbiow -->
|
||||||
|
<g id="edge38" class="edge">
|
||||||
|
<title>4bu62kyfuh4ikdkuyxfxjxanf7e7qopu->xiro2z6na56qdd4czjhj54eag3ekbiow</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M857.6892,-1429.8521C840.9235,-1409.9835 820.9375,-1386.2985 803.4466,-1365.5705"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M859.2178,-1428.5623C842.4521,-1408.6937 822.466,-1385.0087 804.9751,-1364.2807"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="806.7654,-1362.5258 797.6414,-1357.1403 801.4156,-1367.0402 806.7654,-1362.5258"/>
|
||||||
|
</g>
|
||||||
|
<!-- 4bu62kyfuh4ikdkuyxfxjxanf7e7qopu->2w3nq3n3hcj2tqlvcpewsryamltlu5tw -->
|
||||||
|
<g id="edge13" class="edge">
|
||||||
|
<title>4bu62kyfuh4ikdkuyxfxjxanf7e7qopu->2w3nq3n3hcj2tqlvcpewsryamltlu5tw</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1118.1783,-1450.5735C1412.4221,-1422.447 1902.6188,-1374.0528 1984.8578,-1356.2227 2203.916,-1308.9943 2329.6342,-1377.1305 2461.2658,-1197.8052 2492.3675,-1156.1664 2488.743,-1094.1171 2480.3694,-1050.0521"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M1118.3686,-1452.5644C1412.6186,-1424.4374 1902.8153,-1376.0432 1985.2814,-1358.1773 2202.963,-1310.7526 2328.6812,-1378.8889 2462.8734,-1198.9948 2494.3641,-1156.0498 2490.7395,-1094.0005 2482.3343,-1049.6791"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="2484.7438,-1048.9818 2479.3189,-1039.8812 2477.8845,-1050.3784 2484.7438,-1048.9818"/>
|
||||||
|
<text text-anchor="middle" x="1820.4407" y="-1379.7188" font-family="Times,serif" font-size="14.00" fill="#000000">virtuals=mpi</text>
|
||||||
|
</g>
|
||||||
|
<!-- 4bu62kyfuh4ikdkuyxfxjxanf7e7qopu->gguve5icmo5e4cw5o3hvvfsxremc46if -->
|
||||||
|
<g id="edge32" class="edge">
|
||||||
|
<title>4bu62kyfuh4ikdkuyxfxjxanf7e7qopu->gguve5icmo5e4cw5o3hvvfsxremc46if</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M947.2173,-1428.5496C968.7089,-1408.5917 992.2747,-1383.3345 1008.2117,-1356.6861 1067.0588,-1259.8646 1008.3745,-1197.6371 1084.3226,-1110.9351 1110.3076,-1081.7965 1144.7149,-1059.7578 1180.1804,-1043.0531"/>
|
||||||
|
<path fill="none" stroke="#daa520" stroke-width="2" d="M948.5783,-1430.0151C970.1712,-1409.9561 993.737,-1384.6989 1009.9275,-1357.7139 1068.5139,-1258.4924 1009.8295,-1196.2649 1085.8166,-1112.2649 1111.3864,-1083.4807 1145.7936,-1061.442 1181.0322,-1044.8626"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1182.4567,-1046.9607 1190.1008,-1039.6246 1179.5503,-1040.5926 1182.4567,-1046.9607"/>
|
||||||
|
</g>
|
||||||
|
<!-- 5xerf6imlgo4xlubacr4mljacc3edexo -->
|
||||||
|
<g id="node17" class="node">
|
||||||
|
<title>5xerf6imlgo4xlubacr4mljacc3edexo</title>
|
||||||
|
<path fill="#add8e6" stroke="#000000" stroke-width="4" d="M1822.3657,-880.7002C1822.3657,-880.7002 1437.7735,-880.7002 1437.7735,-880.7002 1431.7735,-880.7002 1425.7735,-874.7002 1425.7735,-868.7002 1425.7735,-868.7002 1425.7735,-806.0998 1425.7735,-806.0998 1425.7735,-800.0998 1431.7735,-794.0998 1437.7735,-794.0998 1437.7735,-794.0998 1822.3657,-794.0998 1822.3657,-794.0998 1828.3657,-794.0998 1834.3657,-800.0998 1834.3657,-806.0998 1834.3657,-806.0998 1834.3657,-868.7002 1834.3657,-868.7002 1834.3657,-874.7002 1828.3657,-880.7002 1822.3657,-880.7002"/>
|
||||||
|
<text text-anchor="middle" x="1630.0696" y="-830.2" font-family="Monaco" font-size="24.00" fill="#000000">openssl@1.1.1s%gcc@9.4.0/5xerf6i</text>
|
||||||
|
</g>
|
||||||
|
<!-- 5xerf6imlgo4xlubacr4mljacc3edexo->ywrpvv2hgooeepdke33exkqrtdpd5gkl -->
|
||||||
|
<g id="edge22" class="edge">
|
||||||
|
<title>5xerf6imlgo4xlubacr4mljacc3edexo->ywrpvv2hgooeepdke33exkqrtdpd5gkl</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1425.7129,-803.7711C1262.7545,-776.9548 1035.5151,-739.5603 871.9084,-712.6373"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="872.1525,-709.1305 861.7169,-710.9602 871.0158,-716.0376 872.1525,-709.1305"/>
|
||||||
|
</g>
|
||||||
|
<!-- 5xerf6imlgo4xlubacr4mljacc3edexo->4vsmjofkhntilgzh4zebluqak5mdsu3x -->
|
||||||
|
<g id="edge48" class="edge">
|
||||||
|
<title>5xerf6imlgo4xlubacr4mljacc3edexo->4vsmjofkhntilgzh4zebluqak5mdsu3x</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1644.2788,-794.0072C1650.5843,-774.7513 1658.0636,-751.9107 1664.6976,-731.6514"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1668.0917,-732.533 1667.8776,-721.9403 1661.4393,-730.3546 1668.0917,-732.533"/>
|
||||||
|
</g>
|
||||||
|
<!-- 5xerf6imlgo4xlubacr4mljacc3edexo->nizxi5u5bbrzhzwfy2qb7hatlhuswlrz -->
|
||||||
|
<g id="edge41" class="edge">
|
||||||
|
<title>5xerf6imlgo4xlubacr4mljacc3edexo->nizxi5u5bbrzhzwfy2qb7hatlhuswlrz</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1834.3289,-793.5645C1906.6817,-774.1673 1975.9199,-749.2273 1998.2925,-721.3707 2031.5218,-680.681 2032.1636,-617.9031 2027.044,-573.3921"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M1834.8468,-795.4962C1907.3595,-776.0489 1976.5977,-751.1089 1999.8467,-722.6293 2033.5217,-680.7015 2034.1635,-617.9235 2029.0309,-573.1639"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="2031.4885,-572.6712 2026.7474,-563.1964 2024.5451,-573.5598 2031.4885,-572.6712"/>
|
||||||
|
</g>
|
||||||
|
<!-- v32wejd4d5lc6uka4qlrogwh5xae2h3r -->
|
||||||
|
<g id="node26" class="node">
|
||||||
|
<title>v32wejd4d5lc6uka4qlrogwh5xae2h3r</title>
|
||||||
|
<path fill="#ff7f50" stroke="#000000" stroke-width="4" d="M1306.1776,-404.3002C1306.1776,-404.3002 929.9616,-404.3002 929.9616,-404.3002 923.9616,-404.3002 917.9616,-398.3002 917.9616,-392.3002 917.9616,-392.3002 917.9616,-329.6998 917.9616,-329.6998 917.9616,-323.6998 923.9616,-317.6998 929.9616,-317.6998 929.9616,-317.6998 1306.1776,-317.6998 1306.1776,-317.6998 1312.1776,-317.6998 1318.1776,-323.6998 1318.1776,-329.6998 1318.1776,-329.6998 1318.1776,-392.3002 1318.1776,-392.3002 1318.1776,-398.3002 1312.1776,-404.3002 1306.1776,-404.3002"/>
|
||||||
|
<text text-anchor="middle" x="1118.0696" y="-353.8" font-family="Monaco" font-size="24.00" fill="#000000">readline@8.2%gcc@9.4.0/v32wejd</text>
|
||||||
|
</g>
|
||||||
|
<!-- uabgssx6lsgrevwbttslldnr5nzguprj->v32wejd4d5lc6uka4qlrogwh5xae2h3r -->
|
||||||
|
<g id="edge7" class="edge">
|
||||||
|
<title>uabgssx6lsgrevwbttslldnr5nzguprj->v32wejd4d5lc6uka4qlrogwh5xae2h3r</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1117.0696,-476.4072C1117.0696,-457.3263 1117.0696,-434.7257 1117.0696,-414.6046"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M1119.0696,-476.4072C1119.0696,-457.3263 1119.0696,-434.7257 1119.0696,-414.6046"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1121.5697,-414.3403 1118.0696,-404.3403 1114.5697,-414.3404 1121.5697,-414.3403"/>
|
||||||
|
</g>
|
||||||
|
<!-- lfh3aovn65e66cs24qiehq3nd2ddojef->o524gebsxavobkte3k5fglgwnedfkadf -->
|
||||||
|
<g id="edge14" class="edge">
|
||||||
|
<title>lfh3aovn65e66cs24qiehq3nd2ddojef->o524gebsxavobkte3k5fglgwnedfkadf</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1167.6711,-1112.5788C1078.9073,-1090.9596 971.5916,-1064.822 881.5513,-1042.892"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M1168.1444,-1110.6356C1079.3806,-1089.0165 972.0649,-1062.8788 882.0246,-1040.9488"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="882.5603,-1038.5062 872.016,-1039.5403 880.9038,-1045.3074 882.5603,-1038.5062"/>
|
||||||
|
<text text-anchor="middle" x="963.904" y="-1079.817" font-family="Times,serif" font-size="14.00" fill="#000000">virtuals=blas,lapack</text>
|
||||||
|
</g>
|
||||||
|
<!-- lfh3aovn65e66cs24qiehq3nd2ddojef->2w3nq3n3hcj2tqlvcpewsryamltlu5tw -->
|
||||||
|
<g id="edge31" class="edge">
|
||||||
|
<title>lfh3aovn65e66cs24qiehq3nd2ddojef->2w3nq3n3hcj2tqlvcpewsryamltlu5tw</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1559.7922,-1112.1043C1562.8511,-1111.5975 1565.8904,-1111.1002 1568.9103,-1110.6128 1759.2182,-1079.8992 1973.2397,-1052.1328 2144.6143,-1031.5343"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M1560.1191,-1114.0774C1563.1741,-1113.5712 1566.2134,-1113.0739 1569.2289,-1112.5872 1759.4755,-1081.8826 1973.497,-1054.1161 2144.8529,-1033.52"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="2145.1529,-1036.002 2154.6648,-1031.3357 2144.3191,-1029.0518 2145.1529,-1036.002"/>
|
||||||
|
<text text-anchor="middle" x="1828.178" y="-1072.4692" font-family="Times,serif" font-size="14.00" fill="#000000">virtuals=mpi</text>
|
||||||
|
</g>
|
||||||
|
<!-- lfh3aovn65e66cs24qiehq3nd2ddojef->gguve5icmo5e4cw5o3hvvfsxremc46if -->
|
||||||
|
<g id="edge21" class="edge">
|
||||||
|
<title>lfh3aovn65e66cs24qiehq3nd2ddojef->gguve5icmo5e4cw5o3hvvfsxremc46if</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1346.0696,-1111.6072C1346.0696,-1092.5263 1346.0696,-1069.9257 1346.0696,-1049.8046"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1349.5697,-1049.5403 1346.0696,-1039.5403 1342.5697,-1049.5404 1349.5697,-1049.5403"/>
|
||||||
|
</g>
|
||||||
|
<!-- 2w3nq3n3hcj2tqlvcpewsryamltlu5tw->htzjns66gmq6pjofohp26djmjnpbegho -->
|
||||||
|
<g id="edge30" class="edge">
|
||||||
|
<title>2w3nq3n3hcj2tqlvcpewsryamltlu5tw->htzjns66gmq6pjofohp26djmjnpbegho</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M2467.0696,-952.8072C2467.0696,-933.7263 2467.0696,-911.1257 2467.0696,-891.0046"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="2470.5697,-890.7403 2467.0696,-880.7403 2463.5697,-890.7404 2470.5697,-890.7403"/>
|
||||||
|
</g>
|
||||||
|
<!-- 7rzbmgoxhmm2jhellkgcjmn62uklf22x->gguve5icmo5e4cw5o3hvvfsxremc46if -->
|
||||||
|
<g id="edge2" class="edge">
|
||||||
|
<title>7rzbmgoxhmm2jhellkgcjmn62uklf22x->gguve5icmo5e4cw5o3hvvfsxremc46if</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1422.351,-1429.2133C1312.2528,-1388.8872 1171.1589,-1316.8265 1103.0696,-1198.4 1083.8409,-1164.956 1082.4563,-1144.2088 1103.0696,-1111.6 1121.4102,-1082.5864 1149.2483,-1060.7204 1179.6189,-1044.2895"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1181.4205,-1047.2977 1188.6801,-1039.5809 1178.1927,-1041.0863 1181.4205,-1047.2977"/>
|
||||||
|
</g>
|
||||||
|
<!-- v32wejd4d5lc6uka4qlrogwh5xae2h3r->j5rupoqliu7kasm6xndl7ui32wgawkru -->
|
||||||
|
<g id="edge39" class="edge">
|
||||||
|
<title>v32wejd4d5lc6uka4qlrogwh5xae2h3r->j5rupoqliu7kasm6xndl7ui32wgawkru</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1179.8001,-316.7866C1209.2065,-296.3053 1244.4355,-271.7686 1274.8343,-250.5961"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M1180.9431,-318.4278C1210.3495,-297.9465 1245.5785,-273.4098 1275.9774,-252.2373"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1277.6375,-254.1277 1283.8429,-245.5403 1273.6367,-248.3836 1277.6375,-254.1277"/>
|
||||||
|
</g>
|
||||||
|
<!-- gguve5icmo5e4cw5o3hvvfsxremc46if->j5rupoqliu7kasm6xndl7ui32wgawkru -->
|
||||||
|
<g id="edge18" class="edge">
|
||||||
|
<title>gguve5icmo5e4cw5o3hvvfsxremc46if->j5rupoqliu7kasm6xndl7ui32wgawkru</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1345.0696,-952.7909C1345.0696,-891.6316 1345.0696,-776.6094 1345.0696,-678.6 1345.0696,-678.6 1345.0696,-678.6 1345.0696,-519.8 1345.0696,-426.9591 1345.0696,-318.8523 1345.0696,-255.7237"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M1347.0696,-952.7909C1347.0696,-891.6316 1347.0696,-776.6094 1347.0696,-678.6 1347.0696,-678.6 1347.0696,-678.6 1347.0696,-519.8 1347.0696,-426.9591 1347.0696,-318.8523 1347.0696,-255.7237"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1349.5697,-255.6091 1346.0696,-245.6091 1342.5697,-255.6092 1349.5697,-255.6091"/>
|
||||||
|
</g>
|
||||||
|
<!-- gguve5icmo5e4cw5o3hvvfsxremc46if->5xerf6imlgo4xlubacr4mljacc3edexo -->
|
||||||
|
<g id="edge40" class="edge">
|
||||||
|
<title>gguve5icmo5e4cw5o3hvvfsxremc46if->5xerf6imlgo4xlubacr4mljacc3edexo</title>
|
||||||
|
<path fill="none" stroke="#1e90ff" stroke-width="2" d="M1423.1858,-951.9344C1460.2844,-931.1905 1504.8229,-906.2866 1543.0151,-884.9312"/>
|
||||||
|
<path fill="none" stroke="#dc143c" stroke-width="2" d="M1424.1619,-953.68C1461.2605,-932.9361 1505.799,-908.0322 1543.9912,-886.6769"/>
|
||||||
|
<polygon fill="#1e90ff" stroke="#1e90ff" stroke-width="2" points="1545.5391,-888.6757 1552.5592,-880.7403 1542.1228,-882.5659 1545.5391,-888.6757"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 58 KiB |
|
@ -2974,6 +2974,33 @@ The ``provides("mpi")`` call tells Spack that the ``mpich`` package
|
||||||
can be used to satisfy the dependency of any package that
|
can be used to satisfy the dependency of any package that
|
||||||
``depends_on("mpi")``.
|
``depends_on("mpi")``.
|
||||||
|
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Providing multiple virtuals simultaneously
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Packages can provide more than one virtual dependency. Sometimes, due to implementation details,
|
||||||
|
there are subsets of those virtuals that need to be provided together by the same package.
|
||||||
|
|
||||||
|
A well-known example is ``openblas``, which provides both the ``lapack`` and ``blas`` API in a single ``libopenblas``
|
||||||
|
library. A package that needs ``lapack`` and ``blas`` must either use ``openblas`` to provide both, or not use
|
||||||
|
``openblas`` at all. It cannot pick one or the other.
|
||||||
|
|
||||||
|
To express this constraint in a package, the two virtual dependencies must be listed in the same ``provides`` directive:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
provides('blas', 'lapack')
|
||||||
|
|
||||||
|
This makes it impossible to select ``openblas`` as a provider for one of the two
|
||||||
|
virtual dependencies and not for the other. If you try to, Spack will report an error:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ spack spec netlib-scalapack ^[virtuals=lapack] openblas ^[virtuals=blas] atlas
|
||||||
|
==> Error: concretization failed for the following reasons:
|
||||||
|
|
||||||
|
1. Package 'openblas' needs to provide both 'lapack' and 'blas' together, but provides only 'lapack'
|
||||||
|
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
Versioned Interfaces
|
Versioned Interfaces
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -573,17 +573,21 @@ def _execute_extends(pkg):
|
||||||
return _execute_extends
|
return _execute_extends
|
||||||
|
|
||||||
|
|
||||||
@directive("provided")
|
@directive(dicts=("provided", "provided_together"))
|
||||||
def provides(*specs, **kwargs):
|
def provides(*specs, when: Optional[str] = None):
|
||||||
"""Allows packages to provide a virtual dependency. If a package provides
|
"""Allows packages to provide a virtual dependency.
|
||||||
'mpi', other packages can declare that they depend on "mpi", and spack
|
|
||||||
can use the providing package to satisfy the dependency.
|
If a package provides "mpi", other packages can declare that they depend on "mpi",
|
||||||
|
and spack can use the providing package to satisfy the dependency.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
*specs: virtual specs provided by this package
|
||||||
|
when: condition when this provides clause needs to be considered
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _execute_provides(pkg):
|
def _execute_provides(pkg):
|
||||||
import spack.parser # Avoid circular dependency
|
import spack.parser # Avoid circular dependency
|
||||||
|
|
||||||
when = kwargs.get("when")
|
|
||||||
when_spec = make_when_spec(when)
|
when_spec = make_when_spec(when)
|
||||||
if not when_spec:
|
if not when_spec:
|
||||||
return
|
return
|
||||||
|
@ -591,9 +595,12 @@ def _execute_provides(pkg):
|
||||||
# ``when`` specs for ``provides()`` need a name, as they are used
|
# ``when`` specs for ``provides()`` need a name, as they are used
|
||||||
# to build the ProviderIndex.
|
# to build the ProviderIndex.
|
||||||
when_spec.name = pkg.name
|
when_spec.name = pkg.name
|
||||||
|
spec_objs = [spack.spec.Spec(x) for x in specs]
|
||||||
|
spec_names = [x.name for x in spec_objs]
|
||||||
|
if len(spec_names) > 1:
|
||||||
|
pkg.provided_together.setdefault(when_spec, []).append(set(spec_names))
|
||||||
|
|
||||||
for string in specs:
|
for provided_spec in spec_objs:
|
||||||
for provided_spec in spack.parser.parse(string):
|
|
||||||
if pkg.name == provided_spec.name:
|
if pkg.name == provided_spec.name:
|
||||||
raise CircularReferenceError("Package '%s' cannot provide itself." % pkg.name)
|
raise CircularReferenceError("Package '%s' cannot provide itself." % pkg.name)
|
||||||
|
|
||||||
|
|
|
@ -528,10 +528,15 @@ def node_entry(self, node):
|
||||||
|
|
||||||
def edge_entry(self, edge):
|
def edge_entry(self, edge):
|
||||||
colormap = {"build": "dodgerblue", "link": "crimson", "run": "goldenrod"}
|
colormap = {"build": "dodgerblue", "link": "crimson", "run": "goldenrod"}
|
||||||
|
label = ""
|
||||||
|
if edge.virtuals:
|
||||||
|
label = f" xlabel=\"virtuals={','.join(edge.virtuals)}\""
|
||||||
return (
|
return (
|
||||||
edge.parent.dag_hash(),
|
edge.parent.dag_hash(),
|
||||||
edge.spec.dag_hash(),
|
edge.spec.dag_hash(),
|
||||||
f"[color=\"{':'.join(colormap[x] for x in dt.flag_to_tuple(edge.depflag))}\"]",
|
f"[color=\"{':'.join(colormap[x] for x in dt.flag_to_tuple(edge.depflag))}\""
|
||||||
|
+ label
|
||||||
|
+ "]",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
Here is the EBNF grammar for a spec::
|
Here is the EBNF grammar for a spec::
|
||||||
|
|
||||||
spec = [name] [node_options] { ^ node } |
|
spec = [name] [node_options] { ^[edge_properties] node } |
|
||||||
[name] [node_options] hash |
|
[name] [node_options] hash |
|
||||||
filename
|
filename
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
||||||
filename
|
filename
|
||||||
|
|
||||||
node_options = [@(version_list|version_pair)] [%compiler] { variant }
|
node_options = [@(version_list|version_pair)] [%compiler] { variant }
|
||||||
|
edge_properties = [ { bool_variant | key_value } ]
|
||||||
|
|
||||||
hash = / id
|
hash = / id
|
||||||
filename = (.|/|[a-zA-Z0-9-_]*/)([a-zA-Z0-9-_./]*)(.json|.yaml)
|
filename = (.|/|[a-zA-Z0-9-_]*/)([a-zA-Z0-9-_./]*)(.json|.yaml)
|
||||||
|
@ -64,6 +65,7 @@
|
||||||
|
|
||||||
from llnl.util.tty import color
|
from llnl.util.tty import color
|
||||||
|
|
||||||
|
import spack.deptypes
|
||||||
import spack.error
|
import spack.error
|
||||||
import spack.spec
|
import spack.spec
|
||||||
import spack.version
|
import spack.version
|
||||||
|
@ -126,6 +128,8 @@ class TokenType(TokenBase):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Dependency
|
# Dependency
|
||||||
|
START_EDGE_PROPERTIES = r"(?:\^\[)"
|
||||||
|
END_EDGE_PROPERTIES = r"(?:\])"
|
||||||
DEPENDENCY = r"(?:\^)"
|
DEPENDENCY = r"(?:\^)"
|
||||||
# Version
|
# Version
|
||||||
VERSION_HASH_PAIR = rf"(?:@(?:{GIT_VERSION_PATTERN})=(?:{VERSION}))"
|
VERSION_HASH_PAIR = rf"(?:@(?:{GIT_VERSION_PATTERN})=(?:{VERSION}))"
|
||||||
|
@ -280,16 +284,15 @@ def next_spec(
|
||||||
initial_spec = initial_spec or spack.spec.Spec()
|
initial_spec = initial_spec or spack.spec.Spec()
|
||||||
root_spec = SpecNodeParser(self.ctx).parse(initial_spec)
|
root_spec = SpecNodeParser(self.ctx).parse(initial_spec)
|
||||||
while True:
|
while True:
|
||||||
if self.ctx.accept(TokenType.DEPENDENCY):
|
if self.ctx.accept(TokenType.START_EDGE_PROPERTIES):
|
||||||
dependency = SpecNodeParser(self.ctx).parse()
|
edge_properties = EdgeAttributeParser(self.ctx, self.literal_str).parse()
|
||||||
|
edge_properties.setdefault("depflag", 0)
|
||||||
if dependency is None:
|
edge_properties.setdefault("virtuals", ())
|
||||||
msg = (
|
dependency = self._parse_node(root_spec)
|
||||||
"this dependency sigil needs to be followed by a package name "
|
root_spec._add_dependency(dependency, **edge_properties)
|
||||||
"or a node attribute (version, variant, etc.)"
|
|
||||||
)
|
|
||||||
raise SpecParsingError(msg, self.ctx.current_token, self.literal_str)
|
|
||||||
|
|
||||||
|
elif self.ctx.accept(TokenType.DEPENDENCY):
|
||||||
|
dependency = self._parse_node(root_spec)
|
||||||
root_spec._add_dependency(dependency, depflag=0, virtuals=())
|
root_spec._add_dependency(dependency, depflag=0, virtuals=())
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -297,6 +300,18 @@ def next_spec(
|
||||||
|
|
||||||
return root_spec
|
return root_spec
|
||||||
|
|
||||||
|
def _parse_node(self, root_spec):
|
||||||
|
dependency = SpecNodeParser(self.ctx).parse()
|
||||||
|
if dependency is None:
|
||||||
|
msg = (
|
||||||
|
"the dependency sigil and any optional edge attributes must be followed by a "
|
||||||
|
"package name or a node attribute (version, variant, etc.)"
|
||||||
|
)
|
||||||
|
raise SpecParsingError(msg, self.ctx.current_token, self.literal_str)
|
||||||
|
if root_spec.concrete:
|
||||||
|
raise spack.spec.RedundantSpecError(root_spec, "^" + str(dependency))
|
||||||
|
return dependency
|
||||||
|
|
||||||
def all_specs(self) -> List["spack.spec.Spec"]:
|
def all_specs(self) -> List["spack.spec.Spec"]:
|
||||||
"""Return all the specs that remain to be parsed"""
|
"""Return all the specs that remain to be parsed"""
|
||||||
return list(iter(self.next_spec, None))
|
return list(iter(self.next_spec, None))
|
||||||
|
@ -438,6 +453,41 @@ def parse(self, initial_spec: "spack.spec.Spec") -> "spack.spec.Spec":
|
||||||
return initial_spec
|
return initial_spec
|
||||||
|
|
||||||
|
|
||||||
|
class EdgeAttributeParser:
|
||||||
|
__slots__ = "ctx", "literal_str"
|
||||||
|
|
||||||
|
def __init__(self, ctx, literal_str):
|
||||||
|
self.ctx = ctx
|
||||||
|
self.literal_str = literal_str
|
||||||
|
|
||||||
|
def parse(self):
|
||||||
|
attributes = {}
|
||||||
|
while True:
|
||||||
|
if self.ctx.accept(TokenType.KEY_VALUE_PAIR):
|
||||||
|
name, value = self.ctx.current_token.value.split("=", maxsplit=1)
|
||||||
|
name = name.strip("'\" ")
|
||||||
|
value = value.strip("'\" ").split(",")
|
||||||
|
attributes[name] = value
|
||||||
|
if name not in ("deptypes", "virtuals"):
|
||||||
|
msg = (
|
||||||
|
"the only edge attributes that are currently accepted "
|
||||||
|
'are "deptypes" and "virtuals"'
|
||||||
|
)
|
||||||
|
raise SpecParsingError(msg, self.ctx.current_token, self.literal_str)
|
||||||
|
# TODO: Add code to accept bool variants here as soon as use variants are implemented
|
||||||
|
elif self.ctx.accept(TokenType.END_EDGE_PROPERTIES):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
msg = "unexpected token in edge attributes"
|
||||||
|
raise SpecParsingError(msg, self.ctx.next_token, self.literal_str)
|
||||||
|
|
||||||
|
# Turn deptypes=... to depflag representation
|
||||||
|
if "deptypes" in attributes:
|
||||||
|
deptype_string = attributes.pop("deptypes")
|
||||||
|
attributes["depflag"] = spack.deptypes.canonicalize(deptype_string)
|
||||||
|
return attributes
|
||||||
|
|
||||||
|
|
||||||
def parse(text: str) -> List["spack.spec.Spec"]:
|
def parse(text: str) -> List["spack.spec.Spec"]:
|
||||||
"""Parse text into a list of strings
|
"""Parse text into a list of strings
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
"""Classes and functions to manage providers of virtual dependencies"""
|
"""Classes and functions to manage providers of virtual dependencies"""
|
||||||
import itertools
|
|
||||||
from typing import Dict, List, Optional, Set
|
from typing import Dict, List, Optional, Set
|
||||||
|
|
||||||
import spack.error
|
import spack.error
|
||||||
|
@ -11,33 +10,6 @@
|
||||||
import spack.util.spack_json as sjson
|
import spack.util.spack_json as sjson
|
||||||
|
|
||||||
|
|
||||||
def _cross_provider_maps(lmap, rmap):
|
|
||||||
"""Return a dictionary that combines constraint requests from both input.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
lmap: main provider map
|
|
||||||
rmap: provider map with additional constraints
|
|
||||||
"""
|
|
||||||
# TODO: this is pretty darned nasty, and inefficient, but there
|
|
||||||
# TODO: are not that many vdeps in most specs.
|
|
||||||
result = {}
|
|
||||||
for lspec, rspec in itertools.product(lmap, rmap):
|
|
||||||
try:
|
|
||||||
constrained = lspec.constrained(rspec)
|
|
||||||
except spack.error.UnsatisfiableSpecError:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# lp and rp are left and right provider specs.
|
|
||||||
for lp_spec, rp_spec in itertools.product(lmap[lspec], rmap[rspec]):
|
|
||||||
if lp_spec.name == rp_spec.name:
|
|
||||||
try:
|
|
||||||
const = lp_spec.constrained(rp_spec, deps=False)
|
|
||||||
result.setdefault(constrained, set()).add(const)
|
|
||||||
except spack.error.UnsatisfiableSpecError:
|
|
||||||
continue
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
class _IndexBase:
|
class _IndexBase:
|
||||||
#: This is a dict of dicts used for finding providers of particular
|
#: This is a dict of dicts used for finding providers of particular
|
||||||
#: virtual dependencies. The dict of dicts looks like:
|
#: virtual dependencies. The dict of dicts looks like:
|
||||||
|
@ -81,29 +53,6 @@ def providers_for(self, virtual_spec):
|
||||||
def __contains__(self, name):
|
def __contains__(self, name):
|
||||||
return name in self.providers
|
return name in self.providers
|
||||||
|
|
||||||
def satisfies(self, other):
|
|
||||||
"""Determine if the providers of virtual specs are compatible.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
other: another provider index
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
True if the providers are compatible, False otherwise.
|
|
||||||
"""
|
|
||||||
common = set(self.providers) & set(other.providers)
|
|
||||||
if not common:
|
|
||||||
return True
|
|
||||||
|
|
||||||
# This ensures that some provider in other COULD satisfy the
|
|
||||||
# vpkg constraints on self.
|
|
||||||
result = {}
|
|
||||||
for name in common:
|
|
||||||
crossed = _cross_provider_maps(self.providers[name], other.providers[name])
|
|
||||||
if crossed:
|
|
||||||
result[name] = crossed
|
|
||||||
|
|
||||||
return all(c in result for c in common)
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return self.providers == other.providers
|
return self.providers == other.providers
|
||||||
|
|
||||||
|
|
|
@ -1501,6 +1501,17 @@ def package_provider_rules(self, pkg):
|
||||||
)
|
)
|
||||||
self.gen.newline()
|
self.gen.newline()
|
||||||
|
|
||||||
|
for when, sets_of_virtuals in pkg.provided_together.items():
|
||||||
|
condition_id = self.condition(
|
||||||
|
when, name=pkg.name, msg="Virtuals are provided together"
|
||||||
|
)
|
||||||
|
for set_id, virtuals_together in enumerate(sets_of_virtuals):
|
||||||
|
for name in virtuals_together:
|
||||||
|
self.gen.fact(
|
||||||
|
fn.pkg_fact(pkg.name, fn.provided_together(condition_id, set_id, name))
|
||||||
|
)
|
||||||
|
self.gen.newline()
|
||||||
|
|
||||||
def package_dependencies_rules(self, pkg):
|
def package_dependencies_rules(self, pkg):
|
||||||
"""Translate 'depends_on' directives into ASP logic."""
|
"""Translate 'depends_on' directives into ASP logic."""
|
||||||
for _, conditions in sorted(pkg.dependencies.items()):
|
for _, conditions in sorted(pkg.dependencies.items()):
|
||||||
|
@ -1902,6 +1913,15 @@ class Body:
|
||||||
clauses.append(fn.attr("package_hash", spec.name, spec._package_hash))
|
clauses.append(fn.attr("package_hash", spec.name, spec._package_hash))
|
||||||
clauses.append(fn.attr("hash", spec.name, spec.dag_hash()))
|
clauses.append(fn.attr("hash", spec.name, spec.dag_hash()))
|
||||||
|
|
||||||
|
edges = spec.edges_from_dependents()
|
||||||
|
virtuals = [x for x in itertools.chain.from_iterable([edge.virtuals for edge in edges])]
|
||||||
|
if not body:
|
||||||
|
for virtual in virtuals:
|
||||||
|
clauses.append(fn.attr("provider_set", spec.name, virtual))
|
||||||
|
else:
|
||||||
|
for virtual in virtuals:
|
||||||
|
clauses.append(fn.attr("virtual_on_incoming_edges", spec.name, virtual))
|
||||||
|
|
||||||
# add all clauses from dependencies
|
# add all clauses from dependencies
|
||||||
if transitive:
|
if transitive:
|
||||||
# TODO: Eventually distinguish 2 deps on the same pkg (build and link)
|
# TODO: Eventually distinguish 2 deps on the same pkg (build and link)
|
||||||
|
@ -3124,10 +3144,11 @@ def __init__(self, provided, conflicts):
|
||||||
msg = (
|
msg = (
|
||||||
"Spack concretizer internal error. Please submit a bug report and include the "
|
"Spack concretizer internal error. Please submit a bug report and include the "
|
||||||
"command, environment if applicable and the following error message."
|
"command, environment if applicable and the following error message."
|
||||||
f"\n {provided} is unsatisfiable, errors are:"
|
f"\n {provided} is unsatisfiable"
|
||||||
)
|
)
|
||||||
|
|
||||||
msg += "".join([f"\n {conflict}" for conflict in conflicts])
|
if conflicts:
|
||||||
|
msg += ", errors are:" + "".join([f"\n {conflict}" for conflict in conflicts])
|
||||||
|
|
||||||
super(spack.error.UnsatisfiableSpecError, self).__init__(msg)
|
super(spack.error.UnsatisfiableSpecError, self).__init__(msg)
|
||||||
|
|
||||||
|
|
|
@ -113,10 +113,11 @@ unification_set(SetID, VirtualNode)
|
||||||
multiple_nodes_attribute("node_flag_source").
|
multiple_nodes_attribute("node_flag_source").
|
||||||
multiple_nodes_attribute("depends_on").
|
multiple_nodes_attribute("depends_on").
|
||||||
multiple_nodes_attribute("virtual_on_edge").
|
multiple_nodes_attribute("virtual_on_edge").
|
||||||
|
multiple_nodes_attribute("provider_set").
|
||||||
|
|
||||||
% Map constraint on the literal ID to facts on the node
|
% Map constraint on the literal ID to facts on the node
|
||||||
attr(Name, node(min_dupe_id, A1)) :- literal(LiteralID, Name, A1), solve_literal(LiteralID).
|
attr(Name, node(min_dupe_id, A1)) :- literal(LiteralID, Name, A1), solve_literal(LiteralID).
|
||||||
attr(Name, node(min_dupe_id, A1), A2) :- literal(LiteralID, Name, A1, A2), solve_literal(LiteralID).
|
attr(Name, node(min_dupe_id, A1), A2) :- literal(LiteralID, Name, A1, A2), solve_literal(LiteralID), not multiple_nodes_attribute(Name).
|
||||||
attr(Name, node(min_dupe_id, A1), A2, A3) :- literal(LiteralID, Name, A1, A2, A3), solve_literal(LiteralID), not multiple_nodes_attribute(Name).
|
attr(Name, node(min_dupe_id, A1), A2, A3) :- literal(LiteralID, Name, A1, A2, A3), solve_literal(LiteralID), not multiple_nodes_attribute(Name).
|
||||||
attr(Name, node(min_dupe_id, A1), A2, A3, A4) :- literal(LiteralID, Name, A1, A2, A3, A4), solve_literal(LiteralID).
|
attr(Name, node(min_dupe_id, A1), A2, A3, A4) :- literal(LiteralID, Name, A1, A2, A3, A4), solve_literal(LiteralID).
|
||||||
|
|
||||||
|
@ -124,6 +125,10 @@ attr(Name, node(min_dupe_id, A1), A2, A3, A4) :- literal(LiteralID, Name, A1, A2
|
||||||
attr("node_flag_source", node(min_dupe_id, A1), A2, node(min_dupe_id, A3)) :- literal(LiteralID, "node_flag_source", A1, A2, A3), solve_literal(LiteralID).
|
attr("node_flag_source", node(min_dupe_id, A1), A2, node(min_dupe_id, A3)) :- literal(LiteralID, "node_flag_source", A1, A2, A3), solve_literal(LiteralID).
|
||||||
attr("depends_on", node(min_dupe_id, A1), node(min_dupe_id, A2), A3) :- literal(LiteralID, "depends_on", A1, A2, A3), solve_literal(LiteralID).
|
attr("depends_on", node(min_dupe_id, A1), node(min_dupe_id, A2), A3) :- literal(LiteralID, "depends_on", A1, A2, A3), solve_literal(LiteralID).
|
||||||
|
|
||||||
|
attr("virtual_node", node(min_dupe_id, Virtual)) :- literal(LiteralID, "provider_set", _, Virtual), solve_literal(LiteralID).
|
||||||
|
attr("provider_set", node(min_dupe_id, Provider), node(min_dupe_id, Virtual)) :- literal(LiteralID, "provider_set", Provider, Virtual), solve_literal(LiteralID).
|
||||||
|
provider(node(min_dupe_id, Provider), node(min_dupe_id, Virtual)) :- literal(LiteralID, "provider_set", Provider, Virtual), solve_literal(LiteralID).
|
||||||
|
|
||||||
% Discriminate between "roots" that have been explicitly requested, and roots that are deduced from "virtual roots"
|
% Discriminate between "roots" that have been explicitly requested, and roots that are deduced from "virtual roots"
|
||||||
explicitly_requested_root(node(min_dupe_id, A1)) :- literal(LiteralID, "root", A1), solve_literal(LiteralID).
|
explicitly_requested_root(node(min_dupe_id, A1)) :- literal(LiteralID, "root", A1), solve_literal(LiteralID).
|
||||||
|
|
||||||
|
@ -476,6 +481,19 @@ error(1, Msg)
|
||||||
% Virtual dependencies
|
% Virtual dependencies
|
||||||
%-----------------------------------------------------------------------------
|
%-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
% If the provider is set from the command line, its weight is 0
|
||||||
|
possible_provider_weight(ProviderNode, VirtualNode, 0, "Set on the command line")
|
||||||
|
:- attr("provider_set", ProviderNode, VirtualNode).
|
||||||
|
|
||||||
|
% Enforces all virtuals to be provided, if multiple of them are provided together
|
||||||
|
error(100, "Package '{0}' needs to provide both '{1}' and '{2}' together, but provides only '{1}'", Package, Virtual1, Virtual2)
|
||||||
|
:- condition_holds(ID, node(X, Package)),
|
||||||
|
pkg_fact(Package, provided_together(ID, SetID, Virtual1)),
|
||||||
|
pkg_fact(Package, provided_together(ID, SetID, Virtual2)),
|
||||||
|
Virtual1 != Virtual2,
|
||||||
|
attr("virtual_on_incoming_edges", node(X, Package), Virtual1),
|
||||||
|
not attr("virtual_on_incoming_edges", node(X, Package), Virtual2).
|
||||||
|
|
||||||
% if a package depends on a virtual, it's not external and we have a
|
% if a package depends on a virtual, it's not external and we have a
|
||||||
% provider for that virtual then it depends on the provider
|
% provider for that virtual then it depends on the provider
|
||||||
node_depends_on_virtual(PackageNode, Virtual, Type)
|
node_depends_on_virtual(PackageNode, Virtual, Type)
|
||||||
|
@ -494,6 +512,9 @@ attr("virtual_on_edge", PackageNode, ProviderNode, Virtual)
|
||||||
provider(ProviderNode, node(_, Virtual)),
|
provider(ProviderNode, node(_, Virtual)),
|
||||||
not external(PackageNode).
|
not external(PackageNode).
|
||||||
|
|
||||||
|
attr("virtual_on_incoming_edges", ProviderNode, Virtual)
|
||||||
|
:- attr("virtual_on_edge", _, ProviderNode, Virtual).
|
||||||
|
|
||||||
% dependencies on virtuals also imply that the virtual is a virtual node
|
% dependencies on virtuals also imply that the virtual is a virtual node
|
||||||
1 { attr("virtual_node", node(0..X-1, Virtual)) : max_dupes(Virtual, X) }
|
1 { attr("virtual_node", node(0..X-1, Virtual)) : max_dupes(Virtual, X) }
|
||||||
:- node_depends_on_virtual(PackageNode, Virtual).
|
:- node_depends_on_virtual(PackageNode, Virtual).
|
||||||
|
@ -501,6 +522,10 @@ attr("virtual_on_edge", PackageNode, ProviderNode, Virtual)
|
||||||
% If there's a virtual node, we must select one and only one provider.
|
% If there's a virtual node, we must select one and only one provider.
|
||||||
% The provider must be selected among the possible providers.
|
% The provider must be selected among the possible providers.
|
||||||
|
|
||||||
|
error(100, "'{0}' cannot be a provider for the '{1}' virtual", Package, Virtual)
|
||||||
|
:- attr("provider_set", node(min_dupe_id, Package), node(min_dupe_id, Virtual)),
|
||||||
|
not virtual_condition_holds( node(min_dupe_id, Package), Virtual).
|
||||||
|
|
||||||
error(100, "Cannot find valid provider for virtual {0}", Virtual)
|
error(100, "Cannot find valid provider for virtual {0}", Virtual)
|
||||||
:- attr("virtual_node", node(X, Virtual)),
|
:- attr("virtual_node", node(X, Virtual)),
|
||||||
not provider(_, node(X, Virtual)).
|
not provider(_, node(X, Virtual)).
|
||||||
|
@ -521,20 +546,6 @@ attr("root", PackageNode) :- attr("virtual_root", VirtualNode), provider(Package
|
||||||
attr("node", PackageNode), virtual_condition_holds(PackageNode, Virtual) } 1
|
attr("node", PackageNode), virtual_condition_holds(PackageNode, Virtual) } 1
|
||||||
:- attr("virtual_node", node(X, Virtual)).
|
:- attr("virtual_node", node(X, Virtual)).
|
||||||
|
|
||||||
% If a spec is selected as a provider, it is for all the virtual it could provide
|
|
||||||
:- provider(PackageNode, node(X, Virtual1)),
|
|
||||||
virtual_condition_holds(PackageNode, Virtual2),
|
|
||||||
Virtual2 != Virtual1,
|
|
||||||
unification_set(SetID, PackageNode),
|
|
||||||
unification_set(SetID, node(X, Virtual2)),
|
|
||||||
not provider(PackageNode, node(X, Virtual2)).
|
|
||||||
|
|
||||||
% If a spec is a dependency, and could provide a needed virtual, it must be a provider
|
|
||||||
:- node_depends_on_virtual(PackageNode, Virtual),
|
|
||||||
depends_on(PackageNode, PossibleProviderNode),
|
|
||||||
virtual_condition_holds(PossibleProviderNode, Virtual),
|
|
||||||
not attr("virtual_on_edge", PackageNode, PossibleProviderNode, Virtual).
|
|
||||||
|
|
||||||
% The provider provides the virtual if some provider condition holds.
|
% The provider provides the virtual if some provider condition holds.
|
||||||
virtual_condition_holds(node(ProviderID, Provider), Virtual) :- virtual_condition_holds(ID, node(ProviderID, Provider), Virtual).
|
virtual_condition_holds(node(ProviderID, Provider), Virtual) :- virtual_condition_holds(ID, node(ProviderID, Provider), Virtual).
|
||||||
virtual_condition_holds(ID, node(ProviderID, Provider), Virtual) :-
|
virtual_condition_holds(ID, node(ProviderID, Provider), Virtual) :-
|
||||||
|
@ -561,6 +572,8 @@ do_not_impose(EffectID, node(X, Package))
|
||||||
not virtual_condition_holds(PackageNode, Virtual),
|
not virtual_condition_holds(PackageNode, Virtual),
|
||||||
internal_error("Virtual when provides not respected").
|
internal_error("Virtual when provides not respected").
|
||||||
|
|
||||||
|
#defined provided_together/4.
|
||||||
|
|
||||||
%-----------------------------------------------------------------------------
|
%-----------------------------------------------------------------------------
|
||||||
% Virtual dependency weights
|
% Virtual dependency weights
|
||||||
%-----------------------------------------------------------------------------
|
%-----------------------------------------------------------------------------
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
import warnings
|
import warnings
|
||||||
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Union
|
||||||
|
|
||||||
import llnl.path
|
import llnl.path
|
||||||
import llnl.string
|
import llnl.string
|
||||||
|
@ -1464,6 +1464,26 @@ def edges_to_dependencies(self, name=None, depflag: dt.DepFlag = dt.ALL):
|
||||||
"""
|
"""
|
||||||
return [d for d in self._dependencies.select(child=name, depflag=depflag)]
|
return [d for d in self._dependencies.select(child=name, depflag=depflag)]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def edge_attributes(self) -> str:
|
||||||
|
"""Helper method to print edge attributes in spec literals"""
|
||||||
|
edges = self.edges_from_dependents()
|
||||||
|
if not edges:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
union = DependencySpec(parent=Spec(), spec=self, depflag=0, virtuals=())
|
||||||
|
for edge in edges:
|
||||||
|
union.update_deptypes(edge.depflag)
|
||||||
|
union.update_virtuals(edge.virtuals)
|
||||||
|
deptypes_str = (
|
||||||
|
f"deptypes={','.join(dt.flag_to_tuple(union.depflag))}" if union.depflag else ""
|
||||||
|
)
|
||||||
|
virtuals_str = f"virtuals={','.join(union.virtuals)}" if union.virtuals else ""
|
||||||
|
if not deptypes_str and not virtuals_str:
|
||||||
|
return ""
|
||||||
|
result = f"{deptypes_str} {virtuals_str}".strip()
|
||||||
|
return f"[{result}]"
|
||||||
|
|
||||||
def dependencies(self, name=None, deptype: Union[dt.DepTypes, dt.DepFlag] = dt.ALL):
|
def dependencies(self, name=None, deptype: Union[dt.DepTypes, dt.DepFlag] = dt.ALL):
|
||||||
"""Return a list of direct dependencies (nodes in the DAG).
|
"""Return a list of direct dependencies (nodes in the DAG).
|
||||||
|
|
||||||
|
@ -3688,8 +3708,15 @@ def intersects(self, other: Union[str, "Spec"], deps: bool = True) -> bool:
|
||||||
if other.concrete and self.concrete:
|
if other.concrete and self.concrete:
|
||||||
return self.dag_hash() == other.dag_hash()
|
return self.dag_hash() == other.dag_hash()
|
||||||
|
|
||||||
self_hash = self.dag_hash() if self.concrete else self.abstract_hash
|
elif self.concrete:
|
||||||
other_hash = other.dag_hash() if other.concrete else other.abstract_hash
|
return self.satisfies(other)
|
||||||
|
|
||||||
|
elif other.concrete:
|
||||||
|
return other.satisfies(self)
|
||||||
|
|
||||||
|
# From here we know both self and other are not concrete
|
||||||
|
self_hash = self.abstract_hash
|
||||||
|
other_hash = other.abstract_hash
|
||||||
|
|
||||||
if (
|
if (
|
||||||
self_hash
|
self_hash
|
||||||
|
@ -3778,10 +3805,6 @@ def _intersects_dependencies(self, other):
|
||||||
repository=spack.repo.PATH, specs=other.traverse(), restrict=True
|
repository=spack.repo.PATH, specs=other.traverse(), restrict=True
|
||||||
)
|
)
|
||||||
|
|
||||||
# This handles cases where there are already providers for both vpkgs
|
|
||||||
if not self_index.satisfies(other_index):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# These two loops handle cases where there is an overly restrictive
|
# These two loops handle cases where there is an overly restrictive
|
||||||
# vpkg in one spec for a provider in the other (e.g., mpi@3: is not
|
# vpkg in one spec for a provider in the other (e.g., mpi@3: is not
|
||||||
# compatible with mpich2)
|
# compatible with mpich2)
|
||||||
|
@ -3879,7 +3902,46 @@ def satisfies(self, other: Union[str, "Spec"], deps: bool = True) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# If we arrived here, then rhs is abstract. At the moment we don't care about the edge
|
# If we arrived here, then rhs is abstract. At the moment we don't care about the edge
|
||||||
# structure of an abstract DAG - hence the deps=False parameter.
|
# structure of an abstract DAG, so we check if any edge could satisfy the properties
|
||||||
|
# we ask for.
|
||||||
|
lhs_edges: Dict[str, Set[DependencySpec]] = collections.defaultdict(set)
|
||||||
|
for rhs_edge in other.traverse_edges(root=False, cover="edges"):
|
||||||
|
# If we are checking for ^mpi we need to verify if there is any edge
|
||||||
|
if rhs_edge.spec.virtual:
|
||||||
|
rhs_edge.update_virtuals(virtuals=(rhs_edge.spec.name,))
|
||||||
|
|
||||||
|
if not rhs_edge.virtuals:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not lhs_edges:
|
||||||
|
# Construct a map of the link/run subDAG + direct "build" edges,
|
||||||
|
# keyed by dependency name
|
||||||
|
for lhs_edge in self.traverse_edges(
|
||||||
|
root=False, cover="edges", deptype=("link", "run")
|
||||||
|
):
|
||||||
|
lhs_edges[lhs_edge.spec.name].add(lhs_edge)
|
||||||
|
for virtual_name in lhs_edge.virtuals:
|
||||||
|
lhs_edges[virtual_name].add(lhs_edge)
|
||||||
|
|
||||||
|
build_edges = self.edges_to_dependencies(depflag=dt.BUILD)
|
||||||
|
for lhs_edge in build_edges:
|
||||||
|
lhs_edges[lhs_edge.spec.name].add(lhs_edge)
|
||||||
|
for virtual_name in lhs_edge.virtuals:
|
||||||
|
lhs_edges[virtual_name].add(lhs_edge)
|
||||||
|
|
||||||
|
# We don't have edges to this dependency
|
||||||
|
current_dependency_name = rhs_edge.spec.name
|
||||||
|
if current_dependency_name not in lhs_edges:
|
||||||
|
return False
|
||||||
|
|
||||||
|
for virtual in rhs_edge.virtuals:
|
||||||
|
has_virtual = any(
|
||||||
|
virtual in edge.virtuals for edge in lhs_edges[current_dependency_name]
|
||||||
|
)
|
||||||
|
if not has_virtual:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Edges have been checked above already, hence deps=False
|
||||||
return all(
|
return all(
|
||||||
any(lhs.satisfies(rhs, deps=False) for lhs in self.traverse(root=False))
|
any(lhs.satisfies(rhs, deps=False) for lhs in self.traverse(root=False))
|
||||||
for rhs in other.traverse(root=False)
|
for rhs in other.traverse(root=False)
|
||||||
|
@ -4081,9 +4143,7 @@ def __getitem__(self, name):
|
||||||
"""
|
"""
|
||||||
query_parameters = name.split(":")
|
query_parameters = name.split(":")
|
||||||
if len(query_parameters) > 2:
|
if len(query_parameters) > 2:
|
||||||
msg = "key has more than one ':' symbol."
|
raise KeyError("key has more than one ':' symbol. At most one is admitted.")
|
||||||
msg += " At most one is admitted."
|
|
||||||
raise KeyError(msg)
|
|
||||||
|
|
||||||
name, query_parameters = query_parameters[0], query_parameters[1:]
|
name, query_parameters = query_parameters[0], query_parameters[1:]
|
||||||
if query_parameters:
|
if query_parameters:
|
||||||
|
@ -4108,11 +4168,17 @@ def __getitem__(self, name):
|
||||||
itertools.chain(
|
itertools.chain(
|
||||||
# Regular specs
|
# Regular specs
|
||||||
(x for x in order() if x.name == name),
|
(x for x in order() if x.name == name),
|
||||||
|
(
|
||||||
|
x
|
||||||
|
for x in order()
|
||||||
|
if (not x.virtual)
|
||||||
|
and any(name in edge.virtuals for edge in x.edges_from_dependents())
|
||||||
|
),
|
||||||
(x for x in order() if (not x.virtual) and x.package.provides(name)),
|
(x for x in order() if (not x.virtual) and x.package.provides(name)),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
raise KeyError("No spec with name %s in %s" % (name, self))
|
raise KeyError(f"No spec with name {name} in {self}")
|
||||||
|
|
||||||
if self._concrete:
|
if self._concrete:
|
||||||
return SpecBuildInterface(value, name, query_parameters)
|
return SpecBuildInterface(value, name, query_parameters)
|
||||||
|
@ -4490,17 +4556,27 @@ def format_path(
|
||||||
return str(path_ctor(*output_path_components))
|
return str(path_ctor(*output_path_components))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
sorted_nodes = [self] + sorted(
|
root_str = [self.format()]
|
||||||
|
sorted_dependencies = sorted(
|
||||||
self.traverse(root=False), key=lambda x: (x.name, x.abstract_hash)
|
self.traverse(root=False), key=lambda x: (x.name, x.abstract_hash)
|
||||||
)
|
)
|
||||||
return " ^".join(d.format() for d in sorted_nodes).strip()
|
sorted_dependencies = [
|
||||||
|
d.format("{edge_attributes} " + DEFAULT_FORMAT) for d in sorted_dependencies
|
||||||
|
]
|
||||||
|
spec_str = " ^".join(root_str + sorted_dependencies)
|
||||||
|
return spec_str.strip()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def colored_str(self):
|
def colored_str(self):
|
||||||
sorted_nodes = [self] + sorted(
|
root_str = [self.cformat()]
|
||||||
|
sorted_dependencies = sorted(
|
||||||
self.traverse(root=False), key=lambda x: (x.name, x.abstract_hash)
|
self.traverse(root=False), key=lambda x: (x.name, x.abstract_hash)
|
||||||
)
|
)
|
||||||
return " ^".join(d.cformat() for d in sorted_nodes).strip()
|
sorted_dependencies = [
|
||||||
|
d.cformat("{edge_attributes} " + DISPLAY_FORMAT) for d in sorted_dependencies
|
||||||
|
]
|
||||||
|
spec_str = " ^".join(root_str + sorted_dependencies)
|
||||||
|
return spec_str.strip()
|
||||||
|
|
||||||
def install_status(self):
|
def install_status(self):
|
||||||
"""Helper for tree to print DB install status."""
|
"""Helper for tree to print DB install status."""
|
||||||
|
|
|
@ -642,3 +642,13 @@ def test_effective_deptype_run_environment(default_mock_concretization):
|
||||||
for spec, effective_type in spack.build_environment.effective_deptypes(s, context=Context.RUN):
|
for spec, effective_type in spack.build_environment.effective_deptypes(s, context=Context.RUN):
|
||||||
assert effective_type & expected_flags.pop(spec.name) == effective_type
|
assert effective_type & expected_flags.pop(spec.name) == effective_type
|
||||||
assert not expected_flags, f"Missing {expected_flags.keys()} from effective_deptypes"
|
assert not expected_flags, f"Missing {expected_flags.keys()} from effective_deptypes"
|
||||||
|
|
||||||
|
|
||||||
|
def test_monkey_patching_works_across_virtual(default_mock_concretization):
|
||||||
|
"""Assert that a monkeypatched attribute is found regardless we access through the
|
||||||
|
real name or the virtual name.
|
||||||
|
"""
|
||||||
|
s = default_mock_concretization("mpileaks ^mpich")
|
||||||
|
s["mpich"].foo = "foo"
|
||||||
|
assert s["mpich"].foo == "foo"
|
||||||
|
assert s["mpi"].foo == "foo"
|
||||||
|
|
|
@ -14,7 +14,14 @@
|
||||||
|
|
||||||
dependencies = SpackCommand("dependencies")
|
dependencies = SpackCommand("dependencies")
|
||||||
|
|
||||||
mpis = ["low-priority-provider", "mpich", "mpich2", "multi-provider-mpi", "zmpi"]
|
mpis = [
|
||||||
|
"intel-parallel-studio",
|
||||||
|
"low-priority-provider",
|
||||||
|
"mpich",
|
||||||
|
"mpich2",
|
||||||
|
"multi-provider-mpi",
|
||||||
|
"zmpi",
|
||||||
|
]
|
||||||
mpi_deps = ["fake"]
|
mpi_deps = ["fake"]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2461,8 +2461,12 @@ def test_concretize_user_specs_together():
|
||||||
e.remove("mpich")
|
e.remove("mpich")
|
||||||
e.add("mpich2")
|
e.add("mpich2")
|
||||||
|
|
||||||
|
exc_cls = spack.error.SpackError
|
||||||
|
if spack.config.get("config:concretizer") == "clingo":
|
||||||
|
exc_cls = spack.error.UnsatisfiableSpecError
|
||||||
|
|
||||||
# Concretizing without invalidating the concrete spec for mpileaks fails
|
# Concretizing without invalidating the concrete spec for mpileaks fails
|
||||||
with pytest.raises(spack.error.UnsatisfiableSpecError):
|
with pytest.raises(exc_cls):
|
||||||
e.concretize()
|
e.concretize()
|
||||||
e.concretize(force=True)
|
e.concretize(force=True)
|
||||||
|
|
||||||
|
@ -2494,9 +2498,12 @@ def test_duplicate_packages_raise_when_concretizing_together():
|
||||||
e.add("mpileaks~opt")
|
e.add("mpileaks~opt")
|
||||||
e.add("mpich")
|
e.add("mpich")
|
||||||
|
|
||||||
with pytest.raises(
|
exc_cls, match = spack.error.SpackError, None
|
||||||
spack.error.UnsatisfiableSpecError, match=r"You could consider setting `concretizer:unify`"
|
if spack.config.get("config:concretizer") == "clingo":
|
||||||
):
|
exc_cls = spack.error.UnsatisfiableSpecError
|
||||||
|
match = r"You could consider setting `concretizer:unify`"
|
||||||
|
|
||||||
|
with pytest.raises(exc_cls, match=match):
|
||||||
e.concretize()
|
e.concretize()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1838,7 +1838,8 @@ def test_installed_specs_disregard_conflicts(self, mutable_database, monkeypatch
|
||||||
# If we concretize with --reuse it is not, since "mpich~debug" was already installed
|
# If we concretize with --reuse it is not, since "mpich~debug" was already installed
|
||||||
with spack.config.override("concretizer:reuse", True):
|
with spack.config.override("concretizer:reuse", True):
|
||||||
s = Spec("mpich").concretized()
|
s = Spec("mpich").concretized()
|
||||||
assert s.satisfies("~debug")
|
assert s.installed
|
||||||
|
assert s.satisfies("~debug"), s
|
||||||
|
|
||||||
@pytest.mark.regression("32471")
|
@pytest.mark.regression("32471")
|
||||||
@pytest.mark.only_clingo("Use case not supported by the original concretizer")
|
@pytest.mark.only_clingo("Use case not supported by the original concretizer")
|
||||||
|
@ -2132,14 +2133,16 @@ def test_reuse_python_from_cli_and_extension_from_db(self, mutable_database):
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def duplicates_test_repository():
|
def duplicates_test_repository():
|
||||||
builder_test_path = os.path.join(spack.paths.repos_path, "duplicates.test")
|
repository_path = os.path.join(spack.paths.repos_path, "duplicates.test")
|
||||||
with spack.repo.use_repositories(builder_test_path) as mock_repo:
|
with spack.repo.use_repositories(repository_path) as mock_repo:
|
||||||
yield mock_repo
|
yield mock_repo
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("mutable_config", "duplicates_test_repository")
|
@pytest.mark.usefixtures("mutable_config", "duplicates_test_repository")
|
||||||
@pytest.mark.only_clingo("Not supported by the original concretizer")
|
@pytest.mark.only_clingo("Not supported by the original concretizer")
|
||||||
class TestConcretizeSeparately:
|
class TestConcretizeSeparately:
|
||||||
|
"""Collects test on separate concretization"""
|
||||||
|
|
||||||
@pytest.mark.parametrize("strategy", ["minimal", "full"])
|
@pytest.mark.parametrize("strategy", ["minimal", "full"])
|
||||||
def test_two_gmake(self, strategy):
|
def test_two_gmake(self, strategy):
|
||||||
"""Tests that we can concretize a spec with nodes using the same build
|
"""Tests that we can concretize a spec with nodes using the same build
|
||||||
|
@ -2320,3 +2323,40 @@ def test_adding_specs(self, input_specs, default_mock_concretization):
|
||||||
assert node == container[node.dag_hash()]
|
assert node == container[node.dag_hash()]
|
||||||
assert node.dag_hash() in container
|
assert node.dag_hash() in container
|
||||||
assert node is not container[node.dag_hash()]
|
assert node is not container[node.dag_hash()]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def edges_test_repository():
|
||||||
|
repository_path = os.path.join(spack.paths.repos_path, "edges.test")
|
||||||
|
with spack.repo.use_repositories(repository_path) as mock_repo:
|
||||||
|
yield mock_repo
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("mutable_config", "edges_test_repository")
|
||||||
|
@pytest.mark.only_clingo("Edge properties not supported by the original concretizer")
|
||||||
|
class TestConcretizeEdges:
|
||||||
|
"""Collects tests on edge properties"""
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"spec_str,expected_satisfies,expected_not_satisfies",
|
||||||
|
[
|
||||||
|
("conditional-edge", ["^zlib@2.0"], ["^zlib-api"]),
|
||||||
|
("conditional-edge~foo", ["^zlib@2.0"], ["^zlib-api"]),
|
||||||
|
(
|
||||||
|
"conditional-edge+foo",
|
||||||
|
["^zlib@1.0", "^zlib-api", "^[virtuals=zlib-api] zlib"],
|
||||||
|
["^[virtuals=mpi] zlib"],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_condition_triggered_by_edge_property(
|
||||||
|
self, spec_str, expected_satisfies, expected_not_satisfies
|
||||||
|
):
|
||||||
|
"""Tests that we can enforce constraints based on edge attributes"""
|
||||||
|
s = Spec(spec_str).concretized()
|
||||||
|
|
||||||
|
for expected in expected_satisfies:
|
||||||
|
assert s.satisfies(expected), str(expected)
|
||||||
|
|
||||||
|
for not_expected in expected_not_satisfies:
|
||||||
|
assert not s.satisfies(not_expected), str(not_expected)
|
||||||
|
|
|
@ -37,6 +37,7 @@ def mpileaks_possible_deps(mock_packages, mpi_names):
|
||||||
"low-priority-provider": set(),
|
"low-priority-provider": set(),
|
||||||
"dyninst": set(["libdwarf", "libelf"]),
|
"dyninst": set(["libdwarf", "libelf"]),
|
||||||
"fake": set(),
|
"fake": set(),
|
||||||
|
"intel-parallel-studio": set(),
|
||||||
"libdwarf": set(["libelf"]),
|
"libdwarf": set(["libelf"]),
|
||||||
"libelf": set(),
|
"libelf": set(),
|
||||||
"mpich": set(),
|
"mpich": set(),
|
||||||
|
|
|
@ -532,6 +532,7 @@ def test_normalize_mpileaks(self):
|
||||||
assert not spec.eq_dag(expected_normalized, deptypes=True)
|
assert not spec.eq_dag(expected_normalized, deptypes=True)
|
||||||
assert not spec.eq_dag(non_unique_nodes, deptypes=True)
|
assert not spec.eq_dag(non_unique_nodes, deptypes=True)
|
||||||
|
|
||||||
|
@pytest.mark.xfail(reason="String representation changed")
|
||||||
def test_normalize_with_virtual_package(self):
|
def test_normalize_with_virtual_package(self):
|
||||||
spec = Spec("mpileaks ^mpi ^libelf@1.8.11 ^libdwarf")
|
spec = Spec("mpileaks ^mpi ^libelf@1.8.11 ^libdwarf")
|
||||||
spec.normalize()
|
spec.normalize()
|
||||||
|
|
|
@ -294,13 +294,10 @@ def test_concrete_specs_which_satisfies_abstract(self, lhs, rhs, default_mock_co
|
||||||
("foo@4.0%pgi@4.5", "@1:3%pgi@4.4:4.6"),
|
("foo@4.0%pgi@4.5", "@1:3%pgi@4.4:4.6"),
|
||||||
("builtin.mock.mpich", "builtin.mpich"),
|
("builtin.mock.mpich", "builtin.mpich"),
|
||||||
("mpileaks ^builtin.mock.mpich", "^builtin.mpich"),
|
("mpileaks ^builtin.mock.mpich", "^builtin.mpich"),
|
||||||
("mpileaks^mpich", "^zmpi"),
|
|
||||||
("mpileaks^zmpi", "^mpich"),
|
|
||||||
("mpileaks^mpich@1.2", "^mpich@2.0"),
|
("mpileaks^mpich@1.2", "^mpich@2.0"),
|
||||||
("mpileaks^mpich@4.0^callpath@1.5", "^mpich@1:3^callpath@1.4:1.6"),
|
("mpileaks^mpich@4.0^callpath@1.5", "^mpich@1:3^callpath@1.4:1.6"),
|
||||||
("mpileaks^mpich@2.0^callpath@1.7", "^mpich@1:3^callpath@1.4:1.6"),
|
("mpileaks^mpich@2.0^callpath@1.7", "^mpich@1:3^callpath@1.4:1.6"),
|
||||||
("mpileaks^mpich@4.0^callpath@1.7", "^mpich@1:3^callpath@1.4:1.6"),
|
("mpileaks^mpich@4.0^callpath@1.7", "^mpich@1:3^callpath@1.4:1.6"),
|
||||||
("mpileaks^mpich", "^zmpi"),
|
|
||||||
("mpileaks^mpi@3", "^mpi@1.2:1.6"),
|
("mpileaks^mpi@3", "^mpi@1.2:1.6"),
|
||||||
("mpileaks^mpi@3:", "^mpich2@1.4"),
|
("mpileaks^mpi@3:", "^mpich2@1.4"),
|
||||||
("mpileaks^mpi@3:", "^mpich2"),
|
("mpileaks^mpi@3:", "^mpich2"),
|
||||||
|
@ -338,30 +335,30 @@ def test_constraining_abstract_specs_with_empty_intersection(self, lhs, rhs):
|
||||||
rhs.constrain(lhs)
|
rhs.constrain(lhs)
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"lhs,rhs,intersection_expected",
|
"lhs,rhs",
|
||||||
[
|
[
|
||||||
("mpich", "mpich +foo", True),
|
("mpich", "mpich +foo"),
|
||||||
("mpich", "mpich~foo", True),
|
("mpich", "mpich~foo"),
|
||||||
("mpich", "mpich foo=1", True),
|
("mpich", "mpich foo=1"),
|
||||||
("mpich", "mpich++foo", True),
|
("mpich", "mpich++foo"),
|
||||||
("mpich", "mpich~~foo", True),
|
("mpich", "mpich~~foo"),
|
||||||
("mpich", "mpich foo==1", True),
|
("mpich", "mpich foo==1"),
|
||||||
# Flags semantics is currently different from other variant
|
# Flags semantics is currently different from other variant
|
||||||
("mpich", 'mpich cflags="-O3"', True),
|
("mpich", 'mpich cflags="-O3"'),
|
||||||
("mpich cflags=-O3", 'mpich cflags="-O3 -Ofast"', False),
|
("mpich cflags=-O3", 'mpich cflags="-O3 -Ofast"'),
|
||||||
("mpich cflags=-O2", 'mpich cflags="-O3"', False),
|
("mpich cflags=-O2", 'mpich cflags="-O3"'),
|
||||||
("multivalue-variant foo=bar", "multivalue-variant +foo", False),
|
("multivalue-variant foo=bar", "multivalue-variant +foo"),
|
||||||
("multivalue-variant foo=bar", "multivalue-variant ~foo", False),
|
("multivalue-variant foo=bar", "multivalue-variant ~foo"),
|
||||||
("multivalue-variant fee=bar", "multivalue-variant fee=baz", False),
|
("multivalue-variant fee=bar", "multivalue-variant fee=baz"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_concrete_specs_which_do_not_satisfy_abstract(
|
def test_concrete_specs_which_do_not_satisfy_abstract(
|
||||||
self, lhs, rhs, intersection_expected, default_mock_concretization
|
self, lhs, rhs, default_mock_concretization
|
||||||
):
|
):
|
||||||
lhs, rhs = default_mock_concretization(lhs), Spec(rhs)
|
lhs, rhs = default_mock_concretization(lhs), Spec(rhs)
|
||||||
|
|
||||||
assert lhs.intersects(rhs) is intersection_expected
|
assert lhs.intersects(rhs) is False
|
||||||
assert rhs.intersects(lhs) is intersection_expected
|
assert rhs.intersects(lhs) is False
|
||||||
assert not lhs.satisfies(rhs)
|
assert not lhs.satisfies(rhs)
|
||||||
assert not rhs.satisfies(lhs)
|
assert not rhs.satisfies(lhs)
|
||||||
|
|
||||||
|
@ -483,10 +480,14 @@ def test_intersects_virtual(self):
|
||||||
assert Spec("mpich2").intersects(Spec("mpi"))
|
assert Spec("mpich2").intersects(Spec("mpi"))
|
||||||
assert Spec("zmpi").intersects(Spec("mpi"))
|
assert Spec("zmpi").intersects(Spec("mpi"))
|
||||||
|
|
||||||
def test_intersects_virtual_dep_with_virtual_constraint(self):
|
def test_intersects_virtual_providers(self):
|
||||||
|
"""Tests that we can always intersect virtual providers from abstract specs.
|
||||||
|
Concretization will give meaning to virtuals, and eventually forbid certain
|
||||||
|
configurations.
|
||||||
|
"""
|
||||||
assert Spec("netlib-lapack ^openblas").intersects("netlib-lapack ^openblas")
|
assert Spec("netlib-lapack ^openblas").intersects("netlib-lapack ^openblas")
|
||||||
assert not Spec("netlib-lapack ^netlib-blas").intersects("netlib-lapack ^openblas")
|
assert Spec("netlib-lapack ^netlib-blas").intersects("netlib-lapack ^openblas")
|
||||||
assert not Spec("netlib-lapack ^openblas").intersects("netlib-lapack ^netlib-blas")
|
assert Spec("netlib-lapack ^openblas").intersects("netlib-lapack ^netlib-blas")
|
||||||
assert Spec("netlib-lapack ^netlib-blas").intersects("netlib-lapack ^netlib-blas")
|
assert Spec("netlib-lapack ^netlib-blas").intersects("netlib-lapack ^netlib-blas")
|
||||||
|
|
||||||
def test_intersectable_concrete_specs_must_have_the_same_hash(self):
|
def test_intersectable_concrete_specs_must_have_the_same_hash(self):
|
||||||
|
@ -1006,6 +1007,103 @@ def test_spec_override(self):
|
||||||
assert new_spec.compiler_flags["cflags"] == ["-O2"]
|
assert new_spec.compiler_flags["cflags"] == ["-O2"]
|
||||||
assert new_spec.compiler_flags["cxxflags"] == ["-O1"]
|
assert new_spec.compiler_flags["cxxflags"] == ["-O1"]
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"spec_str,specs_in_dag",
|
||||||
|
[
|
||||||
|
("hdf5 ^[virtuals=mpi] mpich", [("mpich", "mpich"), ("mpi", "mpich")]),
|
||||||
|
# Try different combinations with packages that provides a
|
||||||
|
# disjoint set of virtual dependencies
|
||||||
|
(
|
||||||
|
"netlib-scalapack ^mpich ^openblas-with-lapack",
|
||||||
|
[
|
||||||
|
("mpi", "mpich"),
|
||||||
|
("lapack", "openblas-with-lapack"),
|
||||||
|
("blas", "openblas-with-lapack"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"netlib-scalapack ^[virtuals=mpi] mpich ^openblas-with-lapack",
|
||||||
|
[
|
||||||
|
("mpi", "mpich"),
|
||||||
|
("lapack", "openblas-with-lapack"),
|
||||||
|
("blas", "openblas-with-lapack"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"netlib-scalapack ^mpich ^[virtuals=lapack] openblas-with-lapack",
|
||||||
|
[
|
||||||
|
("mpi", "mpich"),
|
||||||
|
("lapack", "openblas-with-lapack"),
|
||||||
|
("blas", "openblas-with-lapack"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"netlib-scalapack ^[virtuals=mpi] mpich ^[virtuals=lapack] openblas-with-lapack",
|
||||||
|
[
|
||||||
|
("mpi", "mpich"),
|
||||||
|
("lapack", "openblas-with-lapack"),
|
||||||
|
("blas", "openblas-with-lapack"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
# Test that we can mix dependencies that provide an overlapping
|
||||||
|
# sets of virtual dependencies
|
||||||
|
(
|
||||||
|
"netlib-scalapack ^[virtuals=mpi] intel-parallel-studio "
|
||||||
|
"^[virtuals=lapack] openblas-with-lapack",
|
||||||
|
[
|
||||||
|
("mpi", "intel-parallel-studio"),
|
||||||
|
("lapack", "openblas-with-lapack"),
|
||||||
|
("blas", "openblas-with-lapack"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"netlib-scalapack ^[virtuals=mpi] intel-parallel-studio ^openblas-with-lapack",
|
||||||
|
[
|
||||||
|
("mpi", "intel-parallel-studio"),
|
||||||
|
("lapack", "openblas-with-lapack"),
|
||||||
|
("blas", "openblas-with-lapack"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"netlib-scalapack ^intel-parallel-studio ^[virtuals=lapack] openblas-with-lapack",
|
||||||
|
[
|
||||||
|
("mpi", "intel-parallel-studio"),
|
||||||
|
("lapack", "openblas-with-lapack"),
|
||||||
|
("blas", "openblas-with-lapack"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
# Test that we can bind more than one virtual to the same provider
|
||||||
|
(
|
||||||
|
"netlib-scalapack ^[virtuals=lapack,blas] openblas-with-lapack",
|
||||||
|
[("lapack", "openblas-with-lapack"), ("blas", "openblas-with-lapack")],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_virtual_deps_bindings(self, default_mock_concretization, spec_str, specs_in_dag):
|
||||||
|
if spack.config.get("config:concretizer") == "original":
|
||||||
|
pytest.skip("Use case not supported by the original concretizer")
|
||||||
|
|
||||||
|
s = default_mock_concretization(spec_str)
|
||||||
|
for label, expected in specs_in_dag:
|
||||||
|
assert label in s
|
||||||
|
assert s[label].satisfies(expected), label
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"spec_str",
|
||||||
|
[
|
||||||
|
# openblas-with-lapack needs to provide blas and lapack together
|
||||||
|
"netlib-scalapack ^[virtuals=blas] intel-parallel-studio ^openblas-with-lapack",
|
||||||
|
# intel-* provides blas and lapack together, openblas can provide blas only
|
||||||
|
"netlib-scalapack ^[virtuals=lapack] intel-parallel-studio ^openblas",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_unsatisfiable_virtual_deps_bindings(self, spec_str):
|
||||||
|
if spack.config.get("config:concretizer") == "original":
|
||||||
|
pytest.skip("Use case not supported by the original concretizer")
|
||||||
|
|
||||||
|
with pytest.raises(spack.solver.asp.UnsatisfiableSpecError):
|
||||||
|
Spec(spec_str).concretized()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"spec_str,format_str,expected",
|
"spec_str,format_str,expected",
|
||||||
|
|
|
@ -530,6 +530,26 @@ def _specfile_for(spec_str, filename):
|
||||||
[Token(TokenType.VERSION, value="@:0.4"), Token(TokenType.COMPILER, value="% nvhpc")],
|
[Token(TokenType.VERSION, value="@:0.4"), Token(TokenType.COMPILER, value="% nvhpc")],
|
||||||
"@:0.4%nvhpc",
|
"@:0.4%nvhpc",
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
"^[virtuals=mpi] openmpi",
|
||||||
|
[
|
||||||
|
Token(TokenType.START_EDGE_PROPERTIES, value="^["),
|
||||||
|
Token(TokenType.KEY_VALUE_PAIR, value="virtuals=mpi"),
|
||||||
|
Token(TokenType.END_EDGE_PROPERTIES, value="]"),
|
||||||
|
Token(TokenType.UNQUALIFIED_PACKAGE_NAME, value="openmpi"),
|
||||||
|
],
|
||||||
|
"^[virtuals=mpi] openmpi",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"^[deptypes=link,build] zlib",
|
||||||
|
[
|
||||||
|
Token(TokenType.START_EDGE_PROPERTIES, value="^["),
|
||||||
|
Token(TokenType.KEY_VALUE_PAIR, value="deptypes=link,build"),
|
||||||
|
Token(TokenType.END_EDGE_PROPERTIES, value="]"),
|
||||||
|
Token(TokenType.UNQUALIFIED_PACKAGE_NAME, value="zlib"),
|
||||||
|
],
|
||||||
|
"^[deptypes=build,link] zlib",
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"zlib@git.foo/bar",
|
"zlib@git.foo/bar",
|
||||||
[
|
[
|
||||||
|
@ -923,6 +943,9 @@ def test_disambiguate_hash_by_spec(spec1, spec2, constraint, mock_packages, monk
|
||||||
("x platform=test platform=test", spack.spec.DuplicateArchitectureError),
|
("x platform=test platform=test", spack.spec.DuplicateArchitectureError),
|
||||||
("x os=fe platform=test target=fe os=fe", spack.spec.DuplicateArchitectureError),
|
("x os=fe platform=test target=fe os=fe", spack.spec.DuplicateArchitectureError),
|
||||||
("x target=be platform=test os=be os=fe", spack.spec.DuplicateArchitectureError),
|
("x target=be platform=test os=be os=fe", spack.spec.DuplicateArchitectureError),
|
||||||
|
("^[@foo] zlib", spack.parser.SpecParsingError),
|
||||||
|
# TODO: Remove this as soon as use variants are added and we can parse custom attributes
|
||||||
|
("^[foo=bar] zlib", spack.parser.SpecParsingError),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_error_conditions(text, exc_cls):
|
def test_error_conditions(text, exc_cls):
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other
|
||||||
|
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
|
from spack.package import *
|
||||||
|
|
||||||
|
|
||||||
|
class IntelParallelStudio(Package):
|
||||||
|
"""Intel Parallel Studio."""
|
||||||
|
|
||||||
|
homepage = "https://software.intel.com/en-us/intel-parallel-studio-xe"
|
||||||
|
url = "http://tec/16225/parallel_studio_xe_2020_cluster_edition.tgz"
|
||||||
|
|
||||||
|
version("cluster.2020.0", sha256="b1d3e3e425b2e44a06760ff173104bdf")
|
||||||
|
|
||||||
|
provides("mpi@:3")
|
||||||
|
provides("scalapack")
|
||||||
|
provides("blas", "lapack")
|
|
@ -14,5 +14,5 @@ class LowPriorityProvider(Package):
|
||||||
|
|
||||||
version("1.0", md5="0123456789abcdef0123456789abcdef")
|
version("1.0", md5="0123456789abcdef0123456789abcdef")
|
||||||
|
|
||||||
provides("lapack")
|
# A low priority provider that provides both these specs together
|
||||||
provides("mpi")
|
provides("mpi", "lapack")
|
||||||
|
|
|
@ -19,4 +19,4 @@ class ManyVirtualConsumer(Package):
|
||||||
# This directive is an example of imposing a constraint on a
|
# This directive is an example of imposing a constraint on a
|
||||||
# dependency is that dependency is in the DAG. This pattern
|
# dependency is that dependency is in the DAG. This pattern
|
||||||
# is mainly used with virtual providers.
|
# is mainly used with virtual providers.
|
||||||
depends_on("low-priority-provider@1.0", when="^low-priority-provider")
|
depends_on("low-priority-provider@1.0", when="^[virtuals=mpi,lapack] low-priority-provider")
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other
|
||||||
|
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
|
|
||||||
|
from spack.package import *
|
||||||
|
|
||||||
|
|
||||||
|
class NetlibScalapack(Package):
|
||||||
|
homepage = "http://www.netlib.org/scalapack/"
|
||||||
|
url = "http://www.netlib.org/scalapack/scalapack-2.1.0.tgz"
|
||||||
|
|
||||||
|
version("2.1.0", "b1d3e3e425b2e44a06760ff173104bdf")
|
||||||
|
|
||||||
|
provides("scalapack")
|
||||||
|
|
||||||
|
depends_on("mpi")
|
||||||
|
depends_on("lapack")
|
||||||
|
depends_on("blas")
|
|
@ -14,5 +14,4 @@ class OpenblasWithLapack(Package):
|
||||||
|
|
||||||
version("0.2.15", md5="b1190f3d3471685f17cfd1ec1d252ac9")
|
version("0.2.15", md5="b1190f3d3471685f17cfd1ec1d252ac9")
|
||||||
|
|
||||||
provides("lapack")
|
provides("lapack", "blas")
|
||||||
provides("blas")
|
|
||||||
|
|
|
@ -28,8 +28,7 @@ class LuaLuajitOpenresty(LuaImplPackage):
|
||||||
description="add symlinks to make lua-luajit a drop-in lua replacement",
|
description="add symlinks to make lua-luajit a drop-in lua replacement",
|
||||||
)
|
)
|
||||||
|
|
||||||
provides("lua-lang@5.1", when="+lualinks")
|
provides("luajit", "lua-lang@5.1", when="+lualinks")
|
||||||
provides("luajit")
|
|
||||||
lua_version_override = "5.1"
|
lua_version_override = "5.1"
|
||||||
|
|
||||||
@run_after("install")
|
@run_after("install")
|
||||||
|
|
|
@ -33,8 +33,7 @@ class LuaLuajit(LuaImplPackage):
|
||||||
description="add symlinks to make lua-luajit a drop-in lua replacement",
|
description="add symlinks to make lua-luajit a drop-in lua replacement",
|
||||||
)
|
)
|
||||||
|
|
||||||
provides("lua-lang@5.1", when="+lualinks")
|
provides("luajit", "lua-lang@5.1", when="+lualinks")
|
||||||
provides("luajit")
|
|
||||||
lua_version_override = "5.1"
|
lua_version_override = "5.1"
|
||||||
conflicts("platform=darwin", msg="luajit not supported on MacOS, see lua-luajit-openresty")
|
conflicts("platform=darwin", msg="luajit not supported on MacOS, see lua-luajit-openresty")
|
||||||
|
|
||||||
|
|
|
@ -88,8 +88,7 @@ class Openblas(CMakePackage, MakefilePackage):
|
||||||
)
|
)
|
||||||
|
|
||||||
# virtual dependency
|
# virtual dependency
|
||||||
provides("blas")
|
provides("blas", "lapack")
|
||||||
provides("lapack")
|
|
||||||
provides("lapack@3.9.1:", when="@0.3.15:")
|
provides("lapack@3.9.1:", when="@0.3.15:")
|
||||||
provides("lapack@3.7.0", when="@0.2.20")
|
provides("lapack@3.7.0", when="@0.2.20")
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other
|
||||||
|
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
from spack.package import *
|
||||||
|
|
||||||
|
|
||||||
|
class ConditionalEdge(Package):
|
||||||
|
"""This package has a variant that triggers a condition only if a required dependency is
|
||||||
|
providing a virtual.
|
||||||
|
"""
|
||||||
|
|
||||||
|
homepage = "http://www.example.com"
|
||||||
|
url = "http://www.example.com/a-1.0.tar.gz"
|
||||||
|
|
||||||
|
version("2.0", md5="abcdef0123456789abcdef0123456789")
|
||||||
|
version("1.0", md5="0123456789abcdef0123456789abcdef")
|
||||||
|
|
||||||
|
variant("foo", default=False, description="Just a regular foo")
|
||||||
|
|
||||||
|
# zlib is a real package, providing zlib-api
|
||||||
|
depends_on("zlib")
|
||||||
|
depends_on("zlib-api", when="+foo")
|
||||||
|
depends_on("zlib@1.0", when="^[virtuals=zlib-api] zlib")
|
19
var/spack/repos/edges.test/packages/zlib/package.py
Normal file
19
var/spack/repos/edges.test/packages/zlib/package.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other
|
||||||
|
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
from spack.package import *
|
||||||
|
|
||||||
|
|
||||||
|
class Zlib(Package):
|
||||||
|
"""This package has a variant that triggers a condition only if a required dependency is
|
||||||
|
providing a virtual.
|
||||||
|
"""
|
||||||
|
|
||||||
|
homepage = "http://www.example.com"
|
||||||
|
url = "http://www.example.com/a-1.0.tar.gz"
|
||||||
|
|
||||||
|
version("2.0", md5="abcdef0123456789abcdef0123456789")
|
||||||
|
version("1.0", md5="0123456789abcdef0123456789abcdef")
|
||||||
|
|
||||||
|
provides("zlib-api")
|
2
var/spack/repos/edges.test/repo.yaml
Normal file
2
var/spack/repos/edges.test/repo.yaml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
repo:
|
||||||
|
namespace: edges.test
|
Loading…
Reference in a new issue