+
+{% for pkg in software %}
+{% set pkg_slug = pkg.name | replace(' ', '-') %}
+{% if pkg.is_extension -%}
+-
+ {{ pkg.name }}
+ (extension)
+
+
+ {{ pkg.name }} is a {% if pkg.type == "python" -%} Python package{% elif pkg.type == "r" -%}R library{% elif pkg.type == "perl" -%}Perl module{% endif %}
+ that is included as extension in the following software installations:
+
+ {% for parent in pkg.all_parent_names %}
+ {% set parent_slug = parent | replace(' ', '-') %}
+
+ Available in EESSI versions: {% if '2023.06' in pkg.eessi_versions -%}2023.06{% endif %}{% if '2025.06' in pkg.eessi_versions -%}2025.06{% endif %}
+
+ Supported CPU families: {% if 'AMD' in pkg.cpu_families -%}AMD{% endif %}{% if 'Intel' in pkg.cpu_families -%}Intel{% endif %}{% if 'Arm' in pkg.cpu_families -%}Arm{% endif %}{% if 'RISC-V' in pkg.cpu_families -%}RISC-V{% endif %}
+
+ Supported GPU families: {% if pkg.gpu_families == '' -%}(none){% else -%}{% if 'AMD' in pkg.gpu_families -%}AMD{% endif %}{% if 'NVIDIA' in pkg.gpu_families -%}NVIDIA{% endif %}{% endif %}
+
+
+{% endif %}
+{% endfor %}
+
+
+
+---
+
+Last update: {{ data.timestamp }}
diff --git a/docs/available_software/javascripts/populate_overview.js b/docs/available_software/javascripts/populate_overview.js
deleted file mode 100644
index 3f2bd69ae5..0000000000
--- a/docs/available_software/javascripts/populate_overview.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Copyright 2023-2023 Ghent University
- *
- *
- * SPDX license identifier: GPL-3.0-or-later
- *
- * @author: Michiel Lachaert, Kenneth Hoste (HPC-UGent)
- */
-
-/**
- * A function that populates the table on the module overview page with information about all the available modules.
- */
-function populate_overview(json_data) {
- fetch(json_data)
- .then((response) => response.json())
- .then((json) => {
- // Set generated time
- const p = document.getElementById("time")
- p.innerText = `This data was automatically generated ${json.time_generated}`
-
-
- // CONSTRUCT TABLE
-
- // list with all the names of the targets
- const all_targets = json.targets.map(x => {
- //Todo: split up the strings of the targets to automate the hierarchy of the table header
- console.log(x)
- let pathArray = x.split("/")
- pathArray = pathArray.slice(7)
- console.log(pathArray)
- console.log(pathArray[pathArray.length -1])
- x = pathArray[pathArray.length -1]
- //x = pathArray
- return ({"title": x})
- })
- console.log(all_targets)
- console.log([...[{"title": "name"}], ...all_targets])
- const table = new DataTable('#overview_table', {
- columns: [...[{"title": "name"}], ...all_targets],
- paging: true,
- columnDefs: [
- {
- targets: "_all",
- className: 'dt-body-center'
- }
- ],
- scrollX: true,
- });
- console.log(table)
-
-
- // ADD DATA
- let new_rows = [];
-
- // list_avaible contains a list with booleans.
- // These booleans indicates if the software is available on the corresponding cluster.
- for (const [software, list_available] of Object.entries(json.modules)) {
- let new_row = [`${software}`];
- list_available.forEach(bool => new_row.push(bool ? "x" : "-"));
- new_rows.push(new_row);
- }
-
- table.rows.add(new_rows).draw();
- })
-}
-
-// Only start populating the table if the correct page has been loaded.
-document$.subscribe(function() {
- if (document.getElementById("overview_table")) {
- populate_overview("../data/json_data.json")
- }
-})
diff --git a/docs/available_software/javascripts/software-filter.js b/docs/available_software/javascripts/software-filter.js
new file mode 100644
index 0000000000..727d58f895
--- /dev/null
+++ b/docs/available_software/javascripts/software-filter.js
@@ -0,0 +1,18 @@
+/*
+ * Javascript for search box in software overview page (see docs/available_software/index.md)
+ */
+document.addEventListener("DOMContentLoaded", () => {
+ const input = document.getElementById("software-search");
+ const cards = document.querySelectorAll(".software-card");
+
+ input.addEventListener("input", () => {
+ const q = input.value.toLowerCase();
+
+ cards.forEach(card => {
+ const li = card.closest("li");
+ const text = card.dataset.search.toLowerCase();
+ li.style.display = text.includes(q) ? "" : "none";
+ });
+ });
+});
+
diff --git a/docs/available_software/macros.py b/docs/available_software/macros.py
new file mode 100644
index 0000000000..df016c88db
--- /dev/null
+++ b/docs/available_software/macros.py
@@ -0,0 +1,112 @@
+# Macros implemented in Python that can be used in MarkDown files,
+# see also https://mkdocs-macros-plugin.readthedocs.io/en/latest/macros/
+#
+# author: Kenneth Hoste (Ghent University)
+# license (SPDX): GPL-2.0-only
+#
+import json
+import urllib.request
+from pathlib import Path
+
+EESSI_API_SOFTWARE_JSON_URL = 'https://www.eessi.io/api_data/data/eessi_api_metadata_software.json'
+
+CPU_ARCHS = {
+ 'x86_64': ['AMD', 'Intel'],
+ 'aarch64': ['Arm'],
+ 'riscv64': ['RISC-V'],
+}
+
+
+def define_env(env):
+
+ @env.macro
+ def load_json_eessi_software():
+ """
+ Load JSON with metadata for software.eessi.io repository,
+ and return Python dictionary with relevant info to generate software overview in EESSI documentation.
+ """
+ with urllib.request.urlopen(EESSI_API_SOFTWARE_JSON_URL) as response:
+ data = json.loads(response.read().decode('utf-8'))
+
+ data_software = data['software']
+ names = data_software.keys()
+
+ ext_parents = {}
+
+ res = {
+ 'timestamp': data['timestamp'],
+ 'n_software': len(names),
+ 'software': [],
+ }
+ for name in names:
+ name_data = data_software[name]
+ versions = name_data['versions']
+
+ # use description is last version
+ descr = ' '.join(versions[-1]['description'].strip().splitlines())
+ descr = descr.replace('<', 'less than ').replace('>', 'more than ')
+
+ # use all homepages
+ homepages = set(x['homepage'].rstrip('/') for x in versions)
+ homepages = ', '.join("%(h)s" % {'h': h} for h in homepages)
+
+ licenses = ', '.join(y for x in versions for y in x['license'])
+
+ # determine set of supported CPU families (first part of CPU target names, like x86_64 or aarch64)
+ cpu_families = set(c for v in versions for x in v['cpu_arch'] for c in CPU_ARCHS[x.split('/')[0]])
+
+ # EESSI versions in which this software is available
+ eessi_versions = set()
+
+ software = {
+ 'name': name,
+ 'homepages': homepages,
+ 'description': descr,
+ 'n_versions': len(versions),
+ 'licenses': licenses,
+ 'cpu_families': ', '.join(x for x in sorted(cpu_families)),
+ 'gpu_families': '',
+ 'is_extension': False,
+ }
+
+ for version in versions:
+
+ # determine EESSI version in which this software version is installed
+ req_mods = version['required_modules']
+ if req_mods and req_mods[0].get('module_name') == 'EESSI':
+ eessi_versions.add(req_mods[0]['module_version'])
+
+ # pick up on extensions included in this software installation (if any)
+ for ext in version['extensions']:
+ ext_key = ext['type'] + ':' + ext['name']
+
+ # keep track of "parents" for this extension name (per extension version)
+ if ext_key in ext_parents:
+ parents = ext_parents[ext_key]
+ else:
+ parents = {}
+ ext_parents[ext_key] = parents
+ # new extension, so also add it to list of software
+ res['software'].append({
+ 'is_extension': True,
+ 'name': ext['name'],
+ 'type': ext['type'],
+ 'parents': parents,
+ })
+ parent = {'name': name, 'full_module_name': version['module']['full_module_name']}
+ parents.setdefault(ext['version'], []).append(parent)
+
+ software['eessi_versions'] = ', '.join(sorted(eessi_versions))
+ res['software'].append(software)
+
+ res['software'] = sorted(res['software'], key=lambda x: x['name'].lower())
+
+ # collect names of all parents per extension
+ for ext in (x for x in res['software'] if x['is_extension']):
+ ext['all_parent_names'] = set([y['name'] for x in ext['parents'].values() for y in x])
+
+ res['n_extensions'] = len([x for x in res['software'] if x['is_extension']])
+
+ print(f"[software overview] {res['n_software']=}, {res['n_extensions']=}")
+
+ return res
diff --git a/docs/available_software/overview.md b/docs/available_software/overview.md
deleted file mode 100644
index 7744cf043f..0000000000
--- a/docs/available_software/overview.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# Available software (via modules)
-
-This table gives an overview of all the available software in EESSI per specific CPU target.
-
-
-
-
-
-
Name
-
aarch64
-
x86_64
-
-
-
-
nvidia
-
-
amd
-
intel
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/index.md b/docs/index.md
index d149b164ac..c1eeb9392b 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -26,7 +26,7 @@ For users:
* [`software.eessi.io` repository](repositories/software.eessi.io.md)
* [Access](getting_access/is_eessi_accessible.md), [initialize](using_eessi/setting_up_environment.md) and [use](using_eessi/basic_commands.md) EESSI
-* [Overview of software](available_software/overview.md)
+* [Overview of software](available_software/index.md)
* [How to run EESSI test suite](test-suite/index.md)
* [How to use EESSI in CI](using_eessi/eessi_in_ci.md)
- [GitHub Actions](using_eessi/eessi_in_ci.md/#the-eessi-github-action)
diff --git a/docs/repositories/software.eessi.io.md b/docs/repositories/software.eessi.io.md
index bb10383ab3..da650fe571 100644
--- a/docs/repositories/software.eessi.io.md
+++ b/docs/repositories/software.eessi.io.md
@@ -22,7 +22,7 @@ See [Using EESSI](../using_eessi/setting_up_environment.md).
## Available software
-See [Available software](../available_software/overview.md).
+See [Available software](../available_software/index.md).
### Architecture and micro-architecture support
diff --git a/mkdocs.yml b/mkdocs.yml
index 4f767ceefc..094e458456 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -23,14 +23,13 @@ nav:
- Software layer: software_layer.md
- Supported CPU targets: software_layer/cpu_targets.md
- Supported GPU targets: software_layer/gpu_targets.md
- - Available software and repositories:
- - Software: available_software/overview.md
- - Repositories:
- - Production:
- - Software: repositories/software.eessi.io.md
- - Versions: repositories/versions.md
- - RISC-V: repositories/riscv.eessi.io.md
- - Development repository: repositories/dev.eessi.io.md
+ - Available software: available_software/index.md
+ - Repositories:
+ - Production:
+ - Software: repositories/software.eessi.io.md
+ - Versions: repositories/versions.md
+ - RISC-V: repositories/riscv.eessi.io.md
+ - Development repository: repositories/dev.eessi.io.md
- Installation and configuration:
- Is EESSI already installed?: getting_access/is_eessi_accessible.md
- Native: getting_access/native_installation.md
@@ -98,10 +97,16 @@ plugins:
- git-revision-date-localized
# necessary for search to work
- search
- # Enable macros so we can use global variables
- - macros
+ # Enable macros so we can use global variables, and use Jinja2 templates
+ # see also https://mkdocs-macros-plugin.readthedocs.io/en/latest/macros/
+ - macros:
+ module_name: docs/available_software/macros
- redirects:
redirect_maps:
+ # useful easy-to-remember short URLs, don't remove these!
+ gpu.md: site_specific_config/gpu.md
+ rocm.md: site_specific_config/rocm.md
+ # redirects for pages that were moved at some point
adding_software.md: adding_software/overview.md
contributing_sw/building_software.md: adding_software/building_software.md
contributing_sw/contribution_policy.md: adding_software/contribution_policy.md
@@ -111,8 +116,7 @@ plugins:
contributing_sw/overview.md: adding_software/overview.md
software_layer/adding_software.md: adding_software/overview.md
pilot.md: repositories/pilot.md # https://www.eessi.io/docs/pilot is mentioned in the EESSI open access paper
- gpu.md: site_specific_config/gpu.md
- rocm.md: site_specific_config/rocm.md
+ available_software/overview.md: available_software/index.md
# training/ was renamed to training-events/ + subdirectory was removed for Happy Hour sessions
training/index.md: training-events/index.md
training/happy-hours-sessions.md: training-events/happy-hours-sessions.md
@@ -211,13 +215,10 @@ extra:
extra_javascript:
# mermaid diagram
- https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs
- # javascript which generates overview of available software
- - https://code.jquery.com/jquery-3.7.0.min.js
- - https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js
- - available_software/javascripts/populate_overview.js
- - https://cdn.datatables.net/plug-ins/2.2.2/pagination/bootstrap_input.js
+ # javascript used in overview of available software
+ - available_software/javascripts/software-filter.js
extra_css:
# CSS for popultate_overview
- https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css
- - available_software/css/style_table.css
- - https://cdn.datatables.net/2.2.2/css/dataTables.semanticui.css
+ - available_software/css/software.css
+ - https://cdn.datatables.net/2.2.2/css/dataTables.semanticui.cssoftwares