diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..dc471a6 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,214 @@ +name: Maxent CI + +on: + push: + branches: + - master + - modernize/step2 + pull_request: + branches: + - master + - modernize/step2 + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +env: + BOOST_VERSION: "1.91.0" + BOOST_VERSION_U: "1_91_0" + +jobs: + linux-build: + name: >- + Maxent / ${{ matrix.plat.os }} / ${{ matrix.plat.c_compiler }}-${{ matrix.plat.c_version }} / + ${{ matrix.plat.variant }} + runs-on: ${{ matrix.plat.os }} + timeout-minutes: 90 + strategy: + fail-fast: false + matrix: + plat: + # Match the compiler installation conventions used by ALPS 3.0 CI. + - { os: ubuntu-22.04, comp_pack: "gcc-11 g++-11", c_compiler: gcc, cxx_compiler: g++, c_version: 11, variant: strict } + - { os: ubuntu-24.04, comp_pack: "gcc-13 g++-13", c_compiler: gcc, cxx_compiler: g++, c_version: 13, variant: strict } + - { os: ubuntu-24.04, comp_pack: "gcc-15 g++-15", c_compiler: gcc, cxx_compiler: g++, c_version: 15, variant: strict } + - { os: ubuntu-22.04, comp_pack: "clang-15", c_compiler: clang, cxx_compiler: clang++, c_version: 15, variant: strict } + - { os: ubuntu-24.04, comp_pack: "clang-19", c_compiler: clang, cxx_compiler: clang++, c_version: 19, variant: strict } + - { os: ubuntu-24.04, comp_pack: "gcc-13 g++-13", c_compiler: gcc, cxx_compiler: g++, c_version: 13, variant: lapack, lapack: true } + - { os: ubuntu-24.04, comp_pack: "clang-19", c_compiler: clang, cxx_compiler: clang++, c_version: 19, variant: asan-ubsan, sanitizers: true } + - { os: ubuntu-24.04, comp_pack: "gcc-13 g++-13", c_compiler: gcc, cxx_compiler: g++, c_version: 13, variant: alps-flags, alps_flags: true } + + steps: + - uses: actions/checkout@v7 + - name: Check out ALPSCore + uses: actions/checkout@v7 + with: + repository: ALPSCore/ALPSCore + path: alpscore + - name: Set up Python + uses: actions/setup-python@v7 + with: + python-version: "3.14" + - name: Install dependencies + timeout-minutes: 20 + run: | + printf 'Acquire::Retries "3";\nAcquire::http::Timeout "30";\nAcquire::https::Timeout "30";\n' \ + | sudo tee /etc/apt/apt.conf.d/99ci-timeouts > /dev/null + sudo apt-get update + sudo apt-get install -y liblapack-dev libblas-dev libopenmpi-dev libhdf5-serial-dev libeigen3-dev + if [[ "${{ matrix.plat.c_compiler }}" == "clang" && "${{ matrix.plat.c_version }}" -ge 19 ]]; then + wget -nv --tries=3 --timeout=60 -O /tmp/llvm.sh https://apt.llvm.org/llvm.sh + sudo bash /tmp/llvm.sh "${{ matrix.plat.c_version }}" all + else + if [[ "${{ matrix.plat.c_compiler }}" == "gcc" && "${{ matrix.plat.c_version }}" -ge 15 ]]; then + sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + sudo apt-get update + fi + sudo apt-get install -y ${{ matrix.plat.comp_pack }} + fi + python -m pip install --upgrade pip + python -m pip install "numpy>=1.26" "h5py>=3.10" + - name: Determine dependency cache identity + id: dependency-cache + run: | + { + "${{ matrix.plat.cxx_compiler }}-${{ matrix.plat.c_version }}" --version + dpkg-query -W -f='${Package}=${Version}\n' \ + libhdf5-serial-dev libeigen3-dev libopenmpi-dev + } > "${RUNNER_TEMP}/dependency-versions.txt" + dependency_key=$(sha256sum "${RUNNER_TEMP}/dependency-versions.txt" | cut -d ' ' -f 1) + echo "key=${dependency_key}" >> "${GITHUB_OUTPUT}" + - name: Cache Boost and ALPSCore + id: cache-dependencies + uses: actions/cache@v6 + with: + path: | + ${{ runner.temp }}/boost + ${{ runner.temp }}/alpscore-install + key: maxent-deps-${{ runner.os }}-${{ runner.arch }}-${{ steps.dependency-cache.outputs.key }}-boost-${{ env.BOOST_VERSION }}-${{ hashFiles('alpscore/**') }} + - name: Build Boost and ALPSCore + if: steps.cache-dependencies.outputs.cache-hit != 'true' + env: + CC: ${{ matrix.plat.c_compiler }}-${{ matrix.plat.c_version }} + CXX: ${{ matrix.plat.cxx_compiler }}-${{ matrix.plat.c_version }} + run: | + wget -nv --tries=3 --timeout=60 --waitretry=10 \ + "https://archives.boost.io/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION_U}.tar.gz" + tar -xzf "boost_${BOOST_VERSION_U}.tar.gz" + cd "boost_${BOOST_VERSION_U}" + ./bootstrap.sh --prefix="${RUNNER_TEMP}/boost" --with-libraries=program_options + ./b2 -j 2 install + cd .. + cmake -S alpscore -B alpscore-build \ + -DTesting=OFF \ + -DALPS_CXX_STD=c++17 \ + -DBoost_ROOT="${RUNNER_TEMP}/boost" \ + -DCMAKE_PREFIX_PATH="${RUNNER_TEMP}/boost" \ + -DCMAKE_INSTALL_PREFIX="${RUNNER_TEMP}/alpscore-install" + cmake --build alpscore-build -j 2 + cmake --install alpscore-build + - name: Configure Maxent + env: + CC: ${{ matrix.plat.c_compiler }}-${{ matrix.plat.c_version }} + CXX: ${{ matrix.plat.cxx_compiler }}-${{ matrix.plat.c_version }} + run: | + extra_flags="" + if [[ "${{ matrix.plat.sanitizers || false }}" == "true" ]]; then + extra_flags="-fsanitize=address,undefined -fno-omit-frame-pointer" + elif [[ "${{ matrix.plat.alps_flags || false }}" == "true" ]]; then + extra_flags="-fpermissive -DBOOST_NO_AUTO_PTR -DBOOST_FILESYSTEM_NO_CXX20_ATOMIC_REF -DBOOST_TIMER_ENABLE_DEPRECATED" + fi + cmake -S . -B build/ci \ + -DCMAKE_BUILD_TYPE=${{ matrix.plat.sanitizers && 'Debug' || 'Release' }} \ + -DCMAKE_PREFIX_PATH="${RUNNER_TEMP}/alpscore-install;${RUNNER_TEMP}/boost" \ + -DALPSCore_DIR="${RUNNER_TEMP}/alpscore-install/share/ALPSCore" \ + -DBoost_ROOT="${RUNNER_TEMP}/boost" \ + -DMAXENT_USE_LAPACK=${{ matrix.plat.lapack && 'ON' || 'OFF' }} \ + -DMAXENT_WERROR=ON \ + -DCMAKE_CXX_FLAGS="${extra_flags}" \ + -DCMAKE_EXE_LINKER_FLAGS="${extra_flags}" + - name: Build Maxent + run: cmake --build build/ci -j 2 + - name: Test Maxent + env: + ASAN_OPTIONS: detect_leaks=1 + UBSAN_OPTIONS: print_stacktrace=1 + run: ctest --test-dir build/ci --output-on-failure + - name: Upload test logs on failure + if: failure() + uses: actions/upload-artifact@v7 + with: + name: test-logs-${{ matrix.plat.c_compiler }}-${{ matrix.plat.c_version }}-${{ matrix.plat.variant }} + path: build/ci/Testing/Temporary/** + + macos-build: + name: Maxent / macos-15 / AppleClang / strict + runs-on: macos-15 + timeout-minutes: 90 + steps: + - uses: actions/checkout@v7 + - name: Check out ALPSCore + uses: actions/checkout@v7 + with: + repository: ALPSCore/ALPSCore + path: alpscore + - name: Set up Python + uses: actions/setup-python@v7 + with: + python-version: "3.14" + - name: Install dependencies + timeout-minutes: 30 + run: | + brew install boost eigen hdf5 open-mpi + python -m pip install --upgrade pip + python -m pip install "numpy>=1.26" "h5py>=3.10" + - name: Determine dependency cache identity + id: dependency-cache + run: | + { + /usr/bin/clang --version + brew list --versions boost eigen hdf5 open-mpi + } > "${RUNNER_TEMP}/dependency-versions.txt" + dependency_key=$(shasum -a 256 "${RUNNER_TEMP}/dependency-versions.txt" | cut -d ' ' -f 1) + echo "key=${dependency_key}" >> "${GITHUB_OUTPUT}" + - name: Cache ALPSCore + id: cache-alpscore + uses: actions/cache@v6 + with: + path: ${{ runner.temp }}/alpscore-install + key: maxent-alpscore-${{ runner.os }}-${{ runner.arch }}-${{ steps.dependency-cache.outputs.key }}-${{ hashFiles('alpscore/**') }} + - name: Build ALPSCore + if: steps.cache-alpscore.outputs.cache-hit != 'true' + env: + CC: /usr/bin/clang + CXX: /usr/bin/clang++ + run: | + cmake -S alpscore -B alpscore-build \ + -DTesting=OFF \ + -DALPS_CXX_STD=c++17 \ + -DCMAKE_PREFIX_PATH="$(brew --prefix)" \ + -DEIGEN3_INCLUDE_DIR="$(brew --prefix eigen)/include/eigen3" \ + -DCMAKE_INSTALL_PREFIX="${RUNNER_TEMP}/alpscore-install" + cmake --build alpscore-build -j "$(sysctl -n hw.ncpu)" + cmake --install alpscore-build + - name: Configure Maxent + env: + CC: /usr/bin/clang + CXX: /usr/bin/clang++ + run: | + cmake -S . -B build/ci \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_PREFIX_PATH="${RUNNER_TEMP}/alpscore-install;$(brew --prefix)" \ + -DALPSCore_DIR="${RUNNER_TEMP}/alpscore-install/share/ALPSCore" \ + -DMAXENT_WERROR=ON + - name: Build Maxent + run: cmake --build build/ci -j "$(sysctl -n hw.ncpu)" + - name: Test Maxent + run: ctest --test-dir build/ci --output-on-failure + - name: Upload test logs on failure + if: failure() + uses: actions/upload-artifact@v7 + with: + name: test-logs-macos-15-appleclang + path: build/ci/Testing/Temporary/** diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index bbd29c6..0000000 --- a/.travis.yml +++ /dev/null @@ -1,75 +0,0 @@ -#based on ALPSCore/CT-HYB .travis.yml -language: cpp -sudo: required -dist: trusty - -compiler: - - gcc - - clang - -branches: - only: - - master - - GPLv3 - #- travis # To debug .travis.yml - -addons: - apt: - sources: - # Boost 1.58 - - sourceline: ppa:kzemek/boost - packages: - - libboost1.58-dev - - libboost-program-options1.58-dev - - libboost-program-options1.58.0 - - openmpi-bin - - openmpi-common - - openmpi-doc - - libopenmpi-dev - - libhdf5-serial-dev - - gsl-bin - - libgsl0-dev - -install: true - -before_script: - - export OMPI_CC=${CC} - - export OMPI_CXX=${CXX} - - export LD_LIBRARY_PATH=/usr/local/lib/:${LD_LIBRARY_PATH} - -script: - # Stop on first error - - set -e - - # Create directory for installed prerequisites - - export PREREQS_DIR=$(readlink -f $TRAVIS_BUILD_DIR/../installed) - - mkdir $PREREQS_DIR - - # Install ALPSCore wo tests - - cd $TRAVIS_BUILD_DIR/.. - - git clone https://github.com/ALPSCore/ALPSCore.git ALPSCore.git - - mkdir ALPSCore.build && pushd ALPSCore.build - - | - cmake ../ALPSCore.git \ - -DCMAKE_C_COMPILER=mpicc \ - -DCMAKE_CXX_COMPILER=mpic++ \ - -DCMAKE_INSTALL_PREFIX=$PREREQS_DIR/ALPSCore \ - -DALPS_INSTALL_EIGEN=true \ - -DTesting=false \ - -DENABLE_MPI=ON - - make -j3 - - make install - - export ALPSCore_DIR=$PREREQS_DIR/ALPSCore - - # Build and test Maxent - - cd $TRAVIS_BUILD_DIR/.. - - mkdir build - - cd build - - | - cmake ../Maxent \ - -DCMAKE_BUILD_TYPE=Debug \ - -DCMAKE_C_COMPILER=mpicc \ - -DCMAKE_CXX_COMPILER=mpic++ \ - -DCMAKE_INSTALL_PREFIX=$TRAVIS_BUILD_DIR/installed \ - - make -j3 - - make test diff --git a/ALPS3_MIGRATION_PLAN.md b/ALPS3_MIGRATION_PLAN.md index d36dd4d..29b1f2a 100644 --- a/ALPS3_MIGRATION_PLAN.md +++ b/ALPS3_MIGRATION_PLAN.md @@ -436,7 +436,8 @@ Keep the `MaxEntSimulation` public getters stable, because the tests use them. ### 2.4 Hygiene and CI -* Delete `.travis.yml` and add GitHub Actions with this matrix: +* **In progress 2026-09-24:** delete `.travis.yml` and add GitHub Actions, + mirroring ALPS 3.0's workflow conventions, with this matrix: * Ubuntu: GCC 11/13/15, Clang 15/19 * macOS arm64: AppleClang * one ASan/UBSan job @@ -445,7 +446,8 @@ Keep the `MaxEntSimulation` public getters stable, because the tests use them. Build ALPSCore from source in CI and cache it. * **Replace the allowlist `.gitignore`.** Done 2026-09-23: replaced with a minimal ignore list (build dirs, OS/editor files, Python caches). Local-only material (D10) is hidden per clone via `.git/info/exclude`, not in the repository. * ~~Remove the dead Pade sources~~ Done: Pade was removed entirely (D7). -* Update the README: build instructions, dependency list (no GSL), and remove the Travis badge. +* **Done 2026-09-24:** update the README build/test instructions and dependency + list, and replace the Travis badge with the GitHub Actions badge. ### 2.5 Isolate ALPSCore behind two seams (bridge into step 4) diff --git a/CMakeLists.txt b/CMakeLists.txt index 38ba864..81acdb0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,10 @@ if(NOT Boost_FOUND) message(FATAL_ERROR "Boost ${ALPSCore_BOOST_VERSION} (the version ALPSCore was built with) was not " "found. Pass -DBoost_DIR=