3 # This file is part of the GROMACS molecular simulation package.
5 # Copyright (c) 2020, by the GROMACS development team, led by
6 # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
7 # and including many others, as listed in the AUTHORS file in the
8 # top-level source directory and at http://www.gromacs.org.
10 # GROMACS is free software; you can redistribute it and/or
11 # modify it under the terms of the GNU Lesser General Public License
12 # as published by the Free Software Foundation; either version 2.1
13 # of the License, or (at your option) any later version.
15 # GROMACS is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 # Lesser General Public License for more details.
20 # You should have received a copy of the GNU Lesser General Public
21 # License along with GROMACS; if not, see
22 # http://www.gnu.org/licenses, or write to the Free Software Foundation,
23 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 # If you want to redistribute modifications to GROMACS, please
26 # consider that scientific software is very special. Version
27 # control is crucial - bugs must be traceable. We will be happy to
28 # consider code for inclusion in the official distribution, but
29 # derived work must not be called official GROMACS. Details are found
30 # in the README & COPYING files - if they are missing, get the
31 # official version at http://www.gromacs.org.
33 # To help us fund GROMACS development, we humbly ask that you cite
34 # the research papers on the package. Check out http://www.gromacs.org.
37 Generates a set of docker images used for running GROMACS CI on Gitlab.
38 The images are prepared according to a selection of build configuration targets
39 that hope to cover a broad enough scope of different possible systems,
40 allowing us to check compiler types and versions, as well as libraries used
41 for accelerators and parallel communication systems. Each combinations is
42 described as an entry in the build_configs dictionary, with the script
43 analysing the logic and adding build stages as needed.
45 Based on the example script provided by the NVidia HPCCM repository.
48 * Paul Bauer <paul.bauer.q@gmail.com>
49 * Eric Irrgang <ericirrgang@gmail.com>
50 * Joe Jordan <e.jjordan12@gmail.com>
54 $ python3 scripted_gmx_docker_builds.py --help
55 $ python3 scripted_gmx_docker_builds.py --format docker > Dockerfile && docker build .
56 $ python3 scripted_gmx_docker_builds.py | docker build -
69 'This module assumes availability of supporting modules in the same directory. Add the directory to '
70 'PYTHONPATH or invoke Python from within the module directory so module location can be resolved.')
73 # Parse command line arguments
74 parser = argparse.ArgumentParser(description='GROMACS CI image creation script', parents=[utility.parser])
76 parser.add_argument('--format', type=str, default='docker',
77 choices=['docker', 'singularity'],
78 help='Container specification format (default: docker)')
80 def main(args) -> hpccm.Stage:
82 Stage0 = hpccm.Stage()
84 # Create string for base image tag
85 base_image_tag = str()
87 # Check if we use CUDA images or plain linux images
88 if (args.cuda is not None):
89 cuda_version_tag = 'nvidia/cuda:' + args.cuda + '-devel'
90 if (args.centos is not None):
91 cuda_version_tag += '-centos' + args.centos
92 elif (args.ubuntu is not None):
93 if ((args.cuda == '9.0') and (args.ubuntu == '18.04')):
94 raise RuntimeError('Can not combine CUDA 9.0 and Ubuntu 18.04')
95 cuda_version_tag += '-ubuntu' + args.ubuntu
97 raise RuntimeError('Logic error: no Linux distribution selected.')
99 base_image_tag = cuda_version_tag
101 if (args.centos is not None):
102 base_image_tag = 'centos:centos' + args.centos
103 elif (args.ubuntu is not None):
104 base_image_tag = 'ubuntu:' + args.ubuntu
106 raise RuntimeError('Logic error: no Linux distribution selected.')
108 Stage0 += hpccm.primitives.baseimage(image=base_image_tag)
110 # Install the GROMACS packages we always will need for our builds.
111 Stage0 += hpccm.building_blocks.packages(ospackages=['build-essential',
126 Stage0 += hpccm.building_blocks.cmake(eula=True, version=args.cmake)
128 # We always add Python3 and Pip
129 Stage0 += hpccm.building_blocks.python(python3=True, python2=False, devel=True)
130 Stage0 += hpccm.building_blocks.pip(upgrade=True, pip='pip3',
131 packages=['pytest', 'networkx', 'numpy'])
134 if (args.icc is not None):
135 raise RuntimeError('Intel compiler toolchain recipe not implemented yet')
137 if (args.llvm is not None):
138 # Build the default compiler if we don't need special support
139 if (args.tsan is None):
141 if ((args.ubuntu is not None) and (args.ubuntu == '18.04')):
142 raise RuntimeError('LLVM 3 and Ubuntu 18.04 can cause issues when used together')
144 compiler = hpccm.building_blocks.llvm(extra_repository=True, version=args.llvm)
145 # Build our own version instead to get TSAN + OMP
147 compiler_branch = 'release_'+str(args.llvm)+'0'
148 compiler = hpccm.building_blocks.generic_cmake(repository='https://git.llvm.org/git/llvm.git',
149 prefix='/usr/local', recursive=True, branch=compiler_branch,
150 cmake_opts=['-D CMAKE_BUILD_TYPE=Release', '-D LLVM_ENABLE_PROJECTS="clang;openmp;clang-tools-extra"', '-D LIBOMP_TSAN_SUPPORT=on'],
151 preconfigure=['export branch='+compiler_branch,
152 '(cd projects; git clone https://git.llvm.org/git/libcxx.git; cd libcxx; git checkout $branch)',
153 '(cd projects; git clone https://git.llvm.org/git/libcxxabi.git; cd libcxxabi; git checkout $branch)',
154 '(cd projects; git clone https://git.llvm.org/git/compiler-rt.git; cd compiler-rt; git checkout $branch)',
155 '(cd ..; git clone https://git.llvm.org/git/openmp.git; cd openmp; git checkout $branch)',
156 '(cd ..; git clone https://git.llvm.org/git/clang.git; cd clang; git checkout $branch)',
157 '(cd ..; git clone https://git.llvm.org/git/clang-tools-extra.git clang-tools-extra; cd clang-tools-extra; git checkout $branch)'],
158 postinstall=['ln -s /usr/local/bin/clang++ /usr/local/bin/clang++-'+str(args.llvm),
159 'ln -s /usr/local/bin/clang-format /usr/local/bin/clang-format-'+str(args.llvm),
160 'ln -s /usr/local/bin/clang-tidy /usr/local/bin/clang-tidy-'+str(args.llvm),
161 'ln -s /usr/local/libexec/c++-analyzer /usr/local/bin/c++-analyzer-'+str(args.llvm)])
164 elif (args.gnu is not None):
165 compiler = hpccm.building_blocks.gnu(extra_repository=True,
169 raise RuntimeError('Logic error: no compiler toolchain selected.')
173 # If we use the package version of LLVM, we need to install extra packages for it.
174 if (args.llvm is not None) and (args.tsan is None):
175 Stage0 += hpccm.building_blocks.packages(ospackages=['libomp-dev',
176 'clang-format-'+str(args.llvm),
177 'clang-tidy-'+str(args.llvm)])
179 # If needed, add MPI to the image
180 if (args.mpi is not None):
181 if args.mpi == 'openmpi':
183 if (args.cuda is not None):
186 Stage0 += hpccm.building_blocks.openmpi(toolchain=compiler.toolchain, cuda=use_cuda, infiniband=False)
187 elif args.mpi == 'impi':
188 raise RuntimeError('Intel MPI recipe not implemented yet.')
190 # Add OpenCL environment if needed
191 if (args.opencl is not None):
192 if args.opencl == 'nvidia':
193 if (args.cuda is None):
194 raise RuntimeError('Need Nvidia environment for Nvidia OpenCL image')
196 Stage0 += hpccm.building_blocks.packages(ospackages=['nvidia-opencl-dev'])
198 elif args.opencl == 'intel':
199 Stage0 += hpccm.building_blocks.packages(ospackages=['ocl-icd-opencl-dev', 'opencl-headers', 'beignet-opencl-icd'])
200 elif args.opencl == 'amd':
201 # Due to the wisdom of AMD, this needs to be done differently for the OS and version! Hurray!
202 # And they don't allow wget, so this branch is not taken for now! AMD, please allow me to use wget.
203 raise RuntimeError('AMD recipe can not be generated because they do not allow wget for getting the packages.')
205 # if args.ubuntu is not '16.04':
206 # Stage0 += hpccm.building_blocks.generic_build(url='https://www2.ati.com/drivers/linux/ubuntu/'+args.ubuntu+'/amdgpu-pro-18.30-641594.tar.xz',
207 # install=['./amdgpu-install --opencl=legacy --headless -y'])
209 # Stage0 += hpccm.building_blocks.generic_build(url='https://www2.ati.com/drivers/linux/ubuntu/amdgpu-pro-18.30-641594.tar.xz',
210 # install=['./amdgpu-install --opencl=legacy --headless -y'])
212 # Stage0 += hpccm.building_blocks.generic_build(url='https://www2.ati.com/drivers/linux/rhel'+args.centos'/amdgpu-pro-18.30-641594.tar.xz',
213 # install=['./amdgpu-install --opencl=legacy --headless -y'])
215 if (args.clfft is not None):
216 Stage0 += hpccm.building_blocks.generic_cmake(repository='https://github.com/clMathLibraries/clFFT.git',
217 prefix='/usr/local', recursive=True, branch=args.clfft, directory='clFFT/src')
219 # Add documentation requirements (doxygen and sphinx + misc).
220 if (args.doxygen is not None):
221 if (args.doxygen == '1.8.5'):
222 doxygen_commit = 'ed4ed873ab0e7f15116e2052119a6729d4589f7a'
223 elif (args.doxygen == '1.8.11'):
224 doxygen_commit = 'a6d4f4df45febe588c38de37641513fd576b998f'
226 raise RuntimeError('Need to provide either 1.8.5 or 1.8.11 as doxygen version.')
227 Stage0 += hpccm.building_blocks.packages(ospackages=['autoconf',
242 'texlive-latex-base',
243 'texlive-latex-extra',
244 'texlive-fonts-recommended',
245 'texlive-fonts-extra'])
246 Stage0 += hpccm.building_blocks.generic_autotools(repository='https://github.com/westes/flex.git',
247 commit='f7788a9a0ecccdc953ed12043ccb59ca25714018',
248 prefix='/tmp/install-of-flex',
249 configure_opts=['--disable-shared'],
250 preconfigure=['./autogen.sh'])
251 Stage0 += hpccm.building_blocks.generic_autotools(repository='https://github.com/doxygen/doxygen.git',
252 commit=doxygen_commit,
254 configure_opts=['--flex /tmp/install-of-flex/bin/flex', '--static'],
255 postinstall=['sed -i \'/\"XPS\"/d;/\"PDF\"/d;/\"PS\"/d;/\"EPS\"/d;/disable ghostscript format types/d\' /etc/ImageMagick-6/policy.xml'])
256 Stage0 += hpccm.building_blocks.pip(pip='pip3', packages=['sphinx==1.6.1'])
261 if __name__ == '__main__':
262 args = parser.parse_args()
264 container_recipe = main(args)
266 # Set container specification output format
267 hpccm.config.set_container_format(args.format)
269 # Output container specification
270 print(container_recipe)