Skip to content

Commit b314d96

Browse files
committed
Merge from main
1 parent 4bb1559 commit b314d96

86 files changed

Lines changed: 3012 additions & 630 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import argparse
2+
import os
3+
import re
4+
import glob
5+
import json
6+
7+
8+
def parse_module_file(module_file_path):
9+
"""
10+
Extracts module name, version, and extensions from a module file.
11+
"""
12+
module_name = os.path.basename(os.path.dirname(module_file_path))
13+
version = os.path.basename(module_file_path)
14+
15+
try:
16+
with open(module_file_path, "r") as file:
17+
content = file.read()
18+
19+
# Extract extensions from content using regex
20+
match = re.search(r'extensions\("(.+)"\)', content)
21+
extensions = []
22+
23+
if match:
24+
# Split the list of packages by commas
25+
packages = match.group(1)
26+
for pkg in packages.split(","):
27+
parts = pkg.split("/")
28+
29+
# Check if the package is in the name/version format
30+
if len(parts) == 2:
31+
extensions.append((parts[0], parts[1]))
32+
elif len(parts) == 1:
33+
extensions.append((parts[0], "none"))
34+
else:
35+
print(f"Warning: Skipping invalid package format: {pkg}")
36+
37+
return {(module_name, version): tuple(extensions)}
38+
39+
except Exception as e:
40+
print(f"Error parsing module file {module_file_path}: {e}")
41+
return {(module_name, version): ()}
42+
43+
44+
def get_available_modules(base_dir):
45+
"""
46+
Get the list of modules from all subdirectories inside the specified base directory.
47+
"""
48+
try:
49+
modules = {}
50+
# Only look for .lua files
51+
for module_path in glob.glob(os.path.join(base_dir, "*/*.lua")):
52+
modules.update(parse_module_file(module_path))
53+
return modules
54+
55+
except Exception as e:
56+
print(f"Error retrieving modules from {base_dir}: {e}")
57+
return {}
58+
59+
60+
def compare_stacks(dir1, dir2):
61+
"""
62+
Compare two sets of Lmod module files, including versions and extensions.
63+
"""
64+
modules1 = get_available_modules(dir1)
65+
modules2 = get_available_modules(dir2)
66+
67+
# Find differences between the two dictionaries
68+
modules_removed = set(modules1.keys()) - set(modules2.keys())
69+
modules_added = set(modules2.keys()) - set(modules1.keys())
70+
matching_keys = set(modules1.keys()) & set(modules2.keys())
71+
72+
diff_results = {
73+
"module_differences": {
74+
"missing": list("/".join(module) for module in modules_removed),
75+
"added": list("/".join(module) for module in modules_added),
76+
},
77+
"extension_differences": [],
78+
}
79+
80+
# Compare extensions for matching keys
81+
for key in matching_keys:
82+
if modules1[key] != modules2[key]:
83+
diff_results["extension_differences"].append(
84+
{
85+
"/".join(key): {
86+
"missing": list(
87+
"/".join(key)
88+
for key in list(set(modules1[key]) - set(modules2[key]))
89+
),
90+
"added": list(
91+
"/".join(key)
92+
for key in list(set(modules2[key]) - set(modules1[key]))
93+
),
94+
}
95+
}
96+
)
97+
98+
return diff_results
99+
100+
101+
def main():
102+
# Set up argument parser
103+
parser = argparse.ArgumentParser(description="Compare two Lmod module directories")
104+
parser.add_argument("path1", type=str, help="The first directory path")
105+
parser.add_argument("path2", type=str, help="The second directory path")
106+
107+
# Parse the arguments
108+
args = parser.parse_args()
109+
110+
# Validate the paths
111+
for path in [args.path1, args.path2]:
112+
if not os.path.exists(path):
113+
print(f"Warning: Path does not exist: {path}")
114+
115+
# Compare the stacks
116+
diff_results = compare_stacks(args.path1, args.path2)
117+
118+
# Print the differences
119+
if any(
120+
[
121+
diff_results["module_differences"]["missing"],
122+
diff_results["module_differences"]["added"],
123+
diff_results["extension_differences"],
124+
]
125+
):
126+
print(json.dumps(diff_results, indent=2))
127+
exit(1)
128+
129+
130+
if __name__ == "__main__":
131+
main()
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/usr/bin/env bash
2+
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
3+
# Take the arguments
4+
base_dir=$1
5+
target_arch=$2
6+
modules_subdir="modules/all"
7+
# Decide if we want x86_64 or aarch64
8+
arch=$(echo $target_arch | cut -d"/" -f1)
9+
# Get the generic directory
10+
source_of_truth="$arch/generic"
11+
case $arch in
12+
"x86_64")
13+
echo "Using $source_of_truth as source of truth"
14+
;;
15+
"aarch64")
16+
echo "Using $source_of_truth as source of truth"
17+
;;
18+
*)
19+
echo "I don't understand the base architecture: $arch"
20+
exit 1
21+
;;
22+
esac
23+
source_of_truth_modules="$base_dir/$source_of_truth/$modules_subdir"
24+
arch_modules="$base_dir/$target_arch/$modules_subdir"
25+
echo "Comparing $arch_modules to $source_of_truth_modules"
26+
python3 $script_dir/compare_stacks.py $source_of_truth_modules $arch_modules

.github/workflows/test-software.eessi.io.yml

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ jobs:
2929
- x86_64/amd/zen3
3030
- x86_64/amd/zen4
3131
- x86_64/intel/haswell
32+
- x86_64/intel/sapphirerapids
3233
- x86_64/intel/skylake_avx512
3334
- x86_64/generic
3435
steps:
@@ -59,20 +60,6 @@ jobs:
5960
# first check the CPU-only builds for this CPU target
6061
echo "just run check_missing_installations.sh (should use easystacks/software.eessi.io/${{matrix.EESSI_VERSION}}/eessi-${{matrix.EESSI_VERSION}}-*.yml with latest EasyBuild release)"
6162
for easystack_file in $(EESSI_VERSION=${{matrix.EESSI_VERSION}} .github/workflows/scripts/only_latest_easystacks.sh); do
62-
if [ ${{matrix.EESSI_SOFTWARE_SUBDIR_OVERRIDE}} = "x86_64/amd/zen4" ]; then
63-
if grep -q 2022b <<<"${easystack_file}"; then
64-
# skip the check of installed software on zen4 for foss/2022b builds
65-
continue
66-
fi
67-
if [[ $easystack_file == *"rebuilds"* ]]; then
68-
# Also handle rebuilds, make a temporary EasyStack file where we clean out all 2022b stuff and use that
69-
new_easystack=$(mktemp pruned_easystackXXX --suffix=.yml)
70-
# first clean out the options then clean out the .eb name
71-
sed '/2022b\|12\.2\.0/,/\.eb/{/\.eb/!d}' "${easystack_file}" | sed '/2022b\|12\.2\.0/d' > $new_easystack
72-
diff --unified=0 "$easystack_file" "$new_easystack" || :
73-
easystack_file="$new_easystack"
74-
fi
75-
fi
7663
echo "check missing installations for ${easystack_file}..."
7764
./check_missing_installations.sh ${easystack_file}
7865
ec=$?
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# documentation: https://help.github.com/en/articles/workflow-syntax-for-github-actions
2+
name: Check for discrepencies between software stacks in software.eessi.io
3+
on:
4+
push:
5+
branches: [ "*-software.eessi.io" ]
6+
pull_request:
7+
workflow_dispatch:
8+
permissions:
9+
contents: read # to fetch code (actions/checkout)
10+
env:
11+
EESSI_ACCELERATOR_TARGETS: |
12+
x86_64/amd/zen2:
13+
- nvidia/cc80
14+
x86_64/amd/zen3:
15+
- nvidia/cc80
16+
jobs:
17+
compare_stacks:
18+
runs-on: ubuntu-24.04
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
EESSI_VERSION:
23+
- 2023.06
24+
COMPARISON_ARCH:
25+
- aarch64/neoverse_n1
26+
- aarch64/neoverse_v1
27+
- x86_64/amd/zen2
28+
- x86_64/amd/zen3
29+
- x86_64/amd/zen4
30+
- x86_64/intel/haswell
31+
- x86_64/intel/skylake_avx512
32+
- x86_64/intel/sapphirerapids
33+
steps:
34+
- name: Check out software-layer repository
35+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
36+
37+
- name: Mount EESSI CernVM-FS pilot repository
38+
uses: eessi/github-action-eessi@v3
39+
40+
- name: Compare stacks
41+
run: |
42+
export EESSI_PREFIX=/cvmfs/software.eessi.io/versions/${{matrix.EESSI_VERSION}}
43+
export EESSI_OS_TYPE=linux
44+
env | grep ^EESSI | sort
45+
46+
# Compare the requested architecture to the generic stack
47+
# (assumes the general structure /cvmfs/software.eessi.io/versions/2023.06/software/linux/$COMPARISON_ARCH/modules/all)
48+
.github/workflows/scripts/compare_to_generic.sh ${EESSI_PREFIX}/software/${EESSI_OS_TYPE} ${{matrix.COMPARISON_ARCH}}

.github/workflows/tests_archdetect.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ jobs:
1313
matrix:
1414
proc_cpuinfo:
1515
- x86_64/intel/haswell/archspec-linux-E5-2680-v3
16+
- x86_64/intel/sapphirerapids/AWS-Rocky8-8488C
1617
- x86_64/intel/skylake_avx512/archspec-linux-6132
1718
- x86_64/amd/zen2/Azure-CentOS7-7V12
1819
- x86_64/amd/zen3/Azure-CentOS7-7V73X

0 commit comments

Comments
 (0)