From 593d8a5204958e01fa9a6fabaa945660664e0635 Mon Sep 17 00:00:00 2001 From: Scott McMillan Date: Fri, 21 Feb 2025 14:06:47 -0600 Subject: [PATCH 1/2] Add doca_ofed building block for the NVIDIA DOCA Software Framework --- docs/building_blocks.md | 62 +++++++++ hpccm/building_blocks/__init__.py | 2 + hpccm/building_blocks/doca_ofed.py | 184 +++++++++++++++++++++++++ pydocmd.yml | 1 + test/test_doca_ofed.py | 211 +++++++++++++++++++++++++++++ 5 files changed, 460 insertions(+) create mode 100644 hpccm/building_blocks/doca_ofed.py create mode 100644 test/test_doca_ofed.py diff --git a/docs/building_blocks.md b/docs/building_blocks.md index 273c5e71..72639baa 100644 --- a/docs/building_blocks.md +++ b/docs/building_blocks.md @@ -635,6 +635,68 @@ Stage0 += c Stage1 += c.runtime() ``` +# doca_ofed +```python +doca_ofed(self, **kwargs) +``` +The `doca_ofed` building block downloads and installs the [NVIDIA +DOCA Software Framework](https://developer.nvidia.com/networking/doca). + +__Parameters__ + + +- __annotate__: Boolean flag to specify whether to include annotations +(labels). The default is False. + +- __archlabel__: The CPU architecture label assigned by Mellanox to the +package repository. The default value is `x86_64` for x86_64 +processors and `arm64-sbsa` for aarch64 processors. + +- __oslabel__: The Linux distribution label assigned by Mellanox to the +package repository. For Ubuntu, the default value is +`ubuntuXX.04` where `XX` is derived from the base image. For +RHEL-base Linux distributions, the default value is `rhelX.Y` +where `X.Y` is `9.2` for RHEL 9.x and `8.6` for RHEL 8.x. + +- __ospackages__: List of OS packages to install prior to installing +DOCA OFED. The default values are `ca-certificates`, `gnupg`, and +`wget`. + +- __packages__: List of packages to install from Mellanox OFED. For +Ubuntu, the default values are `ibverbs-providers`, +`ibverbs-utils` `libibmad-dev`, `libibmad5`, `libibumad3`, +`libibumad-dev`, `libibverbs-dev` `libibverbs1`, `librdmacm-dev`, +and `librdmacm1`. For RHEL-based Linux distributions, the default +values are `libibumad`, `libibverbs`, `libibverbs-utils`, +`librdmacm`, `rdma-core`, and `rdma-core-devel`. + +- __version__: The version of DOCA OFED to download. The default value +is `2.10.0`. + +__Examples__ + + +```python +doca_ofed(version='2.10.0') +``` + + +## runtime +```python +doca_ofed.runtime(self, _from=u'0') +``` +Generate the set of instructions to install the runtime specific +components from a build in a previous stage. + +__Examples__ + + +```python +d = doca_ofed(...) +Stage0 += d +Stage1 += d.runtime() +``` + # fftw ```python fftw(self, **kwargs) diff --git a/hpccm/building_blocks/__init__.py b/hpccm/building_blocks/__init__.py index a14502df..53fc65f5 100644 --- a/hpccm/building_blocks/__init__.py +++ b/hpccm/building_blocks/__init__.py @@ -23,6 +23,7 @@ 'charm', 'cmake', 'conda', + 'doca_ofed', 'fftw', 'gdrcopy', 'generic_autotools', @@ -78,6 +79,7 @@ from hpccm.building_blocks.charm import charm from hpccm.building_blocks.cmake import cmake from hpccm.building_blocks.conda import conda +from hpccm.building_blocks.doca_ofed import doca_ofed from hpccm.building_blocks.fftw import fftw from hpccm.building_blocks.gdrcopy import gdrcopy from hpccm.building_blocks.generic_autotools import generic_autotools diff --git a/hpccm/building_blocks/doca_ofed.py b/hpccm/building_blocks/doca_ofed.py new file mode 100644 index 00000000..c6df5cef --- /dev/null +++ b/hpccm/building_blocks/doca_ofed.py @@ -0,0 +1,184 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# pylint: disable=invalid-name, too-few-public-methods + +"""DOCA OFED building block""" + +from __future__ import absolute_import +from __future__ import unicode_literals +from __future__ import print_function + +from packaging.version import Version +import posixpath + +import hpccm.config +import hpccm.templates.annotate +import hpccm.templates.rm +import hpccm.templates.tar +import hpccm.templates.wget + +from hpccm.building_blocks.base import bb_base +from hpccm.building_blocks.packages import packages +from hpccm.common import cpu_arch, linux_distro +from hpccm.primitives.comment import comment +from hpccm.primitives.copy import copy +from hpccm.primitives.label import label +from hpccm.primitives.shell import shell + +class doca_ofed(bb_base, hpccm.templates.annotate, hpccm.templates.rm, + hpccm.templates.tar, hpccm.templates.wget): + """The `doca_ofed` building block downloads and installs the [NVIDIA + DOCA Software Framework](https://developer.nvidia.com/networking/doca). + + # Parameters + + annotate: Boolean flag to specify whether to include annotations + (labels). The default is False. + + archlabel: The CPU architecture label assigned by Mellanox to the + package repository. The default value is `x86_64` for x86_64 + processors and `arm64-sbsa` for aarch64 processors. + + oslabel: The Linux distribution label assigned by Mellanox to the + package repository. For Ubuntu, the default value is + `ubuntuXX.04` where `XX` is derived from the base image. For + RHEL-base Linux distributions, the default value is `rhelX.Y` + where `X.Y` is `9.2` for RHEL 9.x and `8.6` for RHEL 8.x. + + ospackages: List of OS packages to install prior to installing + DOCA OFED. The default values are `ca-certificates`, `gnupg`, and + `wget`. + + packages: List of packages to install from Mellanox OFED. For + Ubuntu, the default values are `ibverbs-providers`, + `ibverbs-utils` `libibmad-dev`, `libibmad5`, `libibumad3`, + `libibumad-dev`, `libibverbs-dev` `libibverbs1`, `librdmacm-dev`, + and `librdmacm1`. For RHEL-based Linux distributions, the default + values are `libibumad`, `libibverbs`, `libibverbs-utils`, + `librdmacm`, `rdma-core`, and `rdma-core-devel`. + + version: The version of DOCA OFED to download. The default value + is `2.10.0`. + + # Examples + + ```python + doca_ofed(version='2.10.0') + ``` + + """ + + def __init__(self, **kwargs): + """Initialize building block""" + + super(doca_ofed, self).__init__(**kwargs) + + self.__archlabel = kwargs.get('archlabel', '') # Filled in by __cpu_arch + self.__key = 'https://linux.mellanox.com/public/repo/doca/GPG-KEY-Mellanox.pub' + self.__oslabel = kwargs.get('oslabel', '') # Filled in by __distro + self.__ospackages = kwargs.get('ospackages', + ['ca-certificates', 'gnupg', 'wget']) + self.__packages = kwargs.get('packages', []) # Filled in by __distro + self.__version = kwargs.get('version', '2.10.0') + + # Add annotation + self.add_annotation('version', self.__version) + + # Set the CPU architecture specific parameters + self.__cpu_arch() + + # Set the Linux distribution specific parameters + self.__distro() + + # Fill in container instructions + self.__instructions() + + def __instructions(self): + """Fill in container instructions""" + + self += comment('DOCA OFED version {}'.format(self.__version)) + + self += packages(ospackages=self.__ospackages) + + self += packages( + apt_keys=[self.__key], + apt_repositories=['deb [signed-by=/usr/share/keyrings/{3}] https://linux.mellanox.com/public/repo/doca/{0}/{1}/{2}/ ./'.format(self.__version, self.__oslabel, self.__archlabel, posixpath.basename(self.__key).replace('.pub', '.gpg'))], + ospackages=self.__packages, + yum_keys=[self.__key], + yum_repositories=['https://linux.mellanox.com/public/repo/doca/{0}/{1}/{2}'.format(self.__version, self.__oslabel, self.__archlabel)]) + + self += label(metadata=self.annotate_step()) + + def __cpu_arch(self): + """Based on the CPU architecture, set values accordingly. A user + specified value overrides any defaults.""" + + if not self.__archlabel: + if hpccm.config.g_cpu_arch == cpu_arch.AARCH64: + self.__archlabel = 'arm64-sbsa' + elif hpccm.config.g_cpu_arch == cpu_arch.X86_64: + self.__archlabel = 'x86_64' + else: # pragma: no cover + raise RuntimeError('Unknown CPU architecture') + + def __distro(self): + """Based on the Linux distribution, set values accordingly. A user + specified value overrides any defaults.""" + + if hpccm.config.g_linux_distro == linux_distro.UBUNTU: + if not self.__oslabel: + if hpccm.config.g_linux_version >= Version('24.0'): + self.__oslabel = 'ubuntu24.04' + elif hpccm.config.g_linux_version >= Version('22.0'): + self.__oslabel = 'ubuntu22.04' + else: + self.__oslabel = 'ubuntu20.04' + + if not self.__packages: + self.__packages = ['libibverbs1', 'libibverbs-dev', + 'ibverbs-providers', 'ibverbs-utils', + 'libibmad5', 'libibmad-dev', + 'libibumad3', 'libibumad-dev', + 'librdmacm-dev', 'librdmacm1'] + + elif hpccm.config.g_linux_distro == linux_distro.CENTOS: + if not self.__oslabel: + if hpccm.config.g_linux_version >= Version('9.0'): + self.__oslabel = 'rhel9.2' + else: + self.__oslabel = 'rhel8.6' + + if not self.__packages: + self.__packages = ['libibverbs', 'libibverbs-utils', + 'libibumad', 'librdmacm', + 'rdma-core', 'rdma-core-devel'] + + else: # pragma: no cover + raise RuntimeError('Unknown Linux distribution') + + def runtime(self, _from='0'): + """Generate the set of instructions to install the runtime specific + components from a build in a previous stage. + + # Examples + + ```python + d = doca_ofed(...) + Stage0 += d + Stage1 += d.runtime() + ``` + """ + + return str(self) diff --git a/pydocmd.yml b/pydocmd.yml index 04b48e7e..364a2f11 100644 --- a/pydocmd.yml +++ b/pydocmd.yml @@ -13,6 +13,7 @@ generate: - hpccm.building_blocks.charm+ - hpccm.building_blocks.cmake+ - hpccm.building_blocks.conda+ + - hpccm.building_blocks.doca_ofed+ - hpccm.building_blocks.fftw+ - hpccm.building_blocks.gdrcopy+ - hpccm.building_blocks.generic_autotools+ diff --git a/test/test_doca_ofed.py b/test/test_doca_ofed.py new file mode 100644 index 00000000..84ed2b98 --- /dev/null +++ b/test/test_doca_ofed.py @@ -0,0 +1,211 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# pylint: disable=invalid-name, too-few-public-methods, bad-continuation + +"""Test cases for the mlnx_ofed module""" + +from __future__ import unicode_literals +from __future__ import print_function + +import logging # pylint: disable=unused-import +import unittest + +from helpers import aarch64, centos8, docker, rockylinux9, ubuntu20, ubuntu22, ubuntu24, x86_64 + +from hpccm.building_blocks.doca_ofed import doca_ofed + +class Test_doca_ofed(unittest.TestCase): + def setUp(self): + """Disable logging output messages""" + logging.disable(logging.ERROR) + + @x86_64 + @ubuntu20 + @docker + def test_defaults_ubuntu20(self): + """Default doca_ofed building block""" + doca = doca_ofed() + self.assertMultiLineEqual(str(doca), +r'''# DOCA OFED version 2.10.0 +RUN apt-get update -y && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + ca-certificates \ + gnupg \ + wget && \ + rm -rf /var/lib/apt/lists/* +RUN mkdir -p /usr/share/keyrings && \ + rm -f /usr/share/keyrings/GPG-KEY-Mellanox.gpg && \ + wget -qO - https://linux.mellanox.com/public/repo/doca/GPG-KEY-Mellanox.pub | gpg --dearmor -o /usr/share/keyrings/GPG-KEY-Mellanox.gpg && \ + echo "deb [signed-by=/usr/share/keyrings/GPG-KEY-Mellanox.gpg] https://linux.mellanox.com/public/repo/doca/2.10.0/ubuntu20.04/x86_64/ ./" >> /etc/apt/sources.list.d/hpccm.list && \ + apt-get update -y && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + ibverbs-providers \ + ibverbs-utils \ + libibmad-dev \ + libibmad5 \ + libibumad-dev \ + libibumad3 \ + libibverbs-dev \ + libibverbs1 \ + librdmacm-dev \ + librdmacm1 && \ + rm -rf /var/lib/apt/lists/*''') + + @aarch64 + @ubuntu22 + @docker + def test_defaults_ubuntu22(self): + """Default doca_ofed building block""" + doca = doca_ofed() + self.assertMultiLineEqual(str(doca), +r'''# DOCA OFED version 2.10.0 +RUN apt-get update -y && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + ca-certificates \ + gnupg \ + wget && \ + rm -rf /var/lib/apt/lists/* +RUN mkdir -p /usr/share/keyrings && \ + rm -f /usr/share/keyrings/GPG-KEY-Mellanox.gpg && \ + wget -qO - https://linux.mellanox.com/public/repo/doca/GPG-KEY-Mellanox.pub | gpg --dearmor -o /usr/share/keyrings/GPG-KEY-Mellanox.gpg && \ + echo "deb [signed-by=/usr/share/keyrings/GPG-KEY-Mellanox.gpg] https://linux.mellanox.com/public/repo/doca/2.10.0/ubuntu22.04/arm64-sbsa/ ./" >> /etc/apt/sources.list.d/hpccm.list && \ + apt-get update -y && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + ibverbs-providers \ + ibverbs-utils \ + libibmad-dev \ + libibmad5 \ + libibumad-dev \ + libibumad3 \ + libibverbs-dev \ + libibverbs1 \ + librdmacm-dev \ + librdmacm1 && \ + rm -rf /var/lib/apt/lists/*''') + + @x86_64 + @ubuntu24 + @docker + def test_defaults_ubuntu24(self): + """Default doca_ofed building block""" + doca = doca_ofed() + self.assertMultiLineEqual(str(doca), +r'''# DOCA OFED version 2.10.0 +RUN apt-get update -y && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + ca-certificates \ + gnupg \ + wget && \ + rm -rf /var/lib/apt/lists/* +RUN mkdir -p /usr/share/keyrings && \ + rm -f /usr/share/keyrings/GPG-KEY-Mellanox.gpg && \ + wget -qO - https://linux.mellanox.com/public/repo/doca/GPG-KEY-Mellanox.pub | gpg --dearmor -o /usr/share/keyrings/GPG-KEY-Mellanox.gpg && \ + echo "deb [signed-by=/usr/share/keyrings/GPG-KEY-Mellanox.gpg] https://linux.mellanox.com/public/repo/doca/2.10.0/ubuntu24.04/x86_64/ ./" >> /etc/apt/sources.list.d/hpccm.list && \ + apt-get update -y && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + ibverbs-providers \ + ibverbs-utils \ + libibmad-dev \ + libibmad5 \ + libibumad-dev \ + libibumad3 \ + libibverbs-dev \ + libibverbs1 \ + librdmacm-dev \ + librdmacm1 && \ + rm -rf /var/lib/apt/lists/*''') + + @x86_64 + @rockylinux9 + @docker + def test_defaults_rockylinux9(self): + """Default doca_ofed building block""" + doca = doca_ofed() + self.assertMultiLineEqual(str(doca), +r'''# DOCA OFED version 2.10.0 +RUN yum install -y \ + ca-certificates \ + gnupg \ + wget && \ + rm -rf /var/cache/yum/* +RUN rpm --import https://linux.mellanox.com/public/repo/doca/GPG-KEY-Mellanox.pub && \ + yum install -y dnf-utils && \ + yum-config-manager --add-repo https://linux.mellanox.com/public/repo/doca/2.10.0/rhel9.2/x86_64 && \ + yum install -y \ + libibumad \ + libibverbs \ + libibverbs-utils \ + librdmacm \ + rdma-core \ + rdma-core-devel && \ + rm -rf /var/cache/yum/*''') + + @x86_64 + @centos8 + @docker + def test_defaults_rockylinux8(self): + """Default doca_ofed building block""" + doca = doca_ofed() + self.assertMultiLineEqual(str(doca), +r'''# DOCA OFED version 2.10.0 +RUN yum install -y \ + ca-certificates \ + gnupg \ + wget && \ + rm -rf /var/cache/yum/* +RUN rpm --import https://linux.mellanox.com/public/repo/doca/GPG-KEY-Mellanox.pub && \ + yum install -y dnf-utils && \ + yum-config-manager --add-repo https://linux.mellanox.com/public/repo/doca/2.10.0/rhel8.6/x86_64 && \ + yum install -y \ + libibumad \ + libibverbs \ + libibverbs-utils \ + librdmacm \ + rdma-core \ + rdma-core-devel && \ + rm -rf /var/cache/yum/*''') + + @x86_64 + @ubuntu24 + @docker + def test_runtime(self): + """Runtime""" + doca = doca_ofed(version='2.10.0') + r = doca.runtime() + self.assertMultiLineEqual(r, +r'''# DOCA OFED version 2.10.0 +RUN apt-get update -y && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + ca-certificates \ + gnupg \ + wget && \ + rm -rf /var/lib/apt/lists/* +RUN mkdir -p /usr/share/keyrings && \ + rm -f /usr/share/keyrings/GPG-KEY-Mellanox.gpg && \ + wget -qO - https://linux.mellanox.com/public/repo/doca/GPG-KEY-Mellanox.pub | gpg --dearmor -o /usr/share/keyrings/GPG-KEY-Mellanox.gpg && \ + echo "deb [signed-by=/usr/share/keyrings/GPG-KEY-Mellanox.gpg] https://linux.mellanox.com/public/repo/doca/2.10.0/ubuntu24.04/x86_64/ ./" >> /etc/apt/sources.list.d/hpccm.list && \ + apt-get update -y && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + ibverbs-providers \ + ibverbs-utils \ + libibmad-dev \ + libibmad5 \ + libibumad-dev \ + libibumad3 \ + libibverbs-dev \ + libibverbs1 \ + librdmacm-dev \ + librdmacm1 && \ + rm -rf /var/lib/apt/lists/*''') From 01f9bb8c4e28e3b7e50ee08404c53a800a158fb1 Mon Sep 17 00:00:00 2001 From: Scott McMillan Date: Fri, 21 Feb 2025 14:13:24 -0600 Subject: [PATCH 2/2] Remove unnecessary imports --- hpccm/building_blocks/doca_ofed.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/hpccm/building_blocks/doca_ofed.py b/hpccm/building_blocks/doca_ofed.py index c6df5cef..19894127 100644 --- a/hpccm/building_blocks/doca_ofed.py +++ b/hpccm/building_blocks/doca_ofed.py @@ -25,17 +25,12 @@ import hpccm.config import hpccm.templates.annotate -import hpccm.templates.rm -import hpccm.templates.tar -import hpccm.templates.wget from hpccm.building_blocks.base import bb_base from hpccm.building_blocks.packages import packages from hpccm.common import cpu_arch, linux_distro from hpccm.primitives.comment import comment -from hpccm.primitives.copy import copy from hpccm.primitives.label import label -from hpccm.primitives.shell import shell class doca_ofed(bb_base, hpccm.templates.annotate, hpccm.templates.rm, hpccm.templates.tar, hpccm.templates.wget):