diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 862011a..e8eab12 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,84 +1,173 @@ stages: - docker - - configure - build - test + - wheels + - deploy variables: IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG GIT_SUBMODULE_STRATEGY: recursive BUILD_DIR: build-release cache: key: "$CI_COMMIT_REF_SLUG" +# ------------------------------------------------------------------------------ -docker build:debian: +.docker_build: stage: docker image: docker:19.03.12 services: - docker:19.03.12-dind variables: # Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled DOCKER_HOST: tcp://docker:2376 DOCKER_TLS_CERTDIR: "/certs" script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - - docker build -t $IMAGE_TAG . - - docker push $IMAGE_TAG + - docker build -t $IMAGE_TAG-$IMAGE_NAME -f $DOCKERFILE . + - docker push $IMAGE_TAG-$IMAGE_NAME rules: - changes: - - Dockerfile + - $DOCKERFILE -.debian_stable: - image: $IMAGE_TAG +docker build:debian: + variables: + IMAGE_NAME: debian-stable + DOCKERFILE: tests/ci/docker/debian.mpi + extends: .docker_build -configure: - stage: configure - extends: .debian_stable +docker build:manylinux: + variables: + IMAGE_NAME: manylinux + DOCKERFILE: tests/ci/docker/manylinux before_script: - - rm -rf build-* - script: - - scons build_tests=True - use_googletest=True - build_python=True - py_exec=python3 - use_mpi=True - verbose=True -h - artifacts: - paths: - - build-setup.conf + - cp tests/ci/docker_build_all.sh . + extends: .docker_build + +docker build:cuda: + variables: + IMAGE_NAME: cuda + DOCKERFILE: tests/ci/docker/ubuntu_lts.cuda + extends: .docker_build + +# ------------------------------------------------------------------------------ + +.debian_stable: + image: $IMAGE_TAG-debian-stable -build: +.manylinux: + image: $IMAGE_TAG-manylinux + +.cuda: + image: $IMAGE_TAG-cuda + +# ------------------------------------------------------------------------------ + +.build: stage: build - needs: [configure] - extends: .debian_stable variables: COMPILE_LOG: compilation.log script: - scons 2>&1 | tee $COMPILE_LOG artifacts: paths: + - build-setup.conf - $COMPILE_LOG - $BUILD_DIR + - config.log -test: +build_mpi: + extends: + - .build + - .debian_stable + before_script: + - scons build_tests=True + use_googletest=True + build_python=True + py_exec=python3 + use_mpi=True + backend=omp + fftw_threads=omp + verbose=True -h + +build_cuda: + extends: + - .build + - .cuda + before_script: + - scons build_tests=True + use_googletest=True + build_python=True + py_exec=python3 + use_mpi=False + backend=cuda + fftw_threads=none + verbose=True -h + +# ------------------------------------------------------------------------------ + +test_mpi: stage: test - needs: [build] + dependencies: + - build_mpi extends: .debian_stable variables: PYTHONPATH: $CI_PROJECT_DIR/$BUILD_DIR/python TESTS: $BUILD_DIR/tests JUNITXML: results.xml TESTS_LOG: tests.log script: - ls $PYTHONPATH - python3 -c 'import sys; print(sys.path)' - - python3 -m pytest -vvv --durations=0 --junitxml=$JUNITXML $TESTS 2>&1 | tee $TESTS_LOG + - python3 -m pytest -vvv --durations=0 --junitxml=$JUNITXML + $TESTS 2>&1 | tee $TESTS_LOG artifacts: paths: - $JUNITXML - $TESTS_LOG reports: junit: - $JUNITXML + +# ------------------------------------------------------------------------------ + +wheels: + stage: wheels + extends: .manylinux + script: + - git fetch --tags + - git describe --tags --dirty --always + - ./tests/ci/docker_build_all.sh + artifacts: + paths: + - dist/wheelhouse + rules: + - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' + +# ------------------------------------------------------------------------------ + +gitlab_package: + stage: deploy + extends: .manylinux + dependencies: + - wheels + script: + - TWINE_PASSWORD=${CI_JOB_TOKEN} TWINE_USERNAME=gitlab-ci-token + python -m twine upload + --verbose --repository-url + ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi dist/wheelhouse/* + rules: + - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' + +pypi_package: + stage: deploy + extends: .manylinux + dependencies: + - wheels + script: + - TWINE_PASSWORD=${PYPI_TOKEN} TWINE_USERNAME=__token__ + python -m twine upload dist/wheelhouse/* + rules: + - if: '$CI_COMMIT_TAG =~ /^v.*/' diff --git a/CHANGELOG.md b/CHANGELOG.md index e4e5964..ec6461b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,207 +1,221 @@ # Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) for final versions and [PEP440](https://www.python.org/dev/peps/pep-0440/) in case intermediate versions need to be released (e.g. development version `2.2.3.dev1` or release candidates `2.2.3rc1`), or individual commits are packaged. ## Unreleased +## v2.3.0 -- 2021-06-15 + ### Added - Added `read()` method to dumpers to create a model from a dump file - `getClusters()` can be called in MPI contact with partial contact maps - Added a JSON encoder class for models and a JSON dumper - CUDA compatibility is re-established, but has not been tested - Docstrings in the Python bindings for many classes/methods ### Changed - Tamaas version numbers are now managed by [versioneer](https://github.com/python-versioneer/python-versioneer). This means that Git tags prefixed with `v` (e.g. `v2.2.3`) carry meaning and determine the version. When no tag is set, versioneer uses the last tag, specifies the commit short hash and the distance to the last tag (e.g. `2.2.2+33.ge314b0e`). This version string is used in the compiled library, the `setup.py` script and the `__version__` variable in the python module. +- Tamaas migrated to [GitLab](https://gitlab.com/tamaas/tamaas) +- Continuous delivery has been implemented: + + - the `master` branch will now automatically build and publish Python wheels + to `https://gitlab.com/api/v4/projects/19913787/packages/pypi`. These + "nightly" builds can be installed with: + + pip install -i https://gitlab.com/api/v4/projects/19913787/packages/pypi tamaas + + - version tags pushed to `master` will automatically publish the wheels to + [PyPI](https://pypi.org/project/tamaas/) ### Deprecated - The `finalize()` function is now deprecated, since it is automatically called - when the process terminates. + when the process terminates +- Python versions 3.5 and below are not supported anymore ### Fixed - Fixed a host of dump read/write issues when model type was not `volume_*d`. Dumper tests are now streamlined and systematic. - Fixed a bug where `Model::solveDirichlet` would not compute correctly - Fixed a bug where `Statistics::contact` would not normalize by the global number of surface points ## v2.2.2 -- 2021-04-02 ### Added - Entry-point `tamaas` defines a grouped CLI for `examples/pipe_tools`. Try executing `tamaas surface -h` from the command-line! ### Changed - `CXXFLAGS` are now passed to the linker - Added this changelog - Using absolute paths for environmental variables when running `scons test` - Reorganized documentation layout - Gave the build system a facelift (docs are now generated directly with SCons instead of a Makefile) ### Deprecated - Python 2 support is discontinued. Version `v2.2.1` is the last PyPi build with a Python 2 wheel. - The scripts in `examples/pipe_tools` have been replaced by the `tamaas` command ### Fixed - `UVWDumper` no longer imports `mpi4py` in sequential - Compiling with different Thrust/FFTW backends ## v2.2.1 -- 2021-03-02 ### Added - Output registered fields and dumpers in `print(model)` - Added `operator[]` to the C++ model class (for fields) - Added `traction` and `displacement` properties to Python model bindings - Added `operators` property to Python model bindings, which provides a dict-like access to registered operators - Added `shape` and `spectrum` to properties to Python surface generator bindings - Surface generator constructor accepts surface global shape as argument - Choice of FFTW thread model ### Changed - Tests use `/tmp` for temporary files - Updated dependency versions (Thrust, Pybind11) ### Deprecated - Most `get___()` and `set___()` in Python bindings have been deprecated. They will generate a `DeprecationWarning`. ### Removed - All legacy code ## v2.2.0 -- 2020-12-31 ### Added - More accurate function for computation of contact area - Function to compute deviatoric of tensor fields - MPI implementation - Convenience `hdf5toVTK` function - Readonly properties `shape`, `global_shape`, `boundary_shape` on model to give shape information ### Changed - Preprocessor defined macros are prefixed with `TAMAAS_` - Moved `tamaas.to_voigt` to `tamaas.compute.to_voigt` ### Fixed - Warning about deprecated constructors with recent GCC versions - Wrong computation of grid strides - Wrong computation of grid sizes in views ## v2.1.4 -- 2020-08-07 ### Added - Possibility to generate a static `libTamaas` - C++ implementation of DFSANE solver - Allowing compilation without OpenMP ### Changed - NetCDF dumper writes frames to a single file ### Fixed - Compatibility with SCons+Python 3 ## v2.1.3 -- 2020-07-27 ### Added - Version number to `TamaasInfo` ### Changed - Prepending root directory when generating archive ## v2.1.2 -- 2020-07-24 This release changes some core internals related to discrete Fourier transforms for future MPI support. ### Added - Caching `CXXFLAGS` in SCons build - SCons shortcut to create code archive - Test of the elastic-plastic contact solver - Paraview data dumper (`.pvd` files) - Compression for UVW dumper - `__contains__` and `__iter__` Python bindings of model - Warning message of possible overflow in Kelvin ### Changed - Simplified `tamaas_info.cpp`, particularly the diff part - Using a new class `FFTEngine` to manage discrete Fourier transforms. Plans are re-used as much as possible with different data with the same shape. This is in view of future MPI developments - Redirecting I/O streams in solve functions so they can be used from Python (e.g. in Jupyter notebooks) - Calling `initialize()` and `finalize()` is no longer necessary ### Fixed - Convergence issue with non-linear solvers - Memory error in volume potentials ## v2.1.1 -- 2020-04-22 ### Added - SCons shortcut to run tests ### Fixed - Correct `RPATH` for shared libraries - Issues with SCons commands introduced in v2.1.0 - Tests with Python 2.7 ## v2.1.0 -- 2020-04-17 ### Added - SCons shortcuts to build/install Tamaas and its components - Selection of integration method for Kelvin operator - Compilation option to remove the legacy part of Tamaas - NetCDF dumper ### Fixed - Link bug with clang - NaNs in Kato saturated solver ## v2.0.0 -- 2019-11-11 First public release. Contains relatively mature elastic-plastic contact code. diff --git a/Dockerfile b/tests/ci/docker/debian.mpi similarity index 100% rename from Dockerfile rename to tests/ci/docker/debian.mpi diff --git a/tests/ci/docker/manylinux b/tests/ci/docker/manylinux new file mode 100644 index 0000000..379056f --- /dev/null +++ b/tests/ci/docker/manylinux @@ -0,0 +1,33 @@ +FROM quay.io/pypa/manylinux2010_x86_64 + +MAINTAINER Lucas Frérot + +ENV PATH=/opt/python/cp37-cp37m/bin:$PATH + +RUN yum install -y \ + boost \ + boost-devel +RUN pip install scons twine +RUN mkdir /app + +ENV THRUST_VERSION 1.12.0 +ENV FFTW_VERSION 3.3.8 + +# Setting up thrust +RUN cd /app && \ + curl -L https://github.com/NVIDIA/thrust/archive/refs/tags/$THRUST_VERSION.tar.gz | tar -xz && \ + cd /app/thrust-$THRUST_VERSION&& \ + mkdir include && \ + ln -s ../thrust include/thrust + +# Setting up fftw +RUN cd /app && \ + curl -L http://fftw.org/fftw-$FFTW_VERSION.tar.gz | tar -xz && \ + cd fftw-$FFTW_VERSION && \ + CFLAGS='-fPIC' ./configure --prefix=$PWD && \ + make && \ + make install + +# Setting up environment +ENV THRUST_ROOT=/app/thrust-$THRUST_VERSION +ENV FFTW_ROOT=/app/fftw-$FFTW_VERSION \ No newline at end of file diff --git a/Dockerfile.cuda b/tests/ci/docker/ubuntu_lts.cuda similarity index 93% rename from Dockerfile.cuda rename to tests/ci/docker/ubuntu_lts.cuda index ff5a857..f35db9e 100644 --- a/Dockerfile.cuda +++ b/tests/ci/docker/ubuntu_lts.cuda @@ -1,42 +1,42 @@ -FROM nvidia/cuda:11.3.0-devel-ubuntu18.04 +FROM nvidia/cuda:11.3.0-devel-ubuntu20.04 MAINTAINER Lucas Frérot # Setting up timezone ENV TZ=America/New_York RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN apt-get -qq update && apt-get install -y \ curl \ gcc \ git \ libboost-dev \ libpython3-dev \ libopenmpi-dev \ libfftw3-dev \ libfftw3-mpi-dev \ python3 \ python3-dev \ python3-numpy \ python3-pip \ python3-scipy \ python3-h5py \ python3-netcdf4 \ python3-phabricator \ python3-click \ python3-yaml \ python3-matplotlib \ python3-sphinx \ python3-breathe \ python3-sphinx-rtd-theme \ python3-mpi4py \ doxygen \ scons \ && rm -rf /var/lib/apt/lists/* RUN pip3 install pytest uvw ENV CUDA_ROOT=/usr/local/cuda ENV THRUST_ROOT=/usr/local/cuda ENV LC_ALL=C.UTF-8 ENV LANG=C.UTF-8 \ No newline at end of file diff --git a/tests/ci/docker_build_all.sh b/tests/ci/docker_build_all.sh new file mode 100755 index 0000000..f64c189 --- /dev/null +++ b/tests/ci/docker_build_all.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +set -uxo pipefail + +cd $CI_PROJECT_DIR + +mkdir -p dist/wheels +mkdir -p dist/wheelhouse + +# Checking all version of CPython +for PYROOT in /opt/python/cp*; do + MAJOR=$($PYROOT/bin/python --version 2>&1 | cut -d " " -f 2 | cut -d . -f 1) + MINOR=$($PYROOT/bin/python --version 2>&1 | cut -d " " -f 2 | cut -d . -f 2) + TAG=$(basename $PYROOT | cut -d "-" -f 1) + + # Skip Python 2 + [ $MAJOR -eq 2 ] && continue + # Skip Beta Python 3 versions + [ $MAJOR -eq 3 ] && [ $MINOR -ge 10 ] && continue + + # Compile + scons -j4 \ + py_exec="$PYROOT/bin/python$MAJOR" \ + backend=cpp \ + fftw_threads=none \ + build_static_lib=True \ + use_mpi=False \ + strip_info=True \ + verbose=True \ + THRUST_ROOT=$THRUST_ROOT \ + FFTW_ROOT=$FFTW_ROOT \ + CXX=$(which g++) \ + 2>&1 | tee compile.log + + if [ $? -ne 0 ]; then + cat config.log + fi + + # Link fftw statically + static_command=$(grep 'build-release/python/tamaas/_tamaas' compile.log \ + | sed -e 's/lfftw3/l:libfftw3.a/' \ + | tr -d '$()') + $static_command + + # Create wheel + pushd build-release/python + $PYROOT/bin/python setup.py bdist_wheel \ + --python-tag $TAG \ + --plat-name manylinux2010_x86_64 \ + -d ../../dist/wheels/ + + popd + + rm -rf build-release/python +done + +for wheel in dist/wheels/*.whl; do + auditwheel repair $wheel -w dist/wheelhouse +done