tags[${#tags[@]}]=$tag
python3 $SCRIPT --cmake 3.13.0 --llvm 9 --opencl amd --mpi openmpi | docker build -t $tag -
+tag="gromacs/cmake-3.17.2-oneapi-2021.1-beta08-master"
+tags[${#tags[@]}]=$tag
+python3 $SCRIPT --cmake 3.17.2 --oneapi 2021.1-beta08 | docker build -t $tag -
+
tag="gromacs/ci-docs-llvm-master"
tags[${#tags[@]}]=$tag
python3 $SCRIPT --cmake 3.17.2 --llvm --doxygen | docker build -t $tag -
* Paul Bauer <paul.bauer.q@gmail.com>
* Eric Irrgang <ericirrgang@gmail.com>
* Joe Jordan <e.jjordan12@gmail.com>
+ * Mark Abraham <mark.j.abraham@gmail.com>
Usage::
return []
-def get_compiler(args, tsan_stage: hpccm.Stage = None) -> bb_base:
+def get_compiler(args, compiler_build_stage: hpccm.Stage = None) -> bb_base:
# Compiler
if args.icc is not None:
raise RuntimeError('Intel compiler toolchain recipe not implemented yet')
if args.llvm is not None:
# Build our own version instead to get TSAN + OMP
if args.tsan is not None:
- if tsan_stage is not None:
- compiler = tsan_stage.runtime(_from='tsan')
+ if compiler_build_stage is not None:
+ compiler = compiler_build_stage.runtime(_from='tsan')
else:
- raise RuntimeError('No TSAN stage!')
+ raise RuntimeError('No TSAN compiler build stage!')
# Build the default compiler if we don't need special support
else:
compiler = hpccm.building_blocks.llvm(extra_repository=True, version=args.llvm)
- elif (args.gcc is not None):
+ elif args.oneapi is not None:
+ if compiler_build_stage is not None:
+ compiler = compiler_build_stage.runtime(_from='oneapi')
+ # Prepare the toolchain (needed only for builds done within the Dockerfile, e.g.
+ # OpenMPI builds, which don't currently work for other reasons)
+ oneapi_toolchain = hpccm.toolchain(CC='/opt/intel/oneapi/compiler/latest/linux/bin/intel64/icc',
+ CXX='/opt/intel/oneapi/compiler/latest/linux/bin/intel64/icpc')
+ setattr(compiler, 'toolchain', oneapi_toolchain)
+
+ else:
+ raise RuntimeError('No oneAPI compiler build stage!')
+
+ elif args.gcc is not None:
compiler = hpccm.building_blocks.gnu(extra_repository=True,
version=args.gcc,
fortran=False)
use_cuda = True
if hasattr(compiler, 'toolchain'):
+ if args.oneapi is not None:
+ raise RuntimeError('oneAPI building OpenMPI is not supported')
return hpccm.building_blocks.openmpi(toolchain=compiler.toolchain, cuda=use_cuda, infiniband=False)
else:
raise RuntimeError('compiler is not an HPCCM compiler building block!')
elif args.mpi == 'impi':
+ # TODO Intel MPI from the oneAPI repo is not working reliably,
+ # reasons are unclear. When solved, add packagages called:
+ # 'intel-oneapi-mpi', 'intel-oneapi-mpi-devel'
+ # during the compiler stage.
+ # TODO also consider hpccm's intel_mpi package if that doesn't need
+ # a license to run.
raise RuntimeError('Intel MPI recipe not implemented yet.')
else:
raise RuntimeError('Requested unknown MPI implementation.')
return hpccm.building_blocks.packages(ospackages=['nvidia-opencl-dev'])
elif args.opencl == 'intel':
+ # Note, when using oneapi, there is bundled OpenCL support, so this
+ # installation is not needed.
return hpccm.building_blocks.packages(
apt_ppas=['ppa:intel-opencl/intel-opencl'],
ospackages=['opencl-headers', 'ocl-icd-libopencl1',
return None
-def add_tsan_stage(input_args, output_stages: typing.Mapping[str, hpccm.Stage]):
+def add_tsan_compiler_build_stage(input_args, output_stages: typing.Mapping[str, hpccm.Stage]):
"""Isolate the expensive TSAN preparation stage.
This is a very expensive stage, but has few and disjoint dependencies, and
'ln -s /usr/local/bin/clang-format /usr/local/bin/clang-format-' + str(input_args.llvm),
'ln -s /usr/local/bin/clang-tidy /usr/local/bin/clang-tidy-' + str(input_args.llvm),
'ln -s /usr/local/libexec/c++-analyzer /usr/local/bin/c++-analyzer-' + str(input_args.llvm)])
- output_stages['tsan'] = tsan_stage
+ output_stages['compiler_build'] = tsan_stage
+
+def oneapi_runtime(_from='0'):
+ oneapi_runtime_stage = hpccm.Stage()
+ oneapi_runtime_stage += hpccm.primitives.copy(_from='oneapi-build',
+ files={"/opt/intel": "/opt/intel",
+ "/etc/bash.bashrc": "/etc/bash.bashrc"})
+ return oneapi_runtime_stage
+
+def add_oneapi_compiler_build_stage(input_args, output_stages: typing.Mapping[str, hpccm.Stage]):
+ """Isolate the oneAPI preparation stage.
+ This stage is isolated so that its installed components are minimized in the
+ final image (chiefly /opt/intel) and its environment setup script can be
+ sourced. This also helps with rebuild time and final image size.
+
+ Note that the ICC compiler inside oneAPI on linux also needs
+ gcc to build other components and provide libstdc++.
+ """
+ if not isinstance(output_stages, collections.abc.MutableMapping):
+ raise RuntimeError('Need output_stages container.')
+ oneapi_stage = hpccm.Stage()
+ oneapi_stage += hpccm.primitives.baseimage(image=base_image_tag(input_args), _as='oneapi-build')
+
+ # Add required components for the next stage (both for hpccm and Intel's setvars.sh script)
+ oneapi_stage += hpccm.building_blocks.packages(ospackages=['wget', 'gnupg2', 'ca-certificates', 'lsb-release'])
+ oneapi_stage += hpccm.building_blocks.packages(
+ apt_keys=['https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB'],
+ apt_repositories=['deb https://apt.repos.intel.com/oneapi all main'],
+ # Add minimal packages (not the whole HPC toolkit!)
+ ospackages=['intel-oneapi-dpcpp-compiler', 'intel-oneapi-icc', 'intel-oneapi-mkl', 'intel-oneapi-mkl-devel']
+ )
+ # Ensure that all bash shells on the final container will have access to oneAPI
+ oneapi_stage += hpccm.primitives.shell(
+ commands=['echo "source /opt/intel/oneapi/setvars.sh" >> /etc/bash.bashrc']
+ )
+ setattr(oneapi_stage, 'runtime', oneapi_runtime)
+
+ output_stages['compiler_build'] = oneapi_stage
def prepare_venv(version: StrictVersion) -> typing.Sequence[str]:
"""Get shell commands to set up the venv for the requested Python version."""
# object early in this function.
stages = collections.OrderedDict()
- # If we need the TSAN compilers, the early build is more involved.
+ # If we need TSAN or oneAPI support the early build is more complex,
+ # so that our compiler images don't have all the cruft needed to get those things
+ # installed.
if args.llvm is not None and args.tsan is not None:
- add_tsan_stage(input_args=args, output_stages=stages)
+ add_tsan_compiler_build_stage(input_args=args, output_stages=stages)
+ if args.oneapi is not None:
+ add_oneapi_compiler_build_stage(input_args=args, output_stages=stages)
# Building blocks are chunks of container-builder instructions that can be
# copied to any build stage with the addition operator.
building_blocks = collections.OrderedDict()
# These are the most expensive and most reusable layers, so we put them first.
- building_blocks['compiler'] = get_compiler(args, tsan_stage=stages.get('tsan'))
+ building_blocks['compiler'] = get_compiler(args, compiler_build_stage=stages.get('compiler_build'))
building_blocks['mpi'] = get_mpi(args, building_blocks['compiler'])
# Install additional packages early in the build to optimize Docker build layer cache.
os_packages = _common_packages + get_llvm_packages(args)
if args.doxygen is not None:
os_packages += _docs_extra_packages
+ if args.oneapi is not None:
+ os_packages += ['lsb-release']
building_blocks['ospackages'] = hpccm.building_blocks.packages(ospackages=os_packages)
building_blocks['cmake'] = hpccm.building_blocks.cmake(eula=True, version=args.cmake)
* Paul Bauer <paul.bauer.q@gmail.com>
* Eric Irrgang <ericirrgang@gmail.com>
* Joe Jordan <e.jjordan12@gmail.com>
+ * Mark Abraham <mark.j.abraham@gmail.com>
"""
choices=[19, 20],
help='Select Intel compiler tool chain. '
'Some checking is implemented to avoid incompatible combinations')
+# TODO currently the installation merely gets the latest beta version of oneAPI,
+# not a specific version. GROMACS probably doesn't need to address that until
+# oneAPI makes an official release.
+compiler_group.add_argument('--oneapi', type=str, nargs='?', const="", default="2021.1-beta08",
+ help='Select Intel oneAPI package version.')
linux_group = parser.add_mutually_exclusive_group()
linux_group.add_argument('--ubuntu', type=str, nargs='?', const='18.04', default='20.04',
- export CCACHE_DIR=${PWD}/ccache
- export ASAN_SYMBOLIZER_PATH=/usr/local/bin/llvm-symbolizer
+# Base definition for using oneAPI.
+.use-oneapi:base:
+ variables:
+ # Use the HPC variants of icc and icpc so that OpenMP is active
+ CMAKE_COMPILER_SCRIPT: -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx
+ CMAKE_EXTRA_OPTIONS: -DGMX_FFT_LIBRARY=mkl
+ before_script:
+ - mkdir -p ccache
+ - export CCACHE_BASEDIR=${PWD}
+ - export CCACHE_DIR=${PWD}/ccache
COMPILER_MAJOR_VERSION: 8
CMAKE_BUILD_TYPE_OPTIONS: "-DCMAKE_BUILD_TYPE=ASAN"
+gromacs:oneapi-2021.1-beta08:configure:
+ extends:
+ - .gromacs:base:configure
+ - .use-oneapi:base
+ - .rules:merge-requests
+ image: gromacs/cmake-3.17.2-oneapi-2021.1-beta08-master
+ variables:
+ COMPILER_MAJOR_VERSION: 2021
+ before_script:
+ # Necessary to override gitlab default 'set -e' which breaks Intel's
+ # setvar.sh script
+ - set +e
+ - source /opt/intel/oneapi/setvars.sh
+
gromacs:clang-UBSAN:configure:
extends:
- .gromacs:base:configure
RELEASE_BUILD_DIR: release-builds-clang
CMAKE_BUILD_TYPE_OPTIONS: "-DCMAKE_BUILD_TYPE=RelWithAssert"
+gromacs:oneapi-2021.1-beta08:release:configure:
+ extends:
+ - .gromacs:base:release:configure
+ - .use-oneapi:base
+ - .rules:nightly-only-for-release
+ image: gromacs/cmake-3.17.2-oneapi-2021.1-beta08-master
+ variables:
+ COMPILER_MAJOR_VERSION: 2021
+ RELEASE_BUILD_DIR: release-builds-oneapi
+ before_script:
+ # Necessary to override gitlab default 'set -e' which breaks Intel's
+ # setvar.sh script
+ - set +e
+ - source /opt/intel/oneapi/setvars.sh
+
# Jobs running during build stage
.gromacs:base:build:
needs:
- job: gromacs:clang-8:configure
+gromacs:oneapi-2021.1-beta08:build:
+ extends:
+ - .variables:default
+ - .gromacs:base:build
+ - .use-ccache
+ - .before_script:default
+ - .rules:merge-requests
+ image: gromacs/cmake-3.17.2-oneapi-2021.1-beta08-master
+ needs:
+ - job: gromacs:oneapi-2021.1-beta08:configure
+ before_script:
+ # Necessary to override gitlab default 'set -e' which breaks Intel's
+ # setvar.sh script
+ - set +e
+ - source /opt/intel/oneapi/setvars.sh
+
gromacs:clang-9-mpi:build:
extends:
- .variables:default
needs:
- job: gromacs:clang-8-cuda-10.1:release:configure
+gromacs:oneapi-2021.1-beta08:release:build:
+ extends:
+ - .variables:default
+ - .gromacs:base:build
+ - .use-oneapi:base
+ - .before_script:default
+ - .use-ccache
+ - .rules:nightly-only-for-release
+ stage: release-build
+ variables:
+ BUILD_DIR: release-builds-oneapi
+ COMPILER_MAJOR_VERSION: 2021
+ image: gromacs/cmake-3.17.2-oneapi-2021.1-beta08-master
+ needs:
+ - job: gromacs:oneapi-2021.1-beta08:release:configure
+ before_script:
+ # Necessary to override gitlab default 'set -e' which breaks Intel's
+ # setvar.sh script
+ - set +e
+ - source /opt/intel/oneapi/setvars.sh
+
# Jobs running during test stage
.gromacs:base:test:
needs:
- job: gromacs:clang-UBSAN:build
+gromacs:oneapi-2021.1-beta08:test:
+ extends:
+ - .gromacs:base:test
+ - .rules:merge-requests
+ image: gromacs/cmake-3.17.2-oneapi-2021.1-beta08-master
+ needs:
+ - job: gromacs:oneapi-2021.1-beta08:build
+ before_script:
+ # Necessary to override gitlab default 'set -e' which breaks Intel's
+ # setvar.sh script
+ - set +e
+ - source /opt/intel/oneapi/setvars.sh
+
gromacs:clang-9-mpi:test:
extends:
- .gromacs:base:test
- job: gromacs:clang-9-mpi:build
- job: regressiontests:prepare
+gromacs:oneapi-2021.1-beta08:regressiontest:
+ extends:
+ - .gromacs:base:regressiontest
+ - .rules:merge-requests
+ image: gromacs/cmake-3.17.2-oneapi-2021.1-beta08-master
+ needs:
+ - job: gromacs:oneapi-2021.1-beta08:build
+ - job: regressiontests:prepare
+ before_script:
+ # Necessary to override gitlab default 'set -e' which breaks Intel's
+ # setvar.sh script
+ - set +e
+ - source /opt/intel/oneapi/setvars.sh
+
gromacs:gcc-8-cuda-10.1:release:test:
extends:
- .gromacs:base:test
- job: gromacs:clang-8-cuda-10.1:release:configure
- job: gromacs:clang-8-cuda-10.1:release:build
+gromacs:oneapi-2021.1-beta08:release:test:
+ extends:
+ - .gromacs:base:test
+ - .rules:nightly-only-for-release
+ stage: release-tests
+ image: gromacs/cmake-3.17.2-oneapi-2021.1-beta08-master
+ variables:
+ BUILD_DIR: release-builds-oneapi
+ needs:
+ - job: gromacs:oneapi-2021.1-beta08:release:configure
+ - job: gromacs:oneapi-2021.1-beta08:release:build
+ before_script:
+ # Necessary to override gitlab default 'set -e' which breaks Intel's
+ # setvar.sh script
+ - set +e
+ - source /opt/intel/oneapi/setvars.sh
+
gromacs:gcc-7:release:regressiontest:
extends:
- .gromacs:base:regressiontest
- job: gromacs:clang-8-cuda-10.1:release:build
- job: regressiontests:package
+gromacs:oneapi-2021.1-beta08:release:regressiontest:
+ extends:
+ - .gromacs:base:regressiontest
+ - .rules:nightly-only-for-release
+ stage: release-tests
+ image: gromacs/cmake-3.17.2-oneapi-2021.1-beta08-master
+ variables:
+ BUILD_DIR: release-builds-oneapi
+ REGRESSIONTEST_PME_RANK_NUMBER: 0
+ REGRESSIONTEST_TOTAL_RANK_NUMBER: 2
+ REGRESSIONTEST_OMP_RANK_NUMBER: 1
+ needs:
+ - job: gromacs:oneapi-2021.1-beta08:release:build
+ - job: regressiontests:package
+ before_script:
+ # Necessary to override gitlab default 'set -e' which breaks Intel's
+ # setvar.sh script
+ - set +e
+ - source /opt/intel/oneapi/setvars.sh
While it is our best belief that |Gromacs| will build and run pretty
much everywhere, it is important that we tell you where we really know
-it works because we have tested it. We do test on Linux, Windows, and
-Mac with a range of compilers and libraries for a range of our
-configuration options. Every commit in our git source code repository
-is currently tested on x86 with a number of gcc versions ranging from 5.1
-through 9.1, version 19 of the Intel compiler, and Clang
-versions 3.6 through 8. For this, we use a variety of GNU/Linux
-flavors and versions as well as Windows (where we test only MSVC 2017).
+it works because we have tested it.
+Every commit in our git source code repository
+is currently tested with a range of configuration options on x86 with
+gcc versions 7 and 8,
+clang versions 8 and 9,
+and
+a beta version of oneAPI containing Intel's compiler.
+For this testing, we use Ubuntu 18.04 or 20.04 operating system.
Other compiler, library, and OS versions are tested less frequently.
For details, you can
have a look at the `continuous integration server used by GROMACS`_,
-which runs Jenkins_.
+which uses GitLab runner on a local k8s x86 cluster with NVIDIA and
+AMD GPU support.
We test irregularly on ARM v8, Cray, Power8, Power9,
Google Native Client and other environments, and
#include "gromacs/random/threefry.h"
#include "gromacs/random/uniformintdistribution.h"
#include "gromacs/topology/topology.h"
+#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/fatalerror.h"
int nthreads;
gmx::DefaultRandomEngine* trng = nullptr;
#endif
- int64_t mc = 0, mc_max;
+ int64_t mc_max;
gmx::DefaultRandomEngine rng(seed);
/* allocate memory for pr */
snew(tgr[i], pr->grn);
trng[i].seed(rng());
}
-# pragma omp parallel shared(tgr, trng, mc) private(tid, i, j)
+# pragma omp parallel shared(tgr, trng) private(tid, i, j)
{
gmx::UniformIntDistribution<int> tdist(0, isize - 1);
tid = gmx_omp_get_thread_num();
/* now starting parallel threads */
+ INTEL_DIAGNOSTIC_IGNORE(593)
# pragma omp for
- for (mc = 0; mc < mc_max; mc++)
+ for (int64_t mc = 0; mc < mc_max; mc++)
{
try
{
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
}
}
+ INTEL_DIAGNOSTIC_RESET
/* collecting data from threads */
for (i = 0; i < pr->grn; i++)
{
delete[] trng;
#else
gmx::UniformIntDistribution<int> dist(0, isize - 1);
- for (mc = 0; mc < mc_max; mc++)
+ for (int64_t mc = 0; mc < mc_max; mc++)
{
i = dist(rng); // [0,isize-1]
j = dist(rng); // [0,isize-1]
* 2 seconds, or until all cores have come online. This can be used prior to
* hardware detection for platforms that take unused processors offline.
*
- * This routine will not throw exceptions.
+ * This routine will not throw exceptions. In principle it should be
+ * declared noexcept, but at least icc 19.1 and 21-beta08 with the
+ * libstdc++-7.5 has difficulty implementing a std::vector of
+ * std::thread started with this function when declared noexcept. It
+ * is not clear whether the problem is the compiler or the standard
+ * library. Fortunately, this function is not performance sensitive,
+ * and only runs on platforms other than x86 and POWER (ie ARM),
+ * so the possible overhead introduced by omitting noexcept is not
+ * important.
*/
-static void spinUpCore() noexcept
+static void spinUpCore()
{
#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF) && defined(_SC_NPROCESSORS_ONLN)
float dummy = 0.1;
int64_t step, step_rel;
double t, t0 = ir->init_t, lam0[efptNR];
gmx_bool bGStatEveryStep, bGStat, bCalcVir, bCalcEnerStep, bCalcEner;
- gmx_bool bNS, bNStList, bStopCM, bFirstStep, bInitStep, bLastStep = FALSE;
+ gmx_bool bNS = FALSE, bNStList, bStopCM, bFirstStep, bInitStep, bLastStep = FALSE;
gmx_bool bDoDHDL = FALSE, bDoFEP = FALSE, bDoExpanded = FALSE;
gmx_bool do_ene, do_log, do_verbose;
gmx_bool bMasterState;
bExchanged = FALSE;
bNeedRepartition = FALSE;
+ step = ir->init_step;
+ step_rel = 0;
+
auto stopHandler = stopHandlerBuilder->getStopHandlerMD(
compat::not_null<SimulationSignal*>(&signals[eglsSTOPCOND]), simulationsShareState,
MASTER(cr), ir->nstlist, mdrunOptions.reproducible, nstSignalComm,
const DDBalanceRegionHandler ddBalanceRegionHandler(cr);
- step = ir->init_step;
- step_rel = 0;
-
if (MASTER(cr) && isMultiSim(ms) && !useReplicaExchange)
{
logInitialMultisimStatus(ms, cr, mdlog, simulationsShareState, ir->nsteps, ir->init_step);
"MiMiC does not report kinetic energy, total energy, temperature, virial and "
"pressure.");
+ step = ir->init_step;
+ step_rel = 0;
+
auto stopHandler = stopHandlerBuilder->getStopHandlerMD(
compat::not_null<SimulationSignal*>(&signals[eglsSTOPCOND]), false, MASTER(cr),
ir->nstlist, mdrunOptions.reproducible, nstglobalcomm, mdrunOptions.maximumHoursToRun,
const DDBalanceRegionHandler ddBalanceRegionHandler(cr);
- step = ir->init_step;
- step_rel = 0;
-
/* and stop now if we should */
isLastStep = (isLastStep || (ir->nsteps >= 0 && step_rel > ir->nsteps));
while (!isLastStep)
calc_shifts(rerun_fr.box, fr->shift_vec);
}
+ step = ir->init_step;
+ step_rel = 0;
+
auto stopHandler = stopHandlerBuilder->getStopHandlerMD(
compat::not_null<SimulationSignal*>(&signals[eglsSTOPCOND]), false, MASTER(cr),
ir->nstlist, mdrunOptions.reproducible, nstglobalcomm, mdrunOptions.maximumHoursToRun,
const DDBalanceRegionHandler ddBalanceRegionHandler(cr);
- step = ir->init_step;
- step_rel = 0;
-
/* and stop now if we should */
isLastStep = (isLastStep || (ir->nsteps >= 0 && step_rel > ir->nsteps));
while (!isLastStep)
gmx_target_warning_suppression(scanner -Wno-unused-parameter HAS_NO_UNUSED_PARAMETER)
gmx_target_warning_suppression(scanner -Wno-missing-declarations HAS_NO_MISSING_DECLARATIONS)
gmx_target_warning_suppression(scanner -Wno-null-conversion HAS_NO_NULL_CONVERSIONS)
- gmx_target_warning_suppression(scanner -wd1419 HAS_DECL_IN_SOURCE)
endif()
list(APPEND libgromacs_object_library_dependencies scanner)
set(libgromacs_object_library_dependencies ${libgromacs_object_library_dependencies} PARENT_SCOPE)
# define MSVC_DIAGNOSTIC_RESET
#endif
+#ifdef __INTEL_COMPILER
+// Ignore unused loop variable warning - it was used until the compiler removes the use!
+# define DO_PRAGMA(x) _Pragma(# x)
+# define INTEL_DIAGNOSTIC_IGNORE(id) DO_PRAGMA(warning push) DO_PRAGMA(warning(disable : id ))
+# define INTEL_DIAGNOSTIC_RESET DO_PRAGMA(warning pop)
+#else
+# define INTEL_DIAGNOSTIC_IGNORE(id)
+# define INTEL_DIAGNOSTIC_RESET
+#endif
+
namespace gmx
{
namespace internal