diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 0000000000000000000000000000000000000000..448277025707d290ca92a8b83e17707cc2f73b78 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,3 @@ +-# Remove the `/arbor-source` prefix such that codecov.io can map the files +-fixes: +- - "/arbor-source/::" \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6e6c5b9659a82c7a2f53a70cb884c9f28d65c30e..554ac2ea41ba6b424f31d49c09a1991f77f61444 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,29 +5,39 @@ stages: - build - allocate - test + - upload_reports - cleanup # Builds a docker image on kubernetes -build: +.build_docker_images: extends: .dind stage: build only: ['master', 'staging', 'trying'] variables: GIT_SUBMODULE_STRATEGY: recursive - BUILD_DOCKERFILE: docker/build-env/Dockerfile - BUILD_IMAGE: $CI_REGISTRY_IMAGE/build-env:latest - DEPLOY_DOCKERFILE: docker/deploy/Dockerfile - DEPLOY_IMAGE: $CI_REGISTRY_IMAGE/deploy:$CI_COMMIT_SHA - before_script: - - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: + - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker build -f $BUILD_DOCKERFILE --network=host --cache-from $BUILD_IMAGE --build-arg BUILDKIT_INLINE_CACHE=1 -t $BUILD_IMAGE . - docker push $BUILD_IMAGE - docker build -f $DEPLOY_DOCKERFILE --network=host --build-arg BUILD_ENV=$BUILD_IMAGE -t $DEPLOY_IMAGE . - docker push $DEPLOY_IMAGE -# Executes the docker image on Daint via Sarus -image: $CI_REGISTRY_IMAGE/deploy:$CI_COMMIT_SHA +build release: + extends: .build_docker_images + variables: + BUILD_DOCKERFILE: ci/release/build.Dockerfile + BUILD_IMAGE: $CI_REGISTRY_IMAGE/release/build:latest + DEPLOY_DOCKERFILE: ci/release/deploy.Dockerfile + DEPLOY_IMAGE: $CI_REGISTRY_IMAGE/release/deploy:$CI_COMMIT_SHA + +build codecov: + extends: .build_docker_images + variables: + BUILD_DOCKERFILE: ci/codecov/build.Dockerfile + BUILD_IMAGE: $CI_REGISTRY_IMAGE/codecov/build:latest + DEPLOY_DOCKERFILE: ci/codecov/deploy.Dockerfile + DEPLOY_IMAGE: $CI_REGISTRY_IMAGE/codecov/deploy:$CI_COMMIT_SHA + # Some variables used for running on daint variables: @@ -35,43 +45,121 @@ variables: USE_MPI: 'YES' DISABLE_AFTER_SCRIPT: 'YES' PULL_IMAGE: 'NO' - ALLOCATION_NAME: arbor-ci-$CI_PIPELINE_ID SLURM_CONSTRAINT: gpu SLURM_JOB_NUM_NODES: 2 SLURM_PARTITION: normal + SLURM_TIMELIMIT: '15:00' + +### Release tests ### +allocate release: + stage: allocate + image: $CI_REGISTRY_IMAGE/release/deploy:$CI_COMMIT_SHA + only: ['master', 'staging', 'trying'] + extends: .daint_alloc + variables: + PULL_IMAGE: 'YES' + ALLOCATION_NAME: arbor-ci-release-$CI_PIPELINE_ID + +single node release: + extends: .daint + image: $CI_REGISTRY_IMAGE/release/deploy:$CI_COMMIT_SHA + only: ['master', 'staging', 'trying'] + stage: test + resource_group: daint-job + script: + - unit + - unit-local + - unit-modcc + variables: + SLURM_JOB_NUM_NODES: 1 + SLURM_NTASKS: 1 + ALLOCATION_NAME: arbor-ci-release-$CI_PIPELINE_ID + +multi node release: + extends: .daint + image: $CI_REGISTRY_IMAGE/release/deploy:$CI_COMMIT_SHA + only: ['master', 'staging', 'trying'] + stage: test + resource_group: daint-job + script: + - unit-mpi + variables: + SLURM_JOB_NUM_NODES: 2 + SLURM_NTASKS: 2 + ALLOCATION_NAME: arbor-ci-release-$CI_PIPELINE_ID -allocate: +deallocate release: + only: ['master', 'staging', 'trying'] + image: $CI_REGISTRY_IMAGE/release/deploy:$CI_COMMIT_SHA + stage: cleanup + extends: .daint_dealloc + variables: + ALLOCATION_NAME: arbor-ci-release-$CI_PIPELINE_ID + +### Codecov tests ### +allocate codecov: stage: allocate only: ['master', 'staging', 'trying'] + image: $CI_REGISTRY_IMAGE/codecov/deploy:$CI_COMMIT_SHA extends: .daint_alloc variables: PULL_IMAGE: 'YES' + ALLOCATION_NAME: arbor-ci-codecov-$CI_PIPELINE_ID -single node: +single node codecov: extends: .daint only: ['master', 'staging', 'trying'] + image: $CI_REGISTRY_IMAGE/codecov/deploy:$CI_COMMIT_SHA stage: test resource_group: daint-job script: + - codecov_pre - unit - unit-local - unit-modcc + - codecov_post variables: SLURM_JOB_NUM_NODES: 1 SLURM_NTASKS: 1 + ALLOCATION_NAME: arbor-ci-codecov-$CI_PIPELINE_ID + artifacts: + paths: + - codecov-reports/ -multi node: +multi node codecov: extends: .daint only: ['master', 'staging', 'trying'] + image: $CI_REGISTRY_IMAGE/codecov/deploy:$CI_COMMIT_SHA stage: test resource_group: daint-job script: + - codecov_pre - unit-mpi + - codecov_post variables: SLURM_JOB_NUM_NODES: 2 SLURM_NTASKS: 2 + ALLOCATION_NAME: arbor-ci-codecov-$CI_PIPELINE_ID + artifacts: + paths: + - codecov-reports/ -deallocate: +upload codecov reports: + extends: .daint only: ['master', 'staging', 'trying'] + image: $CI_REGISTRY_IMAGE/codecov/deploy:$CI_COMMIT_SHA + stage: upload_reports + variables: + SLURM_JOB_NUM_NODES: 1 + SLURM_NTASKS: 1 + ALLOCATION_NAME: arbor-ci-codecov-$CI_PIPELINE_ID + script: upload_codecov + resource_group: daint-job + +deallocate codecov: + only: ['master', 'staging', 'trying'] + image: $CI_REGISTRY_IMAGE/codecov/deploy:$CI_COMMIT_SHA stage: cleanup - extends: .daint_dealloc \ No newline at end of file + extends: .daint_dealloc + variables: + ALLOCATION_NAME: arbor-ci-codecov-$CI_PIPELINE_ID \ No newline at end of file diff --git a/README.md b/README.md index 71eea5c42ebfe510afa6a3f3cf69548255677bff..59fd442a878e26264a05f941a3a874de78e21f21 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[](https://gitlab.com/cscs-ci/arbor-sim/arbor/-/commits/master) [](https://travis-ci.org/arbor-sim/arbor) [](https://gitpod.io/#https://github.com/arbor-sim/arbor) +[](https://gitlab.com/cscs-ci/arbor-sim/arbor/-/commits/master) [](https://travis-ci.org/arbor-sim/arbor) [](https://codecov.io/gl/cscs-ci:arbor-sim/arbor) [](https://gitpod.io/#https://github.com/arbor-sim/arbor) # Arbor Library diff --git a/ci/codecov/build.Dockerfile b/ci/codecov/build.Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..1cb095e3e1c544bfc44c04ac0f8e6ef8582397da --- /dev/null +++ b/ci/codecov/build.Dockerfile @@ -0,0 +1,33 @@ +FROM nvidia/cuda:10.1-devel-ubuntu18.04 + +WORKDIR /root + +ARG MPICH_VERSION=3.3.2 + +ENV DEBIAN_FRONTEND noninteractive +ENV FORCE_UNSAFE_CONFIGURE 1 +ENV MPICH_VERSION ${MPICH_VERSION} + +# Install basic tools +RUN apt-get update -qq && apt-get install -qq -y --no-install-recommends \ + build-essential lcov \ + python \ + git tar wget curl && \ + rm -rf /var/lib/apt/lists/* + +# Install cmake +RUN wget -qO- "https://cmake.org/files/v3.17/cmake-3.17.0-Linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C /usr/local + +# Install MPICH ABI compatible with Cray's lib on Piz Daint +RUN wget -q https://www.mpich.org/static/downloads/${MPICH_VERSION}/mpich-${MPICH_VERSION}.tar.gz && \ + tar -xzf mpich-${MPICH_VERSION}.tar.gz && \ + cd mpich-${MPICH_VERSION} && \ + ./configure --disable-fortran && \ + make install -j$(nproc) && \ + rm -rf mpich-${MPICH_VERSION}.tar.gz mpich-${MPICH_VERSION} + +# Install bundle tooling for creating small Docker images +RUN wget -q https://github.com/haampie/libtree/releases/download/v1.1.3/libtree_x86_64.tar.gz && \ + tar -xzf libtree_x86_64.tar.gz && \ + rm libtree_x86_64.tar.gz && \ + ln -s /root/libtree/libtree /usr/local/bin/libtree \ No newline at end of file diff --git a/ci/codecov/deploy.Dockerfile b/ci/codecov/deploy.Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..e2ba4d7bffc081199e25e64a41b51a7691a4e2d1 --- /dev/null +++ b/ci/codecov/deploy.Dockerfile @@ -0,0 +1,91 @@ +# Multistage build: here we import the current source code +# into build environment image, build the project, bundle it +# and then extract it into a small image that just contains +# the binaries we need to run + +ARG BUILD_ENV + +ARG SOURCE_DIR=/arbor-source +ARG BUILD_DIR=/arbor-build +ARG BUNDLE_DIR=/root/arbor.bundle + +FROM $BUILD_ENV as builder + +ARG SOURCE_DIR +ARG BUILD_DIR +ARG BUNDLE_DIR + +# Build arbor +COPY . ${SOURCE_DIR} + +# Build and bundle binaries +RUN mkdir ${BUILD_DIR} && cd ${BUILD_DIR} && \ + CC=mpicc CXX=mpicxx cmake ${SOURCE_DIR} \ + -DARB_VECTORIZE=ON \ + -DARB_ARCH=broadwell \ + -DARB_WITH_PYTHON=OFF \ + -DARB_WITH_MPI=ON \ + -DARB_GPU=cuda \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_CXX_FLAGS="-g -O0 -fprofile-arcs -ftest-coverage" \ + -DCMAKE_EXE_LINKER_FLAGS="-fprofile-arcs -ftest-coverage" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr && \ + make -j$(nproc) tests && \ + libtree --chrpath \ + -d ${BUNDLE_DIR} \ + ${BUILD_DIR}/bin/modcc \ + ${BUILD_DIR}/bin/unit \ + ${BUILD_DIR}/bin/unit-local \ + ${BUILD_DIR}/bin/unit-modcc \ + ${BUILD_DIR}/bin/unit-mpi + +# Install some code cov related executables +RUN libtree -d ${BUNDLE_DIR} $(which gcov) && \ + cp -L ${SOURCE_DIR}/ci/codecov_pre ${SOURCE_DIR}/ci/codecov_post ${SOURCE_DIR}/ci/upload_codecov ${BUNDLE_DIR}/usr/bin && \ + cp -L $(which lcov geninfo) ${BUNDLE_DIR}/usr/bin + +# In the build dir, remove everything except for gcno coverage files +RUN mv ${BUILD_DIR} ${BUILD_DIR}-tmp && \ + mkdir ${BUILD_DIR} && \ + cd ${BUILD_DIR}-tmp && \ + find -iname "*.gcno" -exec cp --parent \{\} ${BUILD_DIR} \; && \ + rm -rf ${BUILD_DIR}-tmp + +# Only keep the sources for tests, not the git history +RUN rm -rf ${SOURCE_DIR}/.git + +FROM ubuntu:18.04 + +ARG SOURCE_DIR +ARG BUILD_DIR +ARG BUNDLE_DIR + +ENV SOURCE_DIR=$SOURCE_DIR +ENV BUILD_DIR=$BUILD_DIR +ENV BUNDLE_DIR=$BUNDLE_DIR + +# This is the only thing necessary really from nvidia/cuda's ubuntu18.04 runtime image +ENV NVIDIA_VISIBLE_DEVICES all +ENV NVIDIA_DRIVER_CAPABILITIES compute,utility +ENV NVIDIA_REQUIRE_CUDA "cuda>=10.1 brand=tesla,driver>=384,driver<385 brand=tesla,driver>=396,driver<397 brand=tesla,driver>=410,driver<411" + +# Install perl to make lcov happy +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -qq perl curl ca-certificates && \ + rm -rf /var/lib/apt/lists/* + +COPY --from=builder ${BUNDLE_DIR} ${BUNDLE_DIR} +COPY --from=builder ${SOURCE_DIR} ${SOURCE_DIR} +COPY --from=builder ${BUILD_DIR} ${BUILD_DIR} + +# Make it easy to call our binaries. +ENV PATH="${BUNDLE_DIR}/usr/bin:$PATH" + +# Automatically print stacktraces on segfault +ENV LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so + +RUN echo "${BUNDLE_DIR}/usr/lib/" > /etc/ld.so.conf.d/arbor.conf && ldconfig + +WORKDIR ${BUNDLE_DIR}/usr/bin + diff --git a/ci/codecov_post b/ci/codecov_post new file mode 100755 index 0000000000000000000000000000000000000000..dafc9376d4577cae5c0b35cdbf82fe3eb9a333fe --- /dev/null +++ b/ci/codecov_post @@ -0,0 +1,22 @@ +#!/bin/bash + +# In case of MPI tests running on a shared file system, we run into race conditions writing files +# so here we generate some unique names for the codecov files. + +LOCAL_REPORTS="/codecov-reports" +SHARED_REPORTS="$CI_PROJECT_DIR/codecov-reports" +REPORT_NAME=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1` +mkdir -p "$SHARED_REPORTS" + +# Create coverage reports for code run +echo "Combining reports" +lcov --no-external --capture --base-directory $SOURCE_DIR --directory $BUILD_DIR --output-file "$LOCAL_REPORTS/run.info" &> /dev/null +lcov --add-tracefile "$LOCAL_REPORTS/baseline-codecov.info" --add-tracefile "$LOCAL_REPORTS/run.info" --output-file "$LOCAL_REPORTS/combined.info" &> /dev/null +lcov --remove "$LOCAL_REPORTS/combined.info" "$SOURCE_DIR/test/*" --output-file "$LOCAL_REPORTS/combined.info" &> /dev/null +lcov --remove "$LOCAL_REPORTS/combined.info" "$SOURCE_DIR/CMakeCXXCompilerId.cpp" --output-file "$LOCAL_REPORTS/combined.info" &> /dev/null +lcov --remove "$LOCAL_REPORTS/combined.info" "$SOURCE_DIR/ext/*" --output-file "$LOCAL_REPORTS/combined.info" &> /dev/null + +# Only keep our own source +lcov --extract "$LOCAL_REPORTS/combined.info" "$SOURCE_DIR/*" --output-file "$LOCAL_REPORTS/combined.info" &> /dev/null + +cp "$LOCAL_REPORTS/combined.info" "$SHARED_REPORTS/codecov-$REPORT_NAME.info" diff --git a/ci/codecov_pre b/ci/codecov_pre new file mode 100755 index 0000000000000000000000000000000000000000..f6584d4ef7f16e0fdee87200178fb7df2e672fbb --- /dev/null +++ b/ci/codecov_pre @@ -0,0 +1,10 @@ +#!/bin/bash + +# In case of MPI tests running on a shared file system, we run into race conditions writing files +# so here we generate some unique names for the codecov files. + +LOCAL_REPORTS="/codecov-reports" +mkdir -p "$LOCAL_REPORTS" + +echo "Generating baseline codecov report" +lcov --no-external --capture --initial --base-directory $SOURCE_DIR --directory $BUILD_DIR --output-file "$LOCAL_REPORTS/baseline-codecov.info" &> /dev/null diff --git a/docker/build-env/Dockerfile b/ci/release/build.Dockerfile similarity index 90% rename from docker/build-env/Dockerfile rename to ci/release/build.Dockerfile index 70b1ba5f772c704ce475760afe232bf500312401..67ba8be8aa21edc61f52bdbd9659f2675714be1e 100644 --- a/docker/build-env/Dockerfile +++ b/ci/release/build.Dockerfile @@ -2,7 +2,7 @@ FROM nvidia/cuda:10.1-devel-ubuntu18.04 WORKDIR /root -ARG MPICH_VERSION=3.1.4 +ARG MPICH_VERSION=3.3.2 ENV DEBIAN_FRONTEND noninteractive ENV FORCE_UNSAFE_CONFIGURE 1 @@ -29,5 +29,5 @@ RUN wget -q https://www.mpich.org/static/downloads/${MPICH_VERSION}/mpich-${MPIC # Install bundle tooling for creating small Docker images RUN wget -q https://github.com/haampie/libtree/releases/download/v1.1.3/libtree_x86_64.tar.gz && \ tar -xzf libtree_x86_64.tar.gz && \ - rm libtree_x86_64.tar.gz && \ - ln -s /root/libtree/libtree /usr/local/bin/libtree + rm libtree_x86_64.tar.gz && \ + ln -s /root/libtree/libtree /usr/local/bin/libtree \ No newline at end of file diff --git a/docker/deploy/Dockerfile b/ci/release/deploy.Dockerfile similarity index 93% rename from docker/deploy/Dockerfile rename to ci/release/deploy.Dockerfile index 443427df2bd93984fc9ec40d127c06f9487d65cb..69a65ff96e3b2107d27ca6c7f4f29339f7666505 100644 --- a/docker/deploy/Dockerfile +++ b/ci/release/deploy.Dockerfile @@ -16,7 +16,7 @@ ARG BUILD_DIR ARG BUNDLE_DIR # Build arbor -COPY . /arbor +COPY . $SOURCE_DIR # Build and bundle binaries RUN mkdir ${BUILD_DIR} && cd ${BUILD_DIR} && \ @@ -57,6 +57,9 @@ COPY --from=builder ${SOURCE_DIR} ${SOURCE_DIR} # Make it easy to call our binaries. ENV PATH="${BUNDLE_DIR}/usr/bin:$PATH" +# Automatically print stacktraces on segfault +ENV LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so + RUN echo "${BUNDLE_DIR}/usr/lib/" > /etc/ld.so.conf.d/arbor.conf && ldconfig WORKDIR ${BUNDLE_DIR}/usr/bin diff --git a/ci/upload_codecov b/ci/upload_codecov new file mode 100755 index 0000000000000000000000000000000000000000..080d06e2916cf13d0e370ac546f4c9debbf85101 --- /dev/null +++ b/ci/upload_codecov @@ -0,0 +1,11 @@ +#!/bin/bash + +# Combine all reports into a single one +SHARED_REPORTS="$CI_PROJECT_DIR/codecov-reports" +TRACE_FILES_ARGS=`find "$SHARED_REPORTS" -type f -iname '*.info' -exec sh -c "echo --add-tracefile {}" \;` +lcov ${TRACE_FILES_ARGS} --output-file "$SHARED_REPORTS/combined.info" + +pushd $SOURCE_DIR +bash <(curl -s https://codecov.io/bash) -f "$SHARED_REPORTS/combined.info" -t $CODECOV_TOKEN_GITHUB +bash <(curl -s https://codecov.io/bash) -f "$SHARED_REPORTS/combined.info" -t $CODECOV_TOKEN_GITLAB +popd \ No newline at end of file