Skip to content

Commit 3354f7f

Browse files
authored
Add support for autodetection of gres resources (#181)
1 parent 5bce8de commit 3354f7f

File tree

3 files changed

+99
-10
lines changed

3 files changed

+99
-10
lines changed

README.md

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,11 @@ unique set of homogenous nodes:
5959
`free --mebi` total * `openhpc_ram_multiplier`.
6060
* `ram_multiplier`: Optional. An override for the top-level definition
6161
`openhpc_ram_multiplier`. Has no effect if `ram_mb` is set.
62-
* `gres`: Optional. List of dicts defining [generic resources](https://slurm.schedmd.com/gres.html). Each dict must define:
62+
* `gres_autodetect`: Optional. The [auto detection mechanism](https://slurm.schedmd.com/gres.conf.html#OPT_AutoDetect) to use for the generic resources. Note: you must still define the `gres` dictionary (see below) but you only need the define the `conf` key. See [GRES autodetection](#gres-autodetection) section below.
63+
* `gres`: Optional. List of dicts defining [generic resources](https://slurm.schedmd.com/gres.html). Each dict should define:
6364
- `conf`: A string with the [resource specification](https://slurm.schedmd.com/slurm.conf.html#OPT_Gres_1) but requiring the format `<name>:<type>:<number>`, e.g. `gpu:A100:2`. Note the `type` is an arbitrary string.
64-
- `file`: A string with the [File](https://slurm.schedmd.com/gres.conf.html#OPT_File) (path to device(s)) for this resource, e.g. `/dev/nvidia[0-1]` for the above example.
65+
- `file`: Omit if `gres_autodetect` is set. A string with the [File](https://slurm.schedmd.com/gres.conf.html#OPT_File) (path to device(s)) for this resource, e.g. `/dev/nvidia[0-1]` for the above example.
66+
6567
Note [GresTypes](https://slurm.schedmd.com/slurm.conf.html#OPT_GresTypes) must be set in `openhpc_config` if this is used.
6668
* `features`: Optional. List of [Features](https://slurm.schedmd.com/slurm.conf.html#OPT_Features) strings.
6769
* `node_params`: Optional. Mapping of additional parameters and values for
@@ -277,7 +279,20 @@ openhpc_nodegroups:
277279
- conf: gpu:A100:2
278280
file: /dev/nvidia[0-1]
279281
```
282+
or if using the NVML gres_autodection mechamism (NOTE: this requires recompilation of the slurm binaries to link against the [NVIDIA Management libray](#gres-autodetection)):
280283
284+
```yaml
285+
openhpc_cluster_name: hpc
286+
openhpc_nodegroups:
287+
- name: general
288+
- name: large
289+
node_params:
290+
CoreSpecCount: 2
291+
- name: gpu
292+
gres_autodetect: nvml
293+
gres:
294+
- conf: gpu:A100:2
295+
```
281296
Now two partitions can be configured - a default one with a short timelimit and
282297
no large memory nodes for testing jobs, and another with all hardware and longer
283298
job runtime for "production" jobs:
@@ -309,4 +324,54 @@ openhpc_config:
309324
-gpu
310325
```
311326

327+
## GRES autodetection
328+
329+
Some autodetection mechanisms require recompilation of the slurm packages to
330+
link against external libraries. Examples are shown in the sections below.
331+
332+
### Recompiling slurm binaries against the [NVIDIA Management libray](https://developer.nvidia.com/management-library-nvml)
333+
334+
This will allow you to use `gres_autodetect: nvml` in your `nodegroup`
335+
definitions.
336+
337+
First, [install the complete cuda toolkit from NVIDIA](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/).
338+
You can then recompile the slurm packages from the source RPMS as follows:
339+
340+
```sh
341+
dnf download --source slurm-slurmd-ohpc
342+
343+
rpm -i slurm-ohpc-*.src.rpm
344+
345+
cd /root/rpmbuild/SPECS
346+
347+
dnf builddep slurm.spec
348+
349+
rpmbuild -bb -D "_with_nvml --with-nvml=/usr/local/cuda-12.8/targets/x86_64-linux/" slurm.spec | tee /tmp/build.txt
350+
```
351+
352+
NOTE: This will need to be adapted for the version of CUDA installed (12.8 is used in the example).
353+
354+
The RPMs will be created in ` /root/rpmbuild/RPMS/x86_64/`. The method to distribute these RPMs to
355+
each compute node is out of scope of this document. You can either use a custom package repository
356+
or simply install them manually on each node with Ansible.
357+
358+
#### Configuration example
359+
360+
A configuration snippet is shown below:
361+
362+
```yaml
363+
openhpc_cluster_name: hpc
364+
openhpc_nodegroups:
365+
- name: general
366+
- name: large
367+
node_params:
368+
CoreSpecCount: 2
369+
- name: gpu
370+
gres_autodetect: nvml
371+
gres:
372+
- conf: gpu:A100:2
373+
```
374+
for additional context refer to the GPU example in: [Multiple Nodegroups](#multiple-nodegroups).
375+
376+
312377
<b id="slurm_ver_footnote">1</b> Slurm 20.11 removed `accounting_storage/filetxt` as an option. This version of Slurm was introduced in OpenHPC v2.1 but the OpenHPC repos are common to all OpenHPC v2.x releases. [↩](#accounting_storage)

tasks/validate.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,25 @@
2121
delegate_to: localhost
2222
run_once: true
2323

24+
- name: Check gres configuration when gres_autodetect is set
25+
assert:
26+
that:
27+
- _failure_reasons | selectattr('when', 'truthy') | length == 0
28+
fail_msg: >
29+
Your nodegroup definition must include a single gres dictionary containing a conf key
30+
if gres_autodetect is set. The following nodegroup failed this check: {{ item }}.
31+
Reasons for failure: {{ _failure_reasons | selectattr('when', 'truthy') | map(attribute='msg') | join(', ') }}
32+
vars:
33+
_openhpc_gres_autodetect_groups: "{{ openhpc_nodegroups | selectattr('gres_autodetect', 'defined') | selectattr('gres_autodetect', 'search', '(?!off).*') }}"
34+
_failure_reasons:
35+
- msg: The gres key was a list with more than one item
36+
when: "{{ item.gres | length != 1 }}"
37+
- msg: The gres dictionary does not contain a conf key
38+
when: "{{ item.gres.0.conf is not defined }}"
39+
delegate_to: localhost
40+
loop: "{{ _openhpc_gres_autodetect_groups }}"
41+
run_once: true
42+
2443
- name: Fail if configuration is old
2544
assert:
2645
that: openhpc_slurm_partitions is not defined

templates/gres.conf.j2

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
AutoDetect=off
22
{% for nodegroup in openhpc_nodegroups %}
3-
{% for gres in nodegroup.gres | default([]) %}
4-
{% set gres_name, gres_type, _ = gres.conf.split(':') %}
5-
{% set inventory_group_name = openhpc_cluster_name ~ '_' ~ nodegroup.name %}
6-
{% set inventory_group_hosts = groups.get(inventory_group_name, []) %}
7-
{% for hostlist in (inventory_group_hosts | hostlist_expression) %}
8-
NodeName={{ hostlist }} Name={{ gres_name }} Type={{ gres_type }} File={{ gres.file }}
9-
{% endfor %}{# hostlists #}
10-
{% endfor %}{# gres #}
3+
{% set gres_list = nodegroup.gres | default([]) %}
4+
{% set gres_autodetect = nodegroup.gres_autodetect | default('off') %}
5+
{% set inventory_group_name = openhpc_cluster_name ~ '_' ~ nodegroup.name %}
6+
{% set inventory_group_hosts = groups.get(inventory_group_name, []) %}
7+
{% set hostlist_string = inventory_group_hosts | hostlist_expression | join(',') %}
8+
{% if gres_autodetect != 'off' %}
9+
NodeName={{ hostlist_string }} AutoDetect={{ gres_autodetect }}
10+
{% else %}
11+
{% for gres in gres_list %}
12+
{% set gres_name, gres_type, _ = gres.conf.split(':') %}
13+
NodeName={{ hostlist_string }} Name={{ gres_name }} Type={{ gres_type }} File={{ gres.file | mandatory('The gres configuration dictionary: ' ~ gres ~ ' is missing the file key, but gres_autodetect is set to off. The error occured on node group: ' ~ nodegroup.name ~ '. Please add the file key or set gres_autodetect.') }}
14+
{% endfor %}{# gres #}
15+
{% endif %}{# autodetect #}
1116
{% endfor %}{# nodegroup #}

0 commit comments

Comments
 (0)