Skip to content

Commit b755670

Browse files
authored
Detect software used on the cluster with the index of Mii (#44)
* Detect binaries used with the index of Mii * Flake and using lower case python to fit the module name * Ignoring some files with codespell
1 parent 243b727 commit b755670

File tree

4 files changed

+879
-62
lines changed

4 files changed

+879
-62
lines changed

.github/workflows/spelling.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ jobs:
1717
with:
1818
check_filenames: true
1919
ignore_words_list: keypair
20-
skip: ./locale/fr/LC_MESSAGES/django.po,./locale/fr/LC_MESSAGES/djangojs.po
20+
skip: ./locale/fr/LC_MESSAGES/django.po,./locale/fr/LC_MESSAGES/djangojs.po,./mii-parser.py,./userportal/settings/30-cluster.py

mii-parser.py

+144
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
import subprocess
2+
import argparse
3+
4+
# Parse the command line arguments
5+
parser = argparse.ArgumentParser(description='Convert mii output to regex')
6+
parser.add_argument('-d', '--duplicates', action='store_true', help='show duplicates')
7+
parser.add_argument('-p', '--pretty', action='store_true', help='pretty print')
8+
parser.add_argument('-o', '--output', action='store_true', help='print output for the config file')
9+
args = parser.parse_args()
10+
11+
# Run the CLI command and capture the output
12+
output = subprocess.check_output(["mii", "list"], universal_newlines=True)
13+
14+
softwares = {'python': set(), 'R': set()}
15+
16+
for line in output.splitlines():
17+
try:
18+
soft_version = line.strip().split('/')
19+
software = soft_version[0]
20+
version = soft_version[1]
21+
except IndexError:
22+
continue
23+
24+
show = subprocess.check_output(["mii", "show", line], universal_newlines=True)
25+
if 'empty result set' in show:
26+
continue
27+
28+
# rename and group some softwares
29+
if software in ['python3', 'python2', 'python-build-bundle', 'pip']:
30+
software = 'python'
31+
if software in ['rstudio-server']:
32+
software = 'R'
33+
if software in ['namd-ofi', 'namd-ucx', 'namd-multicore', 'namd-ucx-smp', 'namd-ofi-smp']:
34+
software = 'namd'
35+
if software in ['starccm-mixed']:
36+
software = 'starccm'
37+
if software in ['gromacs-plumed', 'gromacs-cp2k', 'gromacs-ramd', 'gromacs-colvars']:
38+
software = 'gromacs'
39+
if software in ['petsc-pardiso-64bits', 'petsc-pardiso', 'petsc-64bits']:
40+
software = 'petsc'
41+
if software in ['vtk-mpi']:
42+
software = 'vtk'
43+
if software in ['hdf-fortran']:
44+
software = 'hdf'
45+
if software in ['blast+', 'rmblast']:
46+
software = 'blast'
47+
if software in ['fftw-mpi']:
48+
software = 'fftw'
49+
if software in ['meryl-lookup', 'meryl-import']:
50+
software = 'meryl'
51+
if software in ['paraview-offscreen-gpu', 'paraview-offscreen']:
52+
software = 'paraview'
53+
if software in ['openbabel-omp']:
54+
software = 'openbabel'
55+
if software in ['geant4-seq', 'geant4-topasmc3.9']:
56+
software = 'geant4'
57+
if software in ['hdf5-mpi']:
58+
software = 'hdf5'
59+
if software in ['netcdf-mpi']:
60+
software = 'netcdf'
61+
if software in ['phylobayes-mpi']:
62+
software = 'phylobayes'
63+
if software in ['ansysedt']:
64+
software = 'ansys'
65+
if software in ['hpcspades']:
66+
software = 'spades'
67+
if software in ['ambertools']:
68+
software = 'amber'
69+
if software in ['cudacore', 'nvhpc']:
70+
software = 'cuda'
71+
if software in ['mysql', 'mariadb']:
72+
software = 'mysql'
73+
if software in ['perl-no-thread']:
74+
software = 'perl'
75+
if software in ['wrf-co2', 'wrf-cmaq']:
76+
software = 'wrf'
77+
if software in ['scotch-no-thread']:
78+
software = 'scotch'
79+
if software in ['cfour-mpi']:
80+
software = 'cfour'
81+
if software in ['chapel-multicore', 'chapel-ucx', 'chapel-ofi']:
82+
software = 'chapel'
83+
if software in ['metis-64idx']:
84+
software = 'metis'
85+
if software in ['raxml-pthreads']:
86+
software = 'raxml'
87+
if software in ['mafft-mpi']:
88+
software = 'mafft'
89+
if software in ['flexiblascore']:
90+
software = 'flexiblas'
91+
if software in ['ls-dyna-mpi']:
92+
software = 'ls-dyna'
93+
94+
if software not in softwares:
95+
softwares[software] = set() # set of binaries
96+
97+
for binary in show.splitlines()[1:]:
98+
binary = binary.strip()
99+
if binary.startswith('f2py'):
100+
continue
101+
if 'python' in binary or binary.startswith('pip') or binary.startswith('easy_install'):
102+
software = 'python'
103+
if binary == 'Rscript' or binary == 'R':
104+
software = 'R'
105+
softwares[software].add(binary)
106+
107+
if software in ['openmpi', 'intelmpi', 'dpc++', 'clang', 'llvm', 'intel', 'intelmpi', 'libfabric', 'gcccore']:
108+
del softwares[software]
109+
# ignore some softwares that seems to repackage the whole world or have too many binaries
110+
if software in ['afni', 'ansys', 'masurca', 'minc-toolkit']:
111+
del softwares[software]
112+
113+
if args.pretty:
114+
for software in sorted(softwares.keys()):
115+
print(software + ":")
116+
for binary in sorted(softwares[software]):
117+
print(" " + binary)
118+
print()
119+
120+
if args.duplicates:
121+
duplicates = {}
122+
for software in softwares:
123+
binaries = softwares[software]
124+
for binary in binaries:
125+
if binary not in duplicates:
126+
duplicates[binary] = set()
127+
duplicates[binary].add(software)
128+
print("Duplicates:")
129+
for binary in duplicates:
130+
if len(duplicates[binary]) > 1:
131+
print(binary + ":")
132+
for software in duplicates[binary]:
133+
print(" " + software)
134+
print()
135+
136+
if args.output:
137+
for software in sorted(softwares.keys(), key=lambda x: len(softwares[x])):
138+
if len(softwares[software]) == 0:
139+
continue
140+
# add quotes on each binary
141+
softwares[software] = ['"' + binary + '"' for binary in softwares[software]]
142+
print(" ('{software}', [{bins}]),".format(
143+
software=software,
144+
bins=','.join(sorted(softwares[software]))))

pages/views.py

+19-8
Original file line numberDiff line numberDiff line change
@@ -470,14 +470,25 @@ def graph_software(query_str, software_regexes, extract_path=False):
470470
except KeyError:
471471
# Somehow the metric is missing the exe label
472472
continue
473-
for regex, name in software_regexes:
474-
if re.match(regex, bin):
475-
if name in software:
476-
software[name] += value
477-
else:
478-
software[name] = value
479-
accounted += value
480-
break
473+
basename = bin.split('/')[-1]
474+
for name, regex in software_regexes:
475+
if isinstance(regex, list):
476+
# not a regex but a list of binary names
477+
if basename in regex:
478+
if name in software:
479+
software[name] += value
480+
else:
481+
software[name] = value
482+
accounted += value
483+
break
484+
else:
485+
if re.match(regex, bin):
486+
if name in software:
487+
software[name] += value
488+
else:
489+
software[name] = value
490+
accounted += value
491+
break
481492
else:
482493
if extract_path:
483494
name = "Stored in /{}".format(bin.split('/')[1])

0 commit comments

Comments
 (0)