Repository: NVIDIA/hpc-container-maker

Issue:
conda: allow changing python subversion
Hi,
our workflow needs for the moment a python 3.7 version of conda (nothing I can change on our side). Until last version, I was able to retrieve it by giving 'py37_4.8.3' as version argument, but since this version, the version argument is strictly checked in its format, and py38 (or py27) is forced.
Could the __python_version be modified by the user as well ? That would be useful for us.

Discussion:
samcmill: @adegomme does this look good to you?
adegomme: seems great ! thanks

Patch:
diff --git a/docs/building_blocks.md b/docs/building_blocks.md
index e50a59c..00a7abf 100644
--- a/docs/building_blocks.md
+++ b/docs/building_blocks.md
@@ -595,6 +595,10 @@ empty list.
 - __python2__: Boolean flag to specify that the Python 2 version of
 Anaconda should be installed.  The default is False.
 
+- __python_subversion__: The Python version to install.  This value is
+ignored if the Conda version is less than 4.8.  The default is
+`py38` if using Python 3, and `py27` if using Python 2.
+
 - __version__: The version of Anaconda to download.  The default value
 is `4.8.3`.
 
@@ -2163,6 +2167,9 @@ include the LLVM compilers when necessary. The default is True.
 - __extra_tools__: Boolean flag to specify whether to also install
 `clang-format` and `clang-tidy`.  The default is False.
 
+- __openmp__: Boolean flag to specify whether to also install OpenMP
+support.  The default is True.
+
 - __toolset__: Boolean flag to specify whether to also install the
 full LLVM toolset.  The default is False.
 
diff --git a/hpccm/building_blocks/conda.py b/hpccm/building_blocks/conda.py
index a8f4ba4..20d3beb 100644
--- a/hpccm/building_blocks/conda.py
+++ b/hpccm/building_blocks/conda.py
@@ -64,6 +64,10 @@ class conda(bb_base, hpccm.templates.rm, hpccm.templates.wget):
     python2: Boolean flag to specify that the Python 2 version of
     Anaconda should be installed.  The default is False.
 
+    python_subversion: The Python version to install.  This value is
+    ignored if the Conda version is less than 4.8.  The default is
+    `py38` if using Python 3, and `py27` if using Python 2.
+
     version: The version of Anaconda to download.  The default value
     is `4.8.3`.
 
@@ -104,7 +108,8 @@ class conda(bb_base, hpccm.templates.rm, hpccm.templates.wget):
         self.__prefix = kwargs.get('prefix', '/usr/local/anaconda')
         self.__python2 = kwargs.get('python2', False)
         self.__python_version = '2' if self.__python2 else '3'
-        self.__python_subversion = 'py27' if self.__python2 else 'py38'
+        self.__python_subversion = kwargs.get(
+            'python_subversion', 'py27' if self.__python2 else 'py38')
         self.__version = kwargs.get('version', '4.8.3')
 
         self.__commands = [] # Filled in by __setup()
diff --git a/hpccm/building_blocks/llvm.py b/hpccm/building_blocks/llvm.py
index 5f1d143..2ad8b86 100644
--- a/hpccm/building_blocks/llvm.py
+++ b/hpccm/building_blocks/llvm.py
@@ -51,6 +51,9 @@ class llvm(bb_base, hpccm.templates.envvars):
     extra_tools: Boolean flag to specify whether to also install
     `clang-format` and `clang-tidy`.  The default is False.
 
+    openmp: Boolean flag to specify whether to also install OpenMP
+    support.  The default is True.
+
     toolset: Boolean flag to specify whether to also install the
     full LLVM toolset.  The default is False.
 
@@ -97,6 +100,7 @@ class llvm(bb_base, hpccm.templates.envvars):
         self.__compiler_debs = []  # Filled in below
         self.__compiler_rpms = []  # Filled in below
         self.__extra_tools = kwargs.get('extra_tools', False)
+        self.__openmp = kwargs.get('openmp', True)
         self.__ospackages = kwargs.get('ospackages', []) # Filled in below
         self.__runtime_debs = []   # Filled in below
         self.__runtime_ospackages = [] # Filled in below
@@ -129,21 +133,26 @@ class llvm(bb_base, hpccm.templates.envvars):
 
             if self.__version:
                 if LooseVersion(self.__version) <= LooseVersion('6.0'):
+                    self.__compiler_debs = ['clang-{}'.format(self.__version)]
+                    self.__runtime_debs = [
+                        'libclang1-{}'.format(self.__version)]
+
                     # Versioned OpenMP libraries do not exist for
                     # older versions
-                    self.__compiler_debs = [
-                        'clang-{}'.format(self.__version),
-                        'libomp-dev']
-                    self.__runtime_debs = [
-                        'libclang1-{}'.format(self.__version),
-                        'libomp5']
+                    if self.__openmp:
+                        self.__compiler_debs.append('libomp-dev')
+                        self.__runtime_debs.append('libomp5')
+
                 else:
-                    self.__compiler_debs = [
-                        'clang-{}'.format(self.__version),
-                        'libomp-{}-dev'.format(self.__version)]
+                    self.__compiler_debs = ['clang-{}'.format(self.__version)]
                     self.__runtime_debs = [
-                        'libclang1-{}'.format(self.__version),
-                        'libomp5-{}'.format(self.__version)]
+                        'libclang1-{}'.format(self.__version)]
+
+                    if self.__openmp:
+                        self.__compiler_debs.append(
+                            'libomp-{}-dev'.format(self.__version))
+                        self.__runtime_debs.append(
+                            'libomp5-{}'.format(self.__version))
 
                 if self.__upstream:
                     # Upstream packages from apt.llvm.org
@@ -196,8 +205,12 @@ class llvm(bb_base, hpccm.templates.envvars):
 
             else:
                 # Distro default
-                self.__compiler_debs = ['clang', 'libomp-dev']
-                self.__runtime_debs = ['libclang1', 'libomp5']
+                self.__compiler_debs = ['clang']
+                self.__runtime_debs = ['libclang1']
+
+                if self.__openmp:
+                    self.__compiler_debs.append('libomp-dev')
+                    self.__runtime_debs.append('libomp5')
 
                 if self.__toolset or self.__extra_tools:
                     self.__compiler_debs.extend(['clang-format', 'clang-tidy'])
@@ -224,10 +237,14 @@ class llvm(bb_base, hpccm.templates.envvars):
             if self.__version:
                 if hpccm.config.g_linux_version >= StrictVersion('8.0'):
                     # Multiple versions are not available for CentOS 8
-                    self.__compiler_rpms = ['clang', 'llvm-libs', 'libomp']
-                    self.__runtime_rpms = ['llvm-libs', 'libomp']
+                    self.__compiler_rpms = ['clang', 'llvm-libs']
+                    self.__runtime_rpms = ['llvm-libs']
                     compiler_version = '8'
 
+                    if self.__openmp:
+                        self.__compiler_rpms.append('libomp')
+                        self.__runtime_rpms.append('libomp')
+
                     if self.__toolset or self.__extra_tools:
                         self.__compiler_rpms.append('clang-tools-extra')
 
@@ -236,14 +253,18 @@ class llvm(bb_base, hpccm.templates.envvars):
                 else:
                     # CentOS 7
                     self.__compiler_rpms = [
-                        'llvm-toolset-{}-clang'.format(self.__version),
-                        'llvm-toolset-{}-libomp-devel'.format(self.__version)]
+                        'llvm-toolset-{}-clang'.format(self.__version)]
                     self.__runtime_rpms = [
                         'llvm-toolset-{}-runtime'.format(self.__version),
-                        'llvm-toolset-{}-libomp'.format(self.__version),
                         'llvm-toolset-{}-compiler-rt'.format(self.__version)]
                     compiler_version = '4.8.2'
 
+                    if self.__openmp:
+                        self.__compiler_rpms.append(
+                            'llvm-toolset-{}-libomp-devel'.format(self.__version))
+                        self.__runtime_rpms.append(
+                            'llvm-toolset-{}-libomp'.format(self.__version))
+
                     if self.__toolset or self.__extra_tools:
                         self.__compiler_rpms.append('llvm-toolset-{}-clang-tools-extra'.format(self.__version))
 
@@ -258,9 +279,12 @@ class llvm(bb_base, hpccm.templates.envvars):
                 self.__compiler_rpms = ['clang']
                 if hpccm.config.g_linux_version >= StrictVersion('8.0'):
                     # CentOS 8
-                    self.__runtime_rpms = ['llvm-libs', 'libomp']
+                    self.__runtime_rpms = ['llvm-libs']
                     compiler_version = '8'
 
+                    if self.__openmp:
+                        self.__runtime_rpms.append('libomp')
+
                     if self.__toolset or self.__extra_tools:
                         self.__compiler_rpms.append('clang-tools-extra')
 


Test patch:
diff --git a/test/test_conda.py b/test/test_conda.py
index d86bdec..4a24071 100644
--- a/test/test_conda.py
+++ b/test/test_conda.py
@@ -166,6 +166,26 @@ RUN mkdir -p /var/tmp && wget -q -nc --no-check-certificate -P /var/tmp http://r
     /usr/local/anaconda/bin/conda clean -afy && \
     rm -rf /var/tmp/Miniconda2-4.7.12-Linux-x86_64.sh''')
 
+    @x86_64
+    @ubuntu
+    @docker
+    def test_python_subversion(self):
+        """python subversion"""
+        c = conda(eula=True, python_subversion='py37', version='4.8.3')
+        self.assertEqual(str(c),
+r'''# Anaconda
+RUN apt-get update -y && \
+    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+        ca-certificates \
+        wget && \
+    rm -rf /var/lib/apt/lists/*
+RUN mkdir -p /var/tmp && wget -q -nc --no-check-certificate -P /var/tmp http://repo.anaconda.com/miniconda/Miniconda3-py37_4.8.3-Linux-x86_64.sh && \
+    bash /var/tmp/Miniconda3-py37_4.8.3-Linux-x86_64.sh -b -p /usr/local/anaconda && \
+    /usr/local/anaconda/bin/conda init && \
+    ln -s /usr/local/anaconda/etc/profile.d/conda.sh /etc/profile.d/conda.sh && \
+    /usr/local/anaconda/bin/conda clean -afy && \
+    rm -rf /var/tmp/Miniconda3-py37_4.8.3-Linux-x86_64.sh''')
+
     @x86_64
     @ubuntu
     @docker
diff --git a/test/test_llvm.py b/test/test_llvm.py
index 693be94..f8a246b 100644
--- a/test/test_llvm.py
+++ b/test/test_llvm.py
@@ -169,6 +169,19 @@ ENV COMPILER_PATH=/usr/lib/gcc/aarch64-redhat-linux/8:$COMPILER_PATH \
         with self.assertRaises(RuntimeError):
             llvm()
 
+    @x86_64
+    @ubuntu
+    @docker
+    def test_openmp_ubuntu(self):
+        """openmp disabled"""
+        l = llvm(openmp=False)
+        self.assertEqual(str(l),
+r'''# LLVM compiler
+RUN apt-get update -y && \
+    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+        clang && \
+    rm -rf /var/lib/apt/lists/*''')
+
     @x86_64
     @ubuntu
     @docker