diff --git a/.github/workflows/Dockerfile.alpine b/.github/workflows/Dockerfile.alpine index 7773aaf8d2..7e2aeea51f 100644 --- a/.github/workflows/Dockerfile.alpine +++ b/.github/workflows/Dockerfile.alpine @@ -48,6 +48,7 @@ ARG packages="" RUN apk add --no-cache \ bash \ + ccache \ cmake \ make \ gcc \ @@ -70,12 +71,17 @@ RUN apk add --no-cache \ # Build Storm ############# +ENV CCACHE_DIR=/root/.ccache RUN mkdir /opt/storm WORKDIR /opt/storm # Copy the content of the current local Storm repository into the Docker image COPY . . +# Seed ccache from the workflow cache directory if available. +RUN mkdir -p "$CCACHE_DIR" && \ + if [ -d "/opt/storm/.ci-ccache" ]; then cp -a /opt/storm/.ci-ccache/. "$CCACHE_DIR"/; fi + # Switch to build directory RUN mkdir -p /opt/storm/build WORKDIR /opt/storm/build @@ -104,6 +110,6 @@ RUN cmake -DCMAKE_BUILD_TYPE=$build_type \ # Build Storm # (This can be adapted to only build 'storm' or 'binaries' depending on custom needs) -RUN make -j $no_threads +RUN ccache --max-size=3G && ccache --zero-stats && make -j $no_threads && ccache --show-stats --verbose WORKDIR /opt/storm diff --git a/.github/workflows/Dockerfile.archlinux b/.github/workflows/Dockerfile.archlinux index e1828f1761..e22f34cdae 100644 --- a/.github/workflows/Dockerfile.archlinux +++ b/.github/workflows/Dockerfile.archlinux @@ -52,6 +52,7 @@ ARG packages="" RUN pacman -Syu --noconfirm # Updates needed as Archlinux is rolling release RUN pacman -S --noconfirm \ base-devel \ + ccache \ cmake \ git \ boost \ @@ -68,12 +69,17 @@ RUN pacman -S --noconfirm \ # Build Storm ############# +ENV CCACHE_DIR=/root/.ccache RUN mkdir /opt/storm WORKDIR /opt/storm # Copy the content of the current local Storm repository into the Docker image COPY . . +# Seed ccache from the workflow cache directory if available. +RUN mkdir -p "$CCACHE_DIR" && \ + if [ -d "/opt/storm/.ci-ccache" ]; then cp -a /opt/storm/.ci-ccache/. "$CCACHE_DIR"/; fi + # Switch to build directory RUN mkdir -p /opt/storm/build WORKDIR /opt/storm/build @@ -102,6 +108,6 @@ RUN cmake -DCMAKE_BUILD_TYPE=$build_type \ # Build Storm # (This can be adapted to only build 'storm' or 'binaries' depending on custom needs) -RUN make -j $no_threads +RUN ccache --max-size=3G && ccache --zero-stats && make -j $no_threads && ccache --show-stats --verbose WORKDIR /opt/storm diff --git a/.github/workflows/Dockerfile.release b/.github/workflows/Dockerfile.release index 02379803ce..b78158b682 100644 --- a/.github/workflows/Dockerfile.release +++ b/.github/workflows/Dockerfile.release @@ -56,26 +56,26 @@ COPY . . RUN mkdir -p /opt/storm/build \ && cd /opt/storm/build \ && cmake -DCMAKE_BUILD_TYPE=$build_type \ - -DSTORM_PORTABLE=ON \ - -DSTORM_BUILD_TESTS=OFF \ - -DSTORM_CARL_GIT_REPO=$carl_repo \ - -DSTORM_CARL_GIT_TAG=$carl_tag \ - -DSTORM_DISABLE_CUDD=$disable_cudd \ - -DSTORM_DISABLE_GLPK=$disable_glpk \ - -DSTORM_DISABLE_GMM=$disable_gmm \ - -DSTORM_DISABLE_GUROBI=$disable_gurobi \ - -DSTORM_DISABLE_LIBARCHIVE=$disable_libarchive \ - -DSTORM_DISABLE_MATHSAT=$disable_mathsat \ - -DSTORM_DISABLE_SOPLEX=$disable_soplex \ - -DSTORM_DISABLE_SPOT=$disable_spot \ - -DSTORM_DISABLE_SYLVAN=$disable_sylvan \ - -DSTORM_DISABLE_XERCES=$disable_xerces \ - -DSTORM_DISABLE_Z3=$disable_z3 \ - -DSTORM_DEVELOPER=$developer \ - -DSTORM_USE_CLN_EA=$cln_exact \ - -DSTORM_USE_CLN_RF=$cln_ratfunc \ - -DSTORM_COMPILE_WITH_ALL_SANITIZERS=$all_sanitizers \ - $cmake_args .. \ + -DSTORM_PORTABLE=ON \ + -DSTORM_BUILD_TESTS=OFF \ + -DSTORM_CARL_GIT_REPO=$carl_repo \ + -DSTORM_CARL_GIT_TAG=$carl_tag \ + -DSTORM_DISABLE_CUDD=$disable_cudd \ + -DSTORM_DISABLE_GLPK=$disable_glpk \ + -DSTORM_DISABLE_GMM=$disable_gmm \ + -DSTORM_DISABLE_GUROBI=$disable_gurobi \ + -DSTORM_DISABLE_LIBARCHIVE=$disable_libarchive \ + -DSTORM_DISABLE_MATHSAT=$disable_mathsat \ + -DSTORM_DISABLE_SOPLEX=$disable_soplex \ + -DSTORM_DISABLE_SPOT=$disable_spot \ + -DSTORM_DISABLE_SYLVAN=$disable_sylvan \ + -DSTORM_DISABLE_XERCES=$disable_xerces \ + -DSTORM_DISABLE_Z3=$disable_z3 \ + -DSTORM_DEVELOPER=$developer \ + -DSTORM_USE_CLN_EA=$cln_exact \ + -DSTORM_USE_CLN_RF=$cln_ratfunc \ + -DSTORM_COMPILE_WITH_ALL_SANITIZERS=$all_sanitizers \ + $cmake_args .. \ && make -j $no_threads \ && make install -j $no_threads \ && cd /opt \ diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml deleted file mode 100644 index e89ea30dab..0000000000 --- a/.github/workflows/buildtest.yml +++ /dev/null @@ -1,494 +0,0 @@ -name: Build Test -# Builds and tests storm on various platforms -# also deploys images to DockerHub - -on: - schedule: - # run daily - - cron: '0 6 * * *' - # needed to trigger the workflow manually - workflow_dispatch: - pull_request: - -env: - # GitHub runners currently have 4 cores - NR_JOBS: "4" - -jobs: - # Perform in-depth tests with different configurations - indepthTests: - name: Indepth Tests (${{ matrix.config.name }}, ${{ matrix.config.buildType }}) - runs-on: ubuntu-latest - strategy: - matrix: - config: - - {name: "GMP exact; GMP rational functions; All dependencies", - baseImg: "storm-dependencies:latest", - buildType: "Debug", - disable_cudd: "OFF", - disable_glpk: "OFF", - disable_gmm: "OFF", - disable_gurobi: "OFF", - disable_libarchive: "OFF", - disable_mathsat: "OFF", - disable_soplex: "OFF", - disable_spot: "OFF", - disable_sylvan: "OFF", - disable_xerces: "OFF", - disable_z3: "OFF", - Developer: "ON", - ClnExact: "OFF", - ClnRatfunc: "OFF", - AllSanitizers: "OFF", - cmakeArgs: "-DSTORM_WARNING_AS_ERROR=ON" - } - - {name: "CLN exact; GMP rational functions; All dependencies", - baseImg: "storm-dependencies:latest", - buildType: "Debug", - disable_cudd: "OFF", - disable_glpk: "OFF", - disable_gmm: "OFF", - disable_gurobi: "OFF", - disable_libarchive: "OFF", - disable_mathsat: "OFF", - disable_soplex: "OFF", - disable_spot: "OFF", - disable_sylvan: "OFF", - disable_xerces: "OFF", - disable_z3: "OFF", - Developer: "ON", - ClnExact: "ON", - ClnRatfunc: "OFF", - AllSanitizers: "OFF", - cmakeArgs: "-DSTORM_WARNING_AS_ERROR=ON" - } - - {name: "CLN exact; CLN rational functions; All dependencies", - baseImg: "storm-dependencies:latest", - buildType: "Debug", - disable_cudd: "OFF", - disable_glpk: "OFF", - disable_gmm: "OFF", - disable_gurobi: "OFF", - disable_libarchive: "OFF", - disable_mathsat: "OFF", - disable_soplex: "OFF", - disable_spot: "OFF", - disable_sylvan: "OFF", - disable_xerces: "OFF", - disable_z3: "OFF", - Developer: "ON", - ClnExact: "ON", - ClnRatfunc: "ON", - AllSanitizers: "OFF", - cmakeArgs: "-DSTORM_WARNING_AS_ERROR=ON" - } - - {name: "GMP exact; CLN rational functions; No dependencies", - baseImg: "storm-dependencies:latest", - buildType: "Debug", - disable_cudd: "ON", - disable_glpk: "ON", - disable_gmm: "ON", - disable_gurobi: "ON", - disable_libarchive: "ON", - disable_mathsat: "ON", - disable_soplex: "ON", - disable_spot: "ON", - disable_sylvan: "ON", - disable_xerces: "ON", - disable_z3: "ON", - Developer: "ON", - ClnExact: "OFF", - ClnRatfunc: "ON", - AllSanitizers: "OFF", - cmakeArgs: "-DSTORM_WARNING_AS_ERROR=ON" - } - - {name: "Minimal dependencies (without CLN)", - baseImg: "storm-basesystem:minimal_dependencies", - buildType: "Debug", - disable_cudd: "ON", - disable_glpk: "ON", - disable_gmm: "ON", - disable_gurobi: "ON", - disable_libarchive: "ON", - disable_mathsat: "ON", - disable_soplex: "ON", - disable_spot: "ON", - disable_sylvan: "ON", - disable_xerces: "ON", - disable_z3: "ON", - Developer: "ON", - ClnExact: "OFF", - ClnRatfunc: "OFF", - AllSanitizers: "OFF", - cmakeArgs: "-DSTORM_WARNING_AS_ERROR=ON" - } - steps: - - name: Git clone - uses: actions/checkout@v7 - - name: Build storm from Dockerfile - run: | - docker build -t movesrwth/storm:ci . \ - --build-arg BASE_IMAGE=movesrwth/${{ matrix.config.baseImg }} \ - --build-arg build_type="${{ matrix.config.buildType }}" \ - --build-arg carl_tag="master" \ - --build-arg disable_cudd="${{ matrix.config.disable_cudd }}" \ - --build-arg disable_glpk="${{ matrix.config.disable_glpk }}" \ - --build-arg disable_gmm="${{ matrix.config.disable_gmm }}" \ - --build-arg disable_gurobi="${{ matrix.config.disable_gurobi }}" \ - --build-arg disable_libarchive="${{ matrix.config.disable_libarchive }}" \ - --build-arg disable_mathsat="${{ matrix.config.disable_mathsat }}" \ - --build-arg disable_soplex="${{ matrix.config.disable_soplex }}" \ - --build-arg disable_spot="${{ matrix.config.disable_spot }}" \ - --build-arg disable_sylvan="${{ matrix.config.disable_sylvan }}" \ - --build-arg disable_xerces="${{ matrix.config.disable_xerces }}" \ - --build-arg disable_z3="${{ matrix.config.disable_z3 }}" \ - --build-arg developer="${{ matrix.config.Developer }}" \ - --build-arg cln_exact="${{ matrix.config.ClnExact }}" \ - --build-arg cln_ratfunc="${{ matrix.config.ClnRatfunc }}" \ - --build-arg all_sanitizers="${{ matrix.config.AllSanitizers }}" \ - --build-arg cmake_args="${{ matrix.config.cmakeArgs }}" \ - --build-arg no_threads=${NR_JOBS} - - name: Run Docker - run: docker run -d -it --name ci movesrwth/storm:ci - - name: Run storm - run: docker exec ci bash -c "/opt/storm/build/bin/storm --version" - - name: Check compile flags - uses: ./.github/actions/check-compile-flags-action - with: - buildType: ${{ matrix.config.buildType }} - docker: true - - name: Run tests - # Disabled sanitizer checks for now - #run: docker exec ci bash -c "cd /opt/storm/build; ASAN_OPTIONS=detect_leaks=0,detect_odr_violation=0 ctest test --output-on-failure" - run: docker exec ci bash -c "cd /opt/storm/build; ctest test --output-on-failure" - - name: Build starter-project - uses: ./.github/actions/starter-project-action - with: - docker: true - stormDir: "/opt/storm/build" - command: "--help" # TODO using --help as running the starter-project requires Z3. - - name: Install storm - run: docker exec ci bash -c "cd /opt/storm/build; make install" - - name: Remove build dir - run: | - docker exec ci bash -c "rm -rf /opt/storm/build" - - name: Run installed storm - run: | - docker exec ci bash -c "/usr/local/bin/storm --version" - - name: Build starter-project on installed Storm - uses: ./.github/actions/starter-project-action - with: - docker: true - stormDir: "" - command: "--help" # TODO using --help as running the starter-project requires Z3. - - compilerTests: - # Build and run with different compilers (GCC, Clang) - # Run on latest Archlinux version to get most recent compiler versions - name: Compiler Tests (${{ matrix.config.name }} on ${{ matrix.config.distro }}, ${{ matrix.config.buildType }}) - runs-on: ubuntu-latest - strategy: - matrix: - config: - - {name: "GCC", - buildType: "Debug", - Developer: "ON", - cmakeArgs: "-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DSTORM_WARNING_AS_ERROR=ON", - packages: "", - distro: "archlinux" - } - - {name: "Clang", - buildType: "Debug", - Developer: "ON", - cmakeArgs: "-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DSTORM_WARNING_AS_ERROR=ON", - packages: "clang", - distro: "archlinux" - } - - {name: "musl", - buildType: "Debug", - Developer: "ON", - cmakeArgs: "-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DSTORM_WARNING_AS_ERROR=ON", - packages: "", - distro: "alpine" - } - steps: - - name: Git clone - uses: actions/checkout@v7 - - name: Replace Dockerfile - run: cp .github/workflows/Dockerfile.${{ matrix.config.distro }} Dockerfile - - name: Build storm from Dockerfile - run: | - docker build -t movesrwth/storm:ci . \ - --build-arg build_type="${{ matrix.config.buildType }}" \ - --build-arg carl_tag="master" \ - --build-arg developer="${{ matrix.config.Developer }}" \ - --build-arg cmake_args="${{ matrix.config.cmakeArgs }}" \ - --build-arg packages="${{ matrix.config.packages }}" \ - --build-arg no_threads=${NR_JOBS} - # Omitting arguments disable_*, cln_exact, cln_ratfunc, all_sanitizers - - name: Run Docker - run: docker run -d -it --name ci movesrwth/storm:ci - - name: Run storm - run: docker exec ci bash -c "/opt/storm/build/bin/storm --version" - - name: Check compile flags - uses: ./.github/actions/check-compile-flags-action - with: - buildType: ${{ matrix.config.buildType }} - docker: true - - name: Run tests - run: docker exec ci bash -c "cd /opt/storm/build; ctest test --output-on-failure" - - name: Build starter-project - uses: ./.github/actions/starter-project-action - with: - docker: true - stormDir: "/opt/storm/build" - command: "/opt/storm/resources/examples/testfiles/dtmc/brp-16-2.pm 'P=? [F s=5]'" - - name: Install storm - run: docker exec ci bash -c "cd /opt/storm/build; make install" - - name: Remove build dir - run: | - docker exec ci bash -c "rm -rf /opt/storm/build" - - name: Run installed storm - run: | - docker exec ci bash -c "/usr/local/bin/storm --version" - - name: Build starter-project on installed Storm - uses: ./.github/actions/starter-project-action - with: - docker: true - stormDir: "" - command: "/opt/storm/resources/examples/testfiles/dtmc/brp-16-2.pm 'P=? [F s=5]'" - - linuxTests: - name: Linux Tests (${{ matrix.distro }}, ${{ matrix.buildType }}) on ${{ matrix.runner }} - runs-on: ${{ matrix.runner }} - strategy: - matrix: - distro: ["debian-12", "ubuntu-24.04", "debian-13"] - buildType: ["Release"] - runner: [ubuntu-latest, ubuntu-24.04-arm] - steps: - - name: Git clone - uses: actions/checkout@v7 - - name: Build storm from Dockerfile - run: | - docker build -t movesrwth/storm:ci . \ - --build-arg BASE_IMAGE=movesrwth/storm-basesystem:${{ matrix.distro }} \ - --build-arg build_type="${{ matrix.buildType }}" \ - --build-arg carl_tag="master" \ - --build-arg no_threads=${NR_JOBS} \ - --build-arg cmake_args="-DSTORM_WARNING_AS_ERROR=ON" - # Omitting arguments developer, disable_*, cln_exact, cln_ratfunc, all_sanitizers - - name: Run Docker - run: docker run -d -it --name ci movesrwth/storm:ci - - name: Run storm - run: docker exec ci bash -c "/opt/storm/build/bin/storm --version" - - name: Check compile flags - uses: ./.github/actions/check-compile-flags-action - with: - buildType: ${{ matrix.buildType }} - docker: true - - name: Run tests - run: docker exec ci bash -c "cd /opt/storm/build; ctest test --output-on-failure" - - name: Build starter-project - uses: ./.github/actions/starter-project-action - with: - docker: true - stormDir: "/opt/storm/build" - command: "/opt/storm/resources/examples/testfiles/dtmc/brp-16-2.pm 'P=? [F s=5]'" - - name: Install storm - run: docker exec ci bash -c "cd /opt/storm/build; make install" - - name: Remove build dir - run: | - docker exec ci bash -c "rm -rf /opt/storm/build" - - name: Run installed storm - run: | - docker exec ci bash -c "/usr/local/bin/storm --version" - - name: Build starter-project on installed Storm - uses: ./.github/actions/starter-project-action - with: - docker: true - stormDir: "" - command: "/opt/storm/resources/examples/testfiles/dtmc/brp-16-2.pm 'P=? [F s=5]'" - - macTests: - name: macOS Tests (${{ matrix.config.name }}, ${{ matrix.config.buildType }}) - strategy: - matrix: - config: - - {name: "MacOS 14, ARM", - distro: "macos-14", - xcode: "15.4", - buildType: "Debug" - } - - {name: "MacOS 15, ARM", - distro: "macos-15", - xcode: "16.4", - buildType: "Debug" - } - - {name: "MacOS 26, ARM", - distro: "macos-26", - xcode: "latest-stable", - buildType: "Debug" - } - - {name: "MacOS 26, Intel", - distro: "macos-26-intel", - xcode: "latest-stable", - buildType: "Debug" - } - runs-on: ${{ matrix.config.distro }} - steps: - - uses: maxim-lobanov/setup-xcode@v1 - with: - xcode-version: ${{ matrix.config.xcode }} - - name: Git clone - uses: actions/checkout@v7 - - name: Install dependencies - # cmake and gmp are already installed - run: | - brew update - brew install automake boost cln ginac glpk hwloc libarchive xerces-c z3 - - name: Configure storm - run: | - mkdir build - cd build - cmake .. -DCMAKE_BUILD_TYPE="${{ matrix.config.buildType }}" -DSTORM_CARL_GIT_TAG="master" -DSTORM_WARNING_AS_ERROR=ON - - name: Build storm - working-directory: ./build - run: make -j ${NR_JOBS} - - name: Run storm (build tree) - working-directory: ./build - run: ./bin/storm - - name: Check compile flags - uses: ./.github/actions/check-compile-flags-action - with: - buildType: ${{ matrix.config.buildType }} - docker: false - - name: Run tests - working-directory: ./build - run: ctest test --output-on-failure - - name: Build starter-project - uses: ./.github/actions/starter-project-action - with: - docker: false - stormDir: "${GITHUB_WORKSPACE}/build" - command: "${GITHUB_WORKSPACE}/resources/examples/testfiles/dtmc/brp-16-2.pm 'P=? [F s=5]'" - - name: Install storm - working-directory: ./build - run: sudo make install - - name: Remove build dir - run: | - rm -rf ${GITHUB_WORKSPACE}/build - - name: Run installed storm - run: | - /usr/local/bin/storm --version - - name: Build starter-project on installed Storm - uses: ./.github/actions/starter-project-action - with: - docker: false - stormDir: "" - command: "${GITHUB_WORKSPACE}/resources/examples/testfiles/dtmc/brp-16-2.pm 'P=? [F s=5]'" - - deploy: - name: Test and Deploy (${{ matrix.buildType.name }}) - runs-on: ubuntu-latest - strategy: - matrix: - buildType: - - {name: "Debug", - dockerTag: "ci-debug", - baseImg: "storm-dependencies:latest", - Developer: "ON", - cmakeArgs: "-DSTORM_WARNING_AS_ERROR=ON" - } - - {name: "Release", - dockerTag: "ci", - baseImg: "storm-dependencies:latest", - Developer: "OFF", - cmakeArgs: "-DSTORM_WARNING_AS_ERROR=ON" - } - steps: - - name: Git clone - uses: actions/checkout@v7 - - name: Git describe - id: ghd - uses: proudust/gh-describe@v3 - - name: Set static Storm version - run: echo "set(STORM_VERSION_COMMITS_AHEAD ${{ steps.ghd.outputs.distance }})" >> version.cmake - - name: Build storm from Dockerfile - run: | - docker build -t movesrwth/storm:${{ matrix.buildType.dockerTag }} . \ - --build-arg BASE_IMAGE=movesrwth/${{ matrix.buildType.baseImg }} \ - --build-arg build_type="${{ matrix.buildType.name }}" \ - --build-arg carl_tag="master" \ - --build-arg developer="${{ matrix.buildType.Developer }}" \ - --build-arg cmake_args="${{ matrix.buildType.cmakeArgs }}" \ - --build-arg no_threads=${NR_JOBS} - # Omitting arguments disable_*, cln_exact, cln_ratfunc, all_sanitizers - - name: Run Docker - run: docker run -d -it --name ci movesrwth/storm:${{ matrix.buildType.dockerTag }} - - name: Check compile flags - uses: ./.github/actions/check-compile-flags-action - with: - buildType: ${{ matrix.buildType.name }} - docker: true - - name: Run tests - run: docker exec ci bash -c "cd /opt/storm/build; ctest test --output-on-failure" - - name: Build starter-project - uses: ./.github/actions/starter-project-action - with: - docker: true - stormDir: "/opt/storm/build" - command: "/opt/storm/resources/examples/testfiles/dtmc/brp-16-2.pm 'P=? [F s=5]'" - - name: Install storm - run: docker exec ci bash -c "cd /opt/storm/build; make install" - - name: Temporarily move build dir - run: | - docker exec ci bash -c "mv /opt/storm/build /opt/storm/build-backup" - - name: Run installed storm - run: | - docker exec ci bash -c "/usr/local/bin/storm --version" - - name: Build starter-project on installed Storm - uses: ./.github/actions/starter-project-action - with: - docker: true - stormDir: "" - command: "/opt/storm/resources/examples/testfiles/dtmc/brp-16-2.pm 'P=? [F s=5]'" - - name: Restore build dir - run: | - docker exec ci bash -c "mv /opt/storm/build-backup /opt/storm/build" - - name: Login into docker - # Only login if using master on original repo (and not for pull requests or forks) - if: github.repository_owner == 'stormchecker' && github.ref == 'refs/heads/master' - uses: docker/login-action@v4 - with: - username: ${{ secrets.STORM_CI_DOCKER_USERNAME }} - password: ${{ secrets.STORM_CI_DOCKER_TOKEN }} - - name: Deploy storm - # Only deploy if using master on original repo (and not for pull requests or forks) - if: github.repository_owner == 'stormchecker' && github.ref == 'refs/heads/master' - run: | - docker commit ci movesrwth/storm:${{ matrix.buildType.dockerTag }} - docker push movesrwth/storm:${{ matrix.buildType.dockerTag }} - - notify: - name: Email notification - runs-on: ubuntu-latest - needs: [indepthTests, compilerTests, linuxTests, macTests, deploy] - # Only run in main repo and even if previous step failed - if: github.repository_owner == 'stormchecker' && always() - steps: - - uses: technote-space/workflow-conclusion-action@v3 - - uses: dawidd6/action-send-mail@v18 - with: - server_address: ${{ secrets.STORM_CI_MAIL_SERVER }} - server_port: 587 - username: ${{ secrets.STORM_CI_MAIL_USERNAME }} - password: ${{ secrets.STORM_CI_MAIL_PASSWORD }} - subject: "[You broke it] CI run failed for ${{ github.repository }}" - body: - "CI job of ${{ github.repository }} has failed for commit ${{ github.sha }}.\n\ - The error type is: ${{ env.WORKFLOW_CONCLUSION }}.\n\n\ - For more information, see https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" - to: ${{ secrets.STORM_CI_MAIL_RECIPIENTS }} - from: Github Actions - if: env.WORKFLOW_CONCLUSION != 'success' # notify only if failure diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml new file mode 100644 index 0000000000..96fafe8624 --- /dev/null +++ b/.github/workflows/ci-pr.yml @@ -0,0 +1,140 @@ +name: CI PR +# Runs on every pull request commit: compile-flag checks and short tests. +# All jobs are cached and fail-fast. + +on: + pull_request: + +jobs: + buildTests: + if: "! contains(github.event.pull_request.labels.*.name, 'ready for review')" + strategy: + fail-fast: true + matrix: + config: + - {name: "Debug; All dependencies", + buildType: "Debug", + baseImg: "movesrwth/storm-dependencies:latest", + disable_all: false, + ClnExact: false, + ClnRatfunc: false + } + - {name: "Release; All dependencies", + buildType: "Release", + baseImg: "movesrwth/storm-dependencies:latest", + disable_all: false, + ClnExact: false, + ClnRatfunc: false + } + - {name: "Release; GMP; GMP; Minimal dependencies", + buildType: "Release", + baseImg: "movesrwth/storm-basesystem:minimal_dependencies", + disable_all: true, + ClnExact: false, + ClnRatfunc: false + } + uses: ./.github/workflows/test-build.yml + with: + nr_jobs: "4" + name: ${{ matrix.config.name }} + baseImg: ${{ matrix.config.baseImg }} + buildType: ${{ matrix.config.buildType }} + disable_cudd: ${{ matrix.config.disable_all }} + disable_glpk: ${{ matrix.config.disable_all }} + disable_gmm: ${{ matrix.config.disable_all }} + disable_gurobi: ${{ matrix.config.disable_all }} + disable_libarchive: ${{ matrix.config.disable_all }} + disable_mathsat: ${{ matrix.config.disable_all }} + disable_soplex: ${{ matrix.config.disable_all }} + disable_spot: ${{ matrix.config.disable_all }} + disable_sylvan: ${{ matrix.config.disable_all }} + disable_xerces: ${{ matrix.config.disable_all }} + disable_z3: ${{ matrix.config.disable_all }} + Developer: ${{ matrix.config.buildType == 'Debug' }} + ClnExact: ${{ matrix.config.ClnExact }} + ClnRatfunc: ${{ matrix.config.ClnRatfunc }} + AllSanitizers: false + restore_cache: true + save_cache: true + install: false + + compilerTests: + if: "! contains(github.event.pull_request.labels.*.name, 'ready for review')" + strategy: + fail-fast: true + matrix: + config: + - {name: "GCC", + cmakeArgs: "-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DSTORM_WARNING_AS_ERROR=ON", + packages: "", + dockerfile: ".github/workflows/Dockerfile.archlinux", + baseImg: "archlinux:latest" + } + - {name: "Clang", + cmakeArgs: "-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DSTORM_WARNING_AS_ERROR=ON", + packages: "clang", + dockerfile: ".github/workflows/Dockerfile.archlinux", + baseImg: "archlinux:latest" + } + uses: ./.github/workflows/test-build.yml + with: + nr_jobs: "4" + name: ${{ matrix.config.name }} + buildType: Debug + Developer: true + baseImg: ${{ matrix.config.baseImg }} + cmakeArgs: ${{ matrix.config.cmakeArgs }} + packages: ${{ matrix.config.packages }} + dockerfile: ${{ matrix.config.dockerfile }} + starterProjectCommand: "/opt/storm/resources/examples/testfiles/dtmc/brp-16-2.pm 'P=? [F s=5]'" + restore_cache: true + save_cache: true + install: false + + linuxTests: + if: "! contains(github.event.pull_request.labels.*.name, 'ready for review')" + strategy: + fail-fast: true + matrix: + distro: ["debian-12", "ubuntu-24.04"] + uses: ./.github/workflows/test-linux.yml + with: + nr_jobs: "4" + distro: ${{ matrix.distro }} + buildType: Release + runner: ubuntu-latest + restore_cache: true + save_cache: true + install: false + + macTests: + if: "! contains(github.event.pull_request.labels.*.name, 'ready for review')" + strategy: + fail-fast: true + matrix: + config: + - {name: "Mac 14, ARM", + distro: "macos-14", + xcode: "15.4", + buildType: "Release" + } + - {name: "Mac 26, ARM", + distro: "macos-26", + xcode: "latest-stable", + buildType: "Release" + } + - {name: "Mac 26, Intel", + distro: "macos-26-intel", + xcode: "latest-stable", + buildType: "Release" + } + uses: ./.github/workflows/test-mac.yml + with: + nr_jobs: "4" + name: ${{ matrix.config.name }} + distro: ${{ matrix.config.distro }} + xcode: ${{ matrix.config.xcode }} + buildType: ${{ matrix.config.buildType }} + restore_cache: true + save_cache: true + install: false diff --git a/.github/workflows/ci-ready-for-review.yml b/.github/workflows/ci-ready-for-review.yml new file mode 100644 index 0000000000..446d07149b --- /dev/null +++ b/.github/workflows/ci-ready-for-review.yml @@ -0,0 +1,175 @@ +name: CI PR Ready for Review / Master +# Runs on PRs labelled "ready for review" and on every master push. +# Full task suite: compile flags, all tests, starter project, install, deploy. +# Cache is read-only on PRs, disabled on master. + +on: + push: + branches: [master] + pull_request: + types: [opened, synchronize, reopened, labeled] + +jobs: + buildTests: + if: contains(github.event.pull_request.labels.*.name, 'ready for review') || github.event_name == 'push' + strategy: + fail-fast: true + matrix: + config: + - {name: "Debug; All dependencies", + buildType: "Debug", + baseImg: "movesrwth/storm-dependencies:latest", + disable_all: false, + ClnExact: false, + ClnRatfunc: false + } + - {name: "Release; All dependencies", + buildType: "Release", + baseImg: "movesrwth/storm-dependencies:latest", + disable_all: false, + ClnExact: false, + ClnRatfunc: false + } + - {name: "Release; GMP; GMP; Required dependencies", + buildType: "Release", + baseImg: "movesrwth/storm-basesystem:latest", + disable_all: false, + ClnExact: false, + ClnRatfunc: false + } + - {name: "Release; CLN; CLN; Required dependencies", + buildType: "Release", + baseImg: "movesrwth/storm-basesystem:latest", + disable_all: false, + ClnExact: true, + ClnRatfunc: true + } + uses: ./.github/workflows/test-build.yml + with: + nr_jobs: "4" + name: ${{ matrix.config.name }} + baseImg: ${{ matrix.config.baseImg }} + buildType: ${{ matrix.config.buildType }} + disable_cudd: ${{ matrix.config.disable_all }} + disable_glpk: ${{ matrix.config.disable_all }} + disable_gmm: ${{ matrix.config.disable_all }} + disable_gurobi: ${{ matrix.config.disable_all }} + disable_libarchive: ${{ matrix.config.disable_all }} + disable_mathsat: ${{ matrix.config.disable_all }} + disable_soplex: ${{ matrix.config.disable_all }} + disable_spot: ${{ matrix.config.disable_all }} + disable_sylvan: ${{ matrix.config.disable_all }} + disable_xerces: ${{ matrix.config.disable_all }} + disable_z3: ${{ matrix.config.disable_all }} + Developer: ${{ matrix.config.buildType == 'Debug' }} + ClnExact: ${{ matrix.config.ClnExact }} + ClnRatfunc: ${{ matrix.config.ClnRatfunc }} + AllSanitizers: false + restore_cache: ${{ github.event_name != 'push' }} + save_cache: false + install: true + + compilerTests: + if: contains(github.event.pull_request.labels.*.name, 'ready for review') || github.event_name == 'push' + strategy: + fail-fast: true + matrix: + config: + - {name: "GCC", + cmakeArgs: "-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DSTORM_WARNING_AS_ERROR=ON", + packages: "", + dockerfile: ".github/workflows/Dockerfile.archlinux", + baseImg: "archlinux:latest" + } + - {name: "Clang", + cmakeArgs: "-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DSTORM_WARNING_AS_ERROR=ON", + packages: "clang", + dockerfile: ".github/workflows/Dockerfile.archlinux", + baseImg: "archlinux:latest" + } + uses: ./.github/workflows/test-build.yml + with: + nr_jobs: "4" + name: ${{ matrix.config.name }} + buildType: Debug + Developer: true + baseImg: ${{ matrix.config.baseImg }} + cmakeArgs: ${{ matrix.config.cmakeArgs }} + packages: ${{ matrix.config.packages }} + dockerfile: ${{ matrix.config.dockerfile }} + starterProjectCommand: "/opt/storm/resources/examples/testfiles/dtmc/brp-16-2.pm 'P=? [F s=5]'" + restore_cache: ${{ github.event_name != 'push' }} + save_cache: false + install: true + + linuxTests: + if: contains(github.event.pull_request.labels.*.name, 'ready for review') || github.event_name == 'push' + strategy: + fail-fast: true + matrix: + distro: ["debian-12", "debian-13", "ubuntu-24.04"] + uses: ./.github/workflows/test-linux.yml + with: + nr_jobs: "4" + distro: ${{ matrix.distro }} + buildType: Release + runner: ubuntu-latest + restore_cache: ${{ github.event_name != 'push' }} + save_cache: false + install: true + + macTests: + if: contains(github.event.pull_request.labels.*.name, 'ready for review') || github.event_name == 'push' + strategy: + fail-fast: true + matrix: + config: + - {name: "Mac 14, ARM", + distro: "macos-14", + xcode: "15.4", + buildType: "Release" + } + - {name: "Mac 15, ARM", + distro: "macos-15", + xcode: "16.4", + buildType: "Release" + } + - {name: "Mac 26, ARM", + distro: "macos-26", + xcode: "latest-stable", + buildType: "Release" + } + - {name: "Mac 26, Intel", + distro: "macos-26-intel", + xcode: "latest-stable", + buildType: "Release" + } + uses: ./.github/workflows/test-mac.yml + with: + nr_jobs: "4" + name: ${{ matrix.config.name }} + distro: ${{ matrix.config.distro }} + xcode: ${{ matrix.config.xcode }} + buildType: ${{ matrix.config.buildType }} + restore_cache: ${{ github.event_name != 'push' }} + save_cache: false + install: true + + deploy: + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + strategy: + fail-fast: true + matrix: + config: + - {buildType: "Debug", + dockerTag: "ci-debug" + } + - {buildType: "Release", + dockerTag: "ci" + } + uses: ./.github/workflows/test-deploy.yml + with: + nr_jobs: "4" + buildType: ${{ matrix.config.buildType }} + dockerTag: ${{ matrix.config.dockerTag }} + secrets: inherit diff --git a/.github/workflows/ci-weekly.yml b/.github/workflows/ci-weekly.yml new file mode 100644 index 0000000000..cf4111e5c7 --- /dev/null +++ b/.github/workflows/ci-weekly.yml @@ -0,0 +1,199 @@ +name: CI Weekly +# Comprehensive weekly test run across all configurations. +# No cache, not fail-fast, full task suite including deploy. + +on: + schedule: + - cron: '0 6 * * 1' # Every Monday at 06:00 UTC + workflow_dispatch: + +jobs: + buildTests: + strategy: + fail-fast: false + matrix: + buildType: ["Debug", "Release"] + config: + - {name: "GMP; GMP; Required dependencies", + baseImg: "movesrwth/storm-basesystem:latest", + disable_all: false, + ClnExact: false, + ClnRatfunc: false + } + - {name: "CLN; GMP; Required dependencies", + baseImg: "movesrwth/storm-basesystem:latest", + disable_all: false, + ClnExact: true, + ClnRatfunc: false + } + - {name: "GMP; CLN; Required dependencies", + baseImg: "movesrwth/storm-basesystem:latest", + disable_all: false, + ClnExact: false, + ClnRatfunc: true + } + - {name: "CLN; CLN; Required dependencies", + baseImg: "movesrwth/storm-basesystem:latest", + disable_all: false, + ClnExact: true, + ClnRatfunc: true + } + - {name: "All dependencies (disabled)", + baseImg: "movesrwth/storm-dependencies:latest", + disable_all: true, + ClnExact: false, + ClnRatfunc: false + } + - {name: "Minimal dependencies", + baseImg: "movesrwth/storm-basesystem:minimal_dependencies", + disable_all: true, + ClnExact: false, + ClnRatfunc: false + } + uses: ./.github/workflows/test-build.yml + with: + nr_jobs: "4" + name: ${{ matrix.config.name }} + baseImg: ${{ matrix.config.baseImg }} + buildType: ${{ matrix.buildType }} + disable_cudd: ${{ matrix.config.disable_all }} + disable_glpk: ${{ matrix.config.disable_all }} + disable_gmm: ${{ matrix.config.disable_all }} + disable_gurobi: ${{ matrix.config.disable_all }} + disable_libarchive: ${{ matrix.config.disable_all }} + disable_mathsat: ${{ matrix.config.disable_all }} + disable_soplex: ${{ matrix.config.disable_all }} + disable_spot: ${{ matrix.config.disable_all }} + disable_sylvan: ${{ matrix.config.disable_all }} + disable_xerces: ${{ matrix.config.disable_all }} + disable_z3: ${{ matrix.config.disable_all }} + Developer: ${{ matrix.buildType == 'Debug' }} + ClnExact: ${{ matrix.config.ClnExact }} + ClnRatfunc: ${{ matrix.config.ClnRatfunc }} + AllSanitizers: false + restore_cache: false + save_cache: false + install: true + + compilerTests: + strategy: + fail-fast: false + matrix: + buildType: ["Debug", "Release"] + config: + - {name: "GCC", + cmakeArgs: "-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DSTORM_WARNING_AS_ERROR=ON", + packages: "", + dockerfile: ".github/workflows/Dockerfile.archlinux", + baseImg: "archlinux:latest" + } + - {name: "Clang", + cmakeArgs: "-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DSTORM_WARNING_AS_ERROR=ON", + packages: "clang", + dockerfile: ".github/workflows/Dockerfile.archlinux", + baseImg: "archlinux:latest" + } + uses: ./.github/workflows/test-build.yml + with: + nr_jobs: "4" + name: ${{ matrix.config.name }} + buildType: ${{ matrix.buildType }} + Developer: ${{ matrix.buildType == 'Debug' }} + baseImg: ${{ matrix.config.baseImg }} + cmakeArgs: ${{ matrix.config.cmakeArgs }} + packages: ${{ matrix.config.packages }} + dockerfile: ${{ matrix.config.dockerfile }} + starterProjectCommand: "/opt/storm/resources/examples/testfiles/dtmc/brp-16-2.pm 'P=? [F s=5]'" + restore_cache: false + save_cache: false + install: true + + linuxTests: + strategy: + fail-fast: false + matrix: + distro: ["debian-12", "debian-13", "ubuntu-24.04"] + buildType: ["Debug", "Release"] + uses: ./.github/workflows/test-linux.yml + with: + nr_jobs: "4" + distro: ${{ matrix.distro }} + buildType: ${{ matrix.buildType }} + runner: ubuntu-latest + restore_cache: false + save_cache: false + install: true + + macTests: + strategy: + fail-fast: false + matrix: + buildType: ["Debug", "Release"] + config: + - {name: "Mac 14, ARM", + distro: "macos-14", + xcode: "15.4" + } + - {name: "Mac 15, ARM", + distro: "macos-15", + xcode: "16.4" + } + - {name: "Mac 26, ARM", + distro: "macos-26", + xcode: "latest-stable" + } + - {name: "Mac 26, Intel", + distro: "macos-26-intel", + xcode: "latest-stable" + } + uses: ./.github/workflows/test-mac.yml + with: + nr_jobs: "4" + name: ${{ matrix.config.name }} + distro: ${{ matrix.config.distro }} + xcode: ${{ matrix.config.xcode }} + buildType: ${{ matrix.buildType }} + restore_cache: false + save_cache: false + install: true + + deploy: + strategy: + fail-fast: false + matrix: + config: + - {buildType: "Debug", + dockerTag: "ci-debug" + } + - {buildType: "Release", + dockerTag: "ci" + } + # TODO: Add binaries build/publish configs + uses: ./.github/workflows/test-deploy.yml + with: + nr_jobs: "4" + buildType: ${{ matrix.config.buildType }} + dockerTag: ${{ matrix.config.dockerTag }} + secrets: inherit + + notify: + name: Email notification + runs-on: ubuntu-latest + needs: [buildTests, compilerTests, linuxTests, macTests, deploy] + if: github.repository_owner == 'stormchecker' && always() + steps: + - uses: technote-space/workflow-conclusion-action@v3 + - uses: dawidd6/action-send-mail@v18 + with: + server_address: ${{ secrets.STORM_CI_MAIL_SERVER }} + server_port: 587 + username: ${{ secrets.STORM_CI_MAIL_USERNAME }} + password: ${{ secrets.STORM_CI_MAIL_PASSWORD }} + subject: "[You broke it] CI Weekly failed for ${{ github.repository }}" + body: + "CI job of ${{ github.repository }} has failed for commit ${{ github.sha }}.\n\ + The error type is: ${{ env.WORKFLOW_CONCLUSION }}.\n\n\ + For more information, see https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" + to: ${{ secrets.STORM_CI_MAIL_RECIPIENTS }} + from: Github Actions + if: env.WORKFLOW_CONCLUSION != 'success' diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml new file mode 100644 index 0000000000..a70be8c3cb --- /dev/null +++ b/.github/workflows/test-build.yml @@ -0,0 +1,194 @@ +name: Build Tests + +on: + workflow_call: + inputs: + nr_jobs: + description: "Number of parallel build jobs" + type: string + default: "4" + name: + description: "Display name for the test configuration" + type: string + required: true + buildType: + description: "CMake build type (Debug or Release)" + type: string + default: "Debug" + Developer: + description: "Enable developer mode" + type: boolean + default: true + cmakeArgs: + description: "Extra CMake arguments" + type: string + default: "-DSTORM_WARNING_AS_ERROR=ON" + dockerfile: + description: "Path to the Dockerfile to use" + type: string + default: "Dockerfile" + starterProjectCommand: + description: "Command to pass to the starter-project" + type: string + default: "--help" + baseImg: + description: "Full base image name (e.g. movesrwth/storm-dependencies:latest or archlinux:latest)" + type: string + default: "movesrwth/storm-dependencies:latest" + disable_cudd: + type: boolean + default: false + disable_glpk: + type: boolean + default: false + disable_gmm: + type: boolean + default: false + disable_gurobi: + type: boolean + default: false + disable_libarchive: + type: boolean + default: false + disable_mathsat: + type: boolean + default: false + disable_soplex: + type: boolean + default: false + disable_spot: + type: boolean + default: false + disable_sylvan: + type: boolean + default: false + disable_xerces: + type: boolean + default: false + disable_z3: + type: boolean + default: false + ClnExact: + description: "Use CLN for exact arithmetic" + type: boolean + default: false + ClnRatfunc: + description: "Use CLN for rational functions" + type: boolean + default: false + AllSanitizers: + description: "Enable all sanitizers" + type: boolean + default: false + packages: + description: "Extra packages to install (e.g. clang)" + type: string + default: "" + restore_cache: + description: "Restore ccache from cache" + type: boolean + default: false + save_cache: + description: "Save ccache to cache" + type: boolean + default: false + install: + description: "Run post-build steps: starter project, install, run installed storm" + type: boolean + default: true + +jobs: + buildTests: + name: Build Tests (${{ inputs.name }}, ${{ inputs.buildType }}) + runs-on: ubuntu-latest + env: + NR_JOBS: ${{ inputs.nr_jobs }} + steps: + - name: Git clone + uses: actions/checkout@v7 + - name: Restore ccache (Docker) + id: ccache-restore + if: inputs.restore_cache + uses: actions/cache/restore@v4 + with: + path: .ci-ccache + key: buildtest-ccache-${{ inputs.name }}-${{ inputs.buildType }}-${{ hashFiles(inputs.dockerfile, 'CMakeLists.txt') }}-${{ github.run_id }} + restore-keys: | + buildtest-ccache-${{ inputs.name }}-${{ inputs.buildType }}- + buildtest-ccache-${{ inputs.name }}- + - name: Build storm from Dockerfile + run: | + mkdir -p .ci-ccache + docker build -t movesrwth/storm:ci --file ${{ inputs.dockerfile }} . \ + --build-arg BASE_IMAGE=${{ inputs.baseImg }} \ + --build-arg build_type="${{ inputs.buildType }}" \ + --build-arg disable_cudd="${{ inputs.disable_cudd && 'ON' || 'OFF' }}" \ + --build-arg disable_glpk="${{ inputs.disable_glpk && 'ON' || 'OFF' }}" \ + --build-arg disable_gmm="${{ inputs.disable_gmm && 'ON' || 'OFF' }}" \ + --build-arg disable_gurobi="${{ inputs.disable_gurobi && 'ON' || 'OFF' }}" \ + --build-arg disable_libarchive="${{ inputs.disable_libarchive && 'ON' || 'OFF' }}" \ + --build-arg disable_mathsat="${{ inputs.disable_mathsat && 'ON' || 'OFF' }}" \ + --build-arg disable_soplex="${{ inputs.disable_soplex && 'ON' || 'OFF' }}" \ + --build-arg disable_spot="${{ inputs.disable_spot && 'ON' || 'OFF' }}" \ + --build-arg disable_sylvan="${{ inputs.disable_sylvan && 'ON' || 'OFF' }}" \ + --build-arg disable_xerces="${{ inputs.disable_xerces && 'ON' || 'OFF' }}" \ + --build-arg disable_z3="${{ inputs.disable_z3 && 'ON' || 'OFF' }}" \ + --build-arg developer="${{ inputs.Developer && 'ON' || 'OFF' }}" \ + --build-arg cln_exact="${{ inputs.ClnExact && 'ON' || 'OFF' }}" \ + --build-arg cln_ratfunc="${{ inputs.ClnRatfunc && 'ON' || 'OFF' }}" \ + --build-arg all_sanitizers="${{ inputs.AllSanitizers && 'ON' || 'OFF' }}" \ + --build-arg cmake_args="${{ inputs.cmakeArgs }}" \ + --build-arg packages="${{ inputs.packages }}" \ + --build-arg no_threads=${NR_JOBS} + - name: Export ccache from Docker image + if: inputs.save_cache && always() && steps.ccache-restore.outputs.cache-hit != 'true' + run: | + rm -rf .ci-ccache + mkdir -p .ci-ccache + docker create --name ccache-extract movesrwth/storm:ci + docker cp ccache-extract:/root/.ccache/. .ci-ccache/ || true + docker rm ccache-extract + - name: Save ccache (Docker) + if: inputs.save_cache && always() && steps.ccache-restore.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: .ci-ccache + key: buildtest-ccache-${{ inputs.name }}-${{ inputs.buildType }}-${{ hashFiles(inputs.dockerfile, 'CMakeLists.txt') }}-${{ github.run_id }} + - name: Run Docker + run: docker run -d -it --name ci movesrwth/storm:ci + - name: Run storm + run: docker exec ci bash -c "/opt/storm/build/bin/storm --version" + - name: Check compile flags + uses: ./.github/actions/check-compile-flags-action + with: + buildType: ${{ inputs.buildType }} + docker: true + - name: Run tests + # Disabled sanitizer checks for now + #run: docker exec ci bash -c "cd /opt/storm/build; ASAN_OPTIONS=detect_leaks=0,detect_odr_violation=0 ctest test --output-on-failure" + run: docker exec ci bash -c "cd /opt/storm/build; ctest test --output-on-failure" + - name: Build starter-project + if: inputs.install + uses: ./.github/actions/starter-project-action + with: + docker: true + stormDir: "/opt/storm/build" + command: ${{ inputs.starterProjectCommand }} + - name: Install storm + if: inputs.install + run: docker exec ci bash -c "cd /opt/storm/build; make install" + - name: Remove build dir + if: inputs.install + run: | + docker exec ci bash -c "rm -rf /opt/storm/build" + - name: Run installed storm + if: inputs.install + run: | + docker exec ci bash -c "/usr/local/bin/storm --version" + - name: Build starter-project on installed Storm + if: inputs.install + uses: ./.github/actions/starter-project-action + with: + docker: true + stormDir: "" + command: ${{ inputs.starterProjectCommand }} diff --git a/.github/workflows/test-deploy.yml b/.github/workflows/test-deploy.yml new file mode 100644 index 0000000000..3765b96681 --- /dev/null +++ b/.github/workflows/test-deploy.yml @@ -0,0 +1,108 @@ +name: Deploy + +on: + workflow_call: + inputs: + carl_tag: + description: "Carl git tag to use" + type: string + default: "master" + nr_jobs: + description: "Number of parallel build jobs" + type: string + default: "4" + buildType: + description: "Build type name (Debug or Release)" + type: string + required: true + dockerTag: + description: "Docker image tag to use (e.g. ci-debug, ci)" + type: string + required: true + baseImg: + description: "Base image name (e.g. storm-dependencies:latest)" + type: string + default: "storm-dependencies:latest" + Developer: + description: "Enable developer mode" + type: boolean + default: false + cmakeArgs: + description: "Extra CMake arguments" + type: string + default: "" + secrets: + STORM_CI_DOCKER_USERNAME: + required: false + STORM_CI_DOCKER_TOKEN: + required: false + +jobs: + deploy: + name: Test and Deploy (${{ inputs.buildType }}) + runs-on: ubuntu-latest + env: + NR_JOBS: ${{ inputs.nr_jobs }} + steps: + - name: Git clone + uses: actions/checkout@v7 + - name: Git describe + id: ghd + uses: proudust/gh-describe@v3 + - name: Set static Storm version + run: echo "set(STORM_VERSION_COMMITS_AHEAD ${{ steps.ghd.outputs.distance }})" >> version.cmake + - name: Build storm from Dockerfile + run: | + docker build -t movesrwth/storm:${{ inputs.dockerTag }} . \ + --build-arg BASE_IMAGE=movesrwth/${{ inputs.baseImg }} \ + --build-arg build_type="${{ inputs.buildType }}" \ + --build-arg carl_tag="${{ inputs.carl_tag }}" \ + --build-arg developer="${{ inputs.Developer && 'ON' || 'OFF' }}" \ + --build-arg cmake_args="${{ inputs.cmakeArgs }}" \ + --build-arg no_threads=${NR_JOBS} + # Omitting arguments disable_*, cln_exact, cln_ratfunc, all_sanitizers + - name: Run Docker + run: docker run -d -it --name ci movesrwth/storm:${{ inputs.dockerTag }} + - name: Check compile flags + uses: ./.github/actions/check-compile-flags-action + with: + buildType: ${{ inputs.buildType }} + docker: true + - name: Run tests + run: docker exec ci bash -c "cd /opt/storm/build; ctest test --output-on-failure" + - name: Build starter-project + uses: ./.github/actions/starter-project-action + with: + docker: true + stormDir: "/opt/storm/build" + command: "/opt/storm/resources/examples/testfiles/dtmc/brp-16-2.pm 'P=? [F s=5]'" + - name: Install storm + run: docker exec ci bash -c "cd /opt/storm/build; make install" + - name: Temporarily move build dir + run: | + docker exec ci bash -c "mv /opt/storm/build /opt/storm/build-backup" + - name: Run installed storm + run: | + docker exec ci bash -c "/usr/local/bin/storm --version" + - name: Build starter-project on installed Storm + uses: ./.github/actions/starter-project-action + with: + docker: true + stormDir: "" + command: "/opt/storm/resources/examples/testfiles/dtmc/brp-16-2.pm 'P=? [F s=5]'" + - name: Restore build dir + run: | + docker exec ci bash -c "mv /opt/storm/build-backup /opt/storm/build" + - name: Login into docker + # Only login if using master on original repo (and not for pull requests or forks) + if: github.repository_owner == 'stormchecker' && github.ref == 'refs/heads/master' + uses: docker/login-action@v4 + with: + username: ${{ secrets.STORM_CI_DOCKER_USERNAME }} + password: ${{ secrets.STORM_CI_DOCKER_TOKEN }} + - name: Deploy storm + # Only deploy if using master on original repo (and not for pull requests or forks) + if: github.repository_owner == 'stormchecker' && github.ref == 'refs/heads/master' + run: | + docker commit ci movesrwth/storm:${{ inputs.dockerTag }} + docker push movesrwth/storm:${{ inputs.dockerTag }} diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml new file mode 100644 index 0000000000..031c99e7ca --- /dev/null +++ b/.github/workflows/test-linux.yml @@ -0,0 +1,112 @@ +name: Linux Tests + +on: + workflow_call: + inputs: + nr_jobs: + description: "Number of parallel build jobs" + type: string + default: "4" + distro: + description: "distro to use as base image for the docker image" + type: string + required: true + buildType: + description: "build type to use for the docker image" + type: string + required: true + runner: + description: "runner to use for the job" + type: string + default: "ubuntu-latest" + restore_cache: + description: "Restore ccache from cache" + type: boolean + default: false + save_cache: + description: "Save ccache to cache" + type: boolean + default: false + install: + description: "Run post-build steps: starter project, install, run installed storm" + type: boolean + default: true + +jobs: + linuxTests: + name: Linux Tests (${{ inputs.distro }}, ${{ inputs.buildType }}) on ${{ inputs.runner }} + runs-on: ${{ inputs.runner }} + env: + NR_JOBS: ${{ inputs.nr_jobs }} + steps: + - name: Git clone + uses: actions/checkout@v7 + - name: Restore ccache (Docker) + id: ccache-restore + if: inputs.restore_cache + uses: actions/cache/restore@v4 + with: + path: .ci-ccache + key: buildtest-ccache-linux-${{ inputs.distro }}-${{ inputs.buildType }}-${{ inputs.runner }}-${{ github.run_id }} + restore-keys: | + buildtest-ccache-linux-${{ inputs.distro }}-${{ inputs.buildType }}-${{ inputs.runner }}- + buildtest-ccache-linux- + - name: Build storm from Dockerfile + run: | + mkdir -p .ci-ccache + docker build -t movesrwth/storm:ci . \ + --build-arg BASE_IMAGE=movesrwth/storm-basesystem:${{ inputs.distro }} \ + --build-arg build_type="${{ inputs.buildType }}" \ + --build-arg no_threads=${NR_JOBS} \ + --build-arg cmake_args="-DSTORM_WARNING_AS_ERROR=ON -DSTORM_COMPILE_WITH_PCH=OFF" + # Omitting arguments developer, disable_*, cln_exact, cln_ratfunc, all_sanitizers + - name: Export ccache from Docker image + if: inputs.save_cache && always() && steps.ccache-restore.outputs.cache-hit != 'true' + run: | + rm -rf .ci-ccache + mkdir -p .ci-ccache + docker create --name ccache-extract movesrwth/storm:ci + docker cp ccache-extract:/root/.ccache/. .ci-ccache/ || true + docker rm ccache-extract + - name: Save ccache (Docker) + if: inputs.save_cache && always() && steps.ccache-restore.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: .ci-ccache + key: buildtest-ccache-linux-${{ inputs.distro }}-${{ inputs.buildType }}-${{ inputs.runner }}-${{ github.run_id }} + - name: Run Docker + run: docker run -d -it --name ci movesrwth/storm:ci + - name: Run storm + run: docker exec ci bash -c "/opt/storm/build/bin/storm --version" + - name: Check compile flags + uses: ./.github/actions/check-compile-flags-action + with: + buildType: ${{ inputs.buildType }} + docker: true + - name: Run tests + run: docker exec ci bash -c "cd /opt/storm/build; ctest test --output-on-failure" + - name: Build starter-project + if: inputs.install + uses: ./.github/actions/starter-project-action + with: + docker: true + stormDir: "/opt/storm/build" + command: "/opt/storm/resources/examples/testfiles/dtmc/brp-16-2.pm 'P=? [F s=5]'" + - name: Install storm + if: inputs.install + run: docker exec ci bash -c "cd /opt/storm/build; make install" + - name: Remove build dir + if: inputs.install + run: | + docker exec ci bash -c "rm -rf /opt/storm/build" + - name: Run installed storm + if: inputs.install + run: | + docker exec ci bash -c "/usr/local/bin/storm --version" + - name: Build starter-project on installed Storm + if: inputs.install + uses: ./.github/actions/starter-project-action + with: + docker: true + stormDir: "" + command: "/opt/storm/resources/examples/testfiles/dtmc/brp-16-2.pm 'P=? [F s=5]'" diff --git a/.github/workflows/test-mac.yml b/.github/workflows/test-mac.yml new file mode 100644 index 0000000000..b67add236f --- /dev/null +++ b/.github/workflows/test-mac.yml @@ -0,0 +1,139 @@ +name: macOS Tests + +on: + workflow_call: + inputs: + nr_jobs: + description: "Number of parallel build jobs" + type: string + default: "4" + name: + description: "Display name (e.g. Xcode 15.4, ARM)" + type: string + required: true + distro: + description: "macOS runner image (e.g. macos-14, macos-15)" + type: string + required: true + xcode: + description: "Xcode version (e.g. 15.4, latest-stable)" + type: string + required: true + buildType: + description: "CMake build type (Debug or Release)" + type: string + required: true + restore_cache: + description: "Restore ccache and Homebrew cache" + type: boolean + default: false + save_cache: + description: "Save ccache to cache" + type: boolean + default: false + install: + description: "Run post-build steps: starter project, install, run installed storm" + type: boolean + default: true + +jobs: + macTests: + name: macOS Tests (${{ inputs.name }}, ${{ inputs.buildType }}) + runs-on: ${{ inputs.distro }} + env: + CCACHE_DIR: /Users/runner/.ccache + NR_JOBS: ${{ inputs.nr_jobs }} + steps: + - uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: ${{ inputs.xcode }} + - name: Git clone + uses: actions/checkout@v7 + - name: Cache Homebrew downloads + if: inputs.restore_cache + uses: actions/cache@v4 + with: + path: ~/Library/Caches/Homebrew + key: buildtest-brew-${{ inputs.distro }}-${{ hashFiles('.github/workflows/buildtest.yml') }} + restore-keys: | + buildtest-brew-${{ inputs.distro }}- + - name: Ensure ccache directory exists (macOS) + if: inputs.restore_cache + run: mkdir -p /Users/runner/.ccache + - name: Restore ccache (macOS) + id: ccache-restore-macos + if: inputs.restore_cache + uses: actions/cache/restore@v4 + with: + path: /Users/runner/.ccache + key: buildtest-ccache-macos-${{ inputs.distro }}-${{ inputs.buildType }}-${{ github.run_id }} + restore-keys: | + buildtest-ccache-macos-${{ inputs.distro }}-${{ inputs.buildType }}- + buildtest-ccache-macos-${{ inputs.distro }}- + buildtest-ccache-macos- + - name: Install dependencies + # cmake and gmp are already installed + run: | + brew update + brew install automake boost ccache cln ginac glpk hwloc libarchive xerces-c z3 + - name: Prepare ccache + if: inputs.restore_cache + run: | + ccache --max-size=2G + ccache --zero-stats + ccache --show-stats --verbose + - name: Configure storm + run: | + mkdir build + cd build + cmake .. -DCMAKE_BUILD_TYPE="${{ inputs.buildType }}" -DSTORM_WARNING_AS_ERROR=ON -DSTORM_COMPILE_WITH_PCH=OFF + - name: Build storm + working-directory: ./build + run: | + make -j ${NR_JOBS} + - name: Print ccache stats + if: inputs.restore_cache + run: ccache --show-stats --verbose + - name: Save ccache (macOS) + if: inputs.save_cache && always() && steps.ccache-restore-macos.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: /Users/runner/.ccache + key: buildtest-ccache-macos-${{ inputs.distro }}-${{ inputs.buildType }}-${{ github.run_id }} + - name: Run storm (build tree) + working-directory: ./build + run: ./bin/storm + - name: Check compile flags + uses: ./.github/actions/check-compile-flags-action + with: + buildType: ${{ inputs.buildType }} + docker: false + - name: Run tests + working-directory: ./build + run: ctest test --output-on-failure + - name: Build starter-project + if: inputs.install + uses: ./.github/actions/starter-project-action + with: + docker: false + stormDir: "${GITHUB_WORKSPACE}/build" + command: "${GITHUB_WORKSPACE}/resources/examples/testfiles/dtmc/brp-16-2.pm 'P=? [F s=5]'" + - name: Install storm + if: inputs.install + working-directory: ./build + run: sudo make install + - name: Remove build dir + if: inputs.install + run: | + rm -rf ${GITHUB_WORKSPACE}/build + - name: Run installed storm + if: inputs.install + run: | + /usr/local/bin/storm --version + - name: Build starter-project on installed Storm + if: inputs.install + uses: ./.github/actions/starter-project-action + with: + docker: false + stormDir: "" + command: "${GITHUB_WORKSPACE}/resources/examples/testfiles/dtmc/brp-16-2.pm 'P=? [F s=5]'" diff --git a/CMakeLists.txt b/CMakeLists.txt index fd2e73c9ba..b5d278d629 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,6 +156,9 @@ if (STORM_DEVELOPER) set(STORM_DEBUG_SPOT ON) set(STORM_DEBUG_SYLVAN ON) set(STORM_WARNING_AS_ERROR ON) + # Turn off PCH for faster ccache usage on warm caches. PCH compiled files cannot be properly cached currently. + # TODO: remove and explicitly set if needed + set(STORM_COMPILE_WITH_PCH OFF) else() set(STORM_LOG_DISABLE_DEBUG ON) if (NOT CMAKE_BUILD_TYPE) @@ -171,8 +174,15 @@ if(STORM_COMPILE_WITH_CCACHE) mark_as_advanced(CCACHE_FOUND) if(CCACHE_FOUND) message(STATUS "Storm - Using ccache") + # Relax the caching keys + # pch_defines tries to ignore precompiled headers (but often does not succeed in our case) + # the time options ignore time macros when calculating the cache key, improving cache hit rates + set(ENV{CCACHE_SLOPPINESS} "pch_defines,time_macros,include_file_mtime,include_file_ctime") set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) - set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) + + if(STORM_COMPILE_WITH_PCH) + message(STATUS "Storm - PCH is enabled which will lead to significantly lower ccache hit rates. Consider setting STORM_COMPILE_WITH_PCH=OFF if you plan to rebuild Storm multiple times.") + endif() else() message(STATUS "Storm - Could not find ccache.") endif() @@ -321,6 +331,7 @@ SET(STORM_PRECOMPILED_HEADERS "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "") + ############################################################# ## ## Compiler tests during config diff --git a/Dockerfile b/Dockerfile index ec7424abce..9a952be697 100644 --- a/Dockerfile +++ b/Dockerfile @@ -42,16 +42,34 @@ ARG all_sanitizers="OFF" # Specify additional CMake arguments for Storm ARG cmake_args="" +ARG ccache_size="3G" # Build Storm ############# +RUN if ! command -v ccache >/dev/null 2>&1; then \ + if command -v apt-get >/dev/null 2>&1; then \ + apt-get update && apt-get install -y --no-install-recommends ccache && rm -rf /var/lib/apt/lists/*; \ + elif command -v apk >/dev/null 2>&1; then \ + apk add --no-cache ccache; \ + elif command -v pacman >/dev/null 2>&1; then \ + pacman -S --noconfirm ccache; \ + else \ + echo "No supported package manager found for ccache installation"; \ + fi; \ + fi + +ENV CCACHE_DIR=/root/.ccache RUN mkdir /opt/storm WORKDIR /opt/storm # Copy the content of the current local Storm repository into the Docker image COPY . . +# Seed ccache from the workflow cache directory if available. +RUN mkdir -p "$CCACHE_DIR" && \ + if [ -d "/opt/storm/.ci-ccache" ]; then cp -a /opt/storm/.ci-ccache/. "$CCACHE_DIR"/; fi + # Switch to build directory RUN mkdir -p /opt/storm/build WORKDIR /opt/storm/build @@ -80,6 +98,6 @@ RUN cmake -DCMAKE_BUILD_TYPE=$build_type \ # Build Storm # (This can be adapted to only build 'storm' or 'binaries' depending on custom needs) -RUN make -j $no_threads +RUN ccache --max-size=$ccache_size && ccache --zero-stats && make -j $no_threads && ccache --show-stats --verbose WORKDIR /opt/storm diff --git a/resources/3rdparty/include_spot.cmake b/resources/3rdparty/include_spot.cmake index 0ad1989a29..c6f2c85048 100644 --- a/resources/3rdparty/include_spot.cmake +++ b/resources/3rdparty/include_spot.cmake @@ -60,10 +60,13 @@ if(NOT STORM_DISABLE_SPOT) set(SPOT_SHIPPED_VERSION 2.15.1) set(STORM_SPOT_FLAGS "--disable-python;--enable-shared;--disable-static") if (NOT STORM_DEBUG_SPOT) - set(STORM_SPOT_FLAGS "${STORM_SPOT_FLAGS};--disable-devel;--disable-debug;--enable-optimizations") + set(STORM_SPOT_FLAGS "${STORM_SPOT_FLAGS};--disable-devel;--disable-debug;--enable-optimizations") else() - message(WARNING "Storm - Building Spot in DEBUG mode.") - set(STORM_SPOT_FLAGS "${STORM_SPOT_FLAGS};--enable-devel;--enable-debug;--disable-optimizations") + message(WARNING "Storm - Building Spot in DEBUG mode.") + set(STORM_SPOT_FLAGS "${STORM_SPOT_FLAGS};--disable-devel;--enable-debug;--disable-optimizations") + endif() + if (CCACHE_FOUND) + set(STORM_SPOT_FLAGS "${STORM_SPOT_FLAGS};CC=ccache\\ ${CMAKE_C_COMPILER};CXX=ccache\\ ${CMAKE_CXX_COMPILER}") endif() ExternalProject_Add(Spot URL https://www.lre.epita.fr/dload/spot/spot-${SPOT_SHIPPED_VERSION}.tar.gz https://www.lrde.epita.fr/dload/spot/spot-${SPOT_SHIPPED_VERSION}.tar.gz diff --git a/resources/scripts/benchmark-pch-ccache.sh b/resources/scripts/benchmark-pch-ccache.sh new file mode 100755 index 0000000000..8ea6e487d1 --- /dev/null +++ b/resources/scripts/benchmark-pch-ccache.sh @@ -0,0 +1,295 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Benchmark Storm compile time across: +# - PCH enabled/disabled +# - ccache cold/warm +# +# The script uses ccache through CMake compiler launchers and controls PCH via +# CMAKE_DISABLE_PRECOMPILE_HEADERS, so all four combinations are measurable. + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SOURCE_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd)" +BUILD_ROOT="${SOURCE_DIR}/build-bench-pch-ccache" +CCACHE_ROOT="" +BUILD_TYPE="Release" +TARGET="storm" +JOBS="$(command -v nproc >/dev/null 2>&1 && nproc || echo 4)" +GENERATOR="" +EXTRA_CMAKE_ARGS=() +ENABLE_TRACE=0 +NINJATRACING_BIN="" +NINJATRACING_URL="https://raw.githubusercontent.com/nico/ninjatracing/master/ninjatracing" + +usage() { + cat <<'EOF' +Usage: benchmark-pch-ccache.sh [options] + +Options: + --source-dir Storm source directory (default: repo root) + --build-root Directory for benchmark build trees/results + --ccache-root Directory for benchmark ccache data (default: /ccache) + --build-type CMake build type (default: Release) + --target Build target (default: storm) + --jobs Parallel build jobs (default: nproc or 4) + --generator CMake generator (e.g. Ninja) + --cmake-arg Extra CMake argument (can be repeated) + --trace Generate Chrome trace files via ninjatracing + --ninjatracing Path to local ninjatracing script/binary + --help Show this help + +Output: + - Summary table in stdout + - CSV at /results.csv + - Per-run ccache stats in /results/ + - Optional traces at /results/trace--.json +EOF +} + +require_cmd() { + if ! command -v "$1" >/dev/null 2>&1; then + echo "Error: required command '$1' not found" >&2 + exit 1 + fi +} + +extract_stat() { + local label="$1" + local file="$2" + awk -F: -v key="$label" ' + $1 ~ key { + gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2) + gsub(/[[:space:]]/, "", $2) + print $2 + found=1 + exit + } + END { if (!found) print 0 } + ' "$file" +} + +run_case() { + local pch_mode="$1" # on|off + local cache_state="$2" # cold|warm + local namespace="storm-bench-pch-${pch_mode}" + local ccache_dir="${CCACHE_ROOT}/${namespace}" + local enable_pch="ON" + + if [[ "$pch_mode" == "off" ]]; then + enable_pch="OFF" + fi + + local build_dir="${BUILD_ROOT}/build-${pch_mode}" + local result_dir="${BUILD_ROOT}/results" + mkdir -p "$result_dir" + + export CCACHE_DIR="$ccache_dir" + export CCACHE_NAMESPACE="$namespace" + export CCACHE_BASEDIR="$SOURCE_DIR" + export CCACHE_NOHASHDIR="1" + + if [[ "$cache_state" == "cold" ]]; then + rm -rf "$ccache_dir" + rm -rf "$build_dir" + fi + mkdir -p "$ccache_dir" + ccache --zero-stats >/dev/null + + local cmake_cmd=(cmake -S "$SOURCE_DIR" -B "$build_dir" + -DSTORM_COMPILE_WITH_PCH="$enable_pch" + -DCMAKE_BUILD_TYPE="$BUILD_TYPE") + + if [[ -n "$GENERATOR" ]]; then + cmake_cmd+=(-G "$GENERATOR") + fi + + if [[ ${#EXTRA_CMAKE_ARGS[@]} -gt 0 ]]; then + cmake_cmd+=("${EXTRA_CMAKE_ARGS[@]}") + fi + + if [[ "$cache_state" == "cold" || ! -d "$build_dir" ]]; then + echo "[benchmark] Configure: pch=${pch_mode}, cache=${cache_state}" + "${cmake_cmd[@]}" >/dev/null + fi + + if [[ "$cache_state" == "warm" ]]; then + # Rebuild in the same build directory to keep paths stable for ccache. + cmake --build "$build_dir" --target clean -j "$JOBS" >/dev/null || true + fi + + local time_file="${result_dir}/time-${pch_mode}-${cache_state}.txt" + echo "[benchmark] Build: pch=${pch_mode}, cache=${cache_state}" + /usr/bin/time -f "%e" -o "$time_file" \ + cmake --build "$build_dir" --target "$TARGET" -j "$JOBS" >/dev/null + + local stats_file="${result_dir}/ccache-${pch_mode}-${cache_state}.txt" + ccache --show-stats --verbose >"$stats_file" + + if [[ "$ENABLE_TRACE" == "1" ]]; then + local ninja_log="${build_dir}/.ninja_log" + local trace_file="${result_dir}/trace-${pch_mode}-${cache_state}.json" + if [[ ! -f "$ninja_log" ]]; then + echo "Error: ninja log not found at $ninja_log" >&2 + exit 1 + fi + python3 "$NINJATRACING_BIN" "$ninja_log" >"$trace_file" + fi + + local elapsed + elapsed="$(cat "$time_file")" + + local cacheable hits misses uncacheable + cacheable="$(extract_stat "Cacheable calls" "$stats_file")" + hits="$(extract_stat "Hits" "$stats_file")" + misses="$(extract_stat "Misses" "$stats_file")" + uncacheable="$(extract_stat "Uncacheable calls" "$stats_file")" + + local hit_rate="0.00" + if [[ "$cacheable" != "0" ]]; then + hit_rate="$(awk -v h="$hits" -v c="$cacheable" 'BEGIN { printf "%.2f", (100.0*h)/c }')" + fi + + printf "%s,%s,%s,%s,%s,%s,%s\n" \ + "$pch_mode" "$cache_state" "$elapsed" "$cacheable" "$hits" "$misses" "$uncacheable" \ + >>"${BUILD_ROOT}/results.csv" + + printf "%-8s %-6s %10s %12s %10s %10s %12s %9s\n" \ + "$pch_mode" "$cache_state" "$elapsed" "$cacheable" "$hits" "$misses" "$uncacheable" "${hit_rate}%" +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --source-dir) + SOURCE_DIR="$2" + shift 2 + ;; + --build-root) + BUILD_ROOT="$2" + shift 2 + ;; + --ccache-root) + CCACHE_ROOT="$2" + shift 2 + ;; + --build-type) + BUILD_TYPE="$2" + shift 2 + ;; + --target) + TARGET="$2" + shift 2 + ;; + --jobs) + JOBS="$2" + shift 2 + ;; + --generator) + GENERATOR="$2" + shift 2 + ;; + --cmake-arg) + EXTRA_CMAKE_ARGS+=("$2") + shift 2 + ;; + --trace) + ENABLE_TRACE=1 + shift + ;; + --ninjatracing) + NINJATRACING_BIN="$2" + shift 2 + ;; + --help) + usage + exit 0 + ;; + *) + echo "Unknown argument: $1" >&2 + usage + exit 1 + ;; + esac +done + +require_cmd cmake +require_cmd ccache +require_cmd /usr/bin/time + +if [[ "$ENABLE_TRACE" == "1" ]]; then + require_cmd python3 + if [[ -z "$GENERATOR" ]]; then + GENERATOR="Ninja" + fi + if [[ "$GENERATOR" != "Ninja" ]]; then + echo "Error: --trace requires --generator Ninja (or no generator, which defaults to Ninja)." >&2 + exit 1 + fi + require_cmd ninja +fi + +if [[ -z "$CCACHE_ROOT" ]]; then + CCACHE_ROOT="${BUILD_ROOT}/ccache" +fi + +mkdir -p "$BUILD_ROOT" +mkdir -p "$CCACHE_ROOT" +: >"${BUILD_ROOT}/results.csv" +echo "pch,cache_state,build_seconds,cacheable_calls,hits,misses,uncacheable_calls" >>"${BUILD_ROOT}/results.csv" + +if [[ "$ENABLE_TRACE" == "1" ]]; then + if [[ -z "$NINJATRACING_BIN" ]]; then + NINJATRACING_BIN="${BUILD_ROOT}/tools/ninjatracing" + mkdir -p "${BUILD_ROOT}/tools" + if [[ ! -f "$NINJATRACING_BIN" ]]; then + if command -v curl >/dev/null 2>&1; then + curl -fsSL "$NINJATRACING_URL" -o "$NINJATRACING_BIN" + elif command -v wget >/dev/null 2>&1; then + wget -qO "$NINJATRACING_BIN" "$NINJATRACING_URL" + else + echo "Error: neither curl nor wget found; provide --ninjatracing ." >&2 + exit 1 + fi + chmod +x "$NINJATRACING_BIN" + fi + fi +fi + +echo +echo "Benchmark settings" +echo " source-dir: $SOURCE_DIR" +echo " build-root: $BUILD_ROOT" +echo " ccache-root: $CCACHE_ROOT" +echo " build-type: $BUILD_TYPE" +echo " target: $TARGET" +echo " jobs: $JOBS" +if [[ -n "$GENERATOR" ]]; then + echo " generator: $GENERATOR" +fi +if [[ "$ENABLE_TRACE" == "1" ]]; then + echo " trace: enabled" + echo " ninjatrace: $NINJATRACING_BIN" +else + echo " trace: disabled" +fi +if [[ ${#EXTRA_CMAKE_ARGS[@]} -gt 0 ]]; then + echo " extra args: ${EXTRA_CMAKE_ARGS[*]}" +fi + +echo +echo "Results" +printf "%-8s %-6s %10s %12s %10s %10s %12s %9s\n" \ + "pch" "cache" "seconds" "cacheable" "hits" "misses" "uncacheable" "hit-rate" +printf "%-8s %-6s %10s %12s %10s %10s %12s %9s\n" \ + "--------" "------" "----------" "------------" "----------" "----------" "------------" "---------" + +run_case off cold +run_case off warm +run_case on cold +run_case on warm + +echo +echo "CSV written to: ${BUILD_ROOT}/results.csv" +echo "Raw stats in: ${BUILD_ROOT}/results" +if [[ "$ENABLE_TRACE" == "1" ]]; then + echo "Traces in: ${BUILD_ROOT}/results" +fi diff --git a/src/storm-parsers/parser/SpiritParserDefinitions.h b/src/storm-parsers/parser/SpiritParserDefinitions.h index ecf0fccbae..d54ac7d96d 100644 --- a/src/storm-parsers/parser/SpiritParserDefinitions.h +++ b/src/storm-parsers/parser/SpiritParserDefinitions.h @@ -3,6 +3,12 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-W#pragma-messages" +// Boost Spirit's utf8.hpp uses char_traits which Apple libc++ (Xcode 26+) deprecated +#if defined(__clang__) && defined(__apple_build_version__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + // Include boost spirit. #define BOOST_SPIRIT_USE_PHOENIX_V3 #define BOOST_SPIRIT_UNICODE diff --git a/src/storm/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp b/src/storm/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp index 6b87af50e2..cc6f86e10d 100644 --- a/src/storm/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp +++ b/src/storm/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp @@ -635,6 +635,12 @@ std::unique_ptr SparseDtmcEliminationModelChecker>(result); } +// GCC 15 raises a false positive -Wfree-nonheap-object when compiling SparseDtmcEliminationModelChecker +// with GMP rational functions (STORM_USE_CLN_RF=OFF) in Release mode: the inlined std::vector destructor +// for MatrixEntry<..., RationalFunction<..., GMP>> is incorrectly flagged. Not a real memory error. +// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108846 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfree-nonheap-object" template std::unique_ptr SparseDtmcEliminationModelChecker::computeConditionalProbabilities( Environment const& env, CheckTask const& checkTask) { @@ -875,6 +881,7 @@ void SparseDtmcEliminationModelChecker::performPrioritizedS #endif } } +#pragma GCC diagnostic pop template void SparseDtmcEliminationModelChecker::performOrdinaryStateElimination(