diff --git a/.github/workflows/bench-frontier.yml b/.github/workflows/bench-frontier.yml new file mode 100644 index 0000000000..2a37e75e3d --- /dev/null +++ b/.github/workflows/bench-frontier.yml @@ -0,0 +1,86 @@ +name: 'Benchmark Frontier Releases' + +concurrency: + group: bench-frontier + cancel-in-progress: false + + +on: + push: + pull_request: + workflow_dispatch: + inputs: + tag: + description: 'tag to Benchmark' + required: true + default: 'v5.1.3' + +jobs: + self: + name: "${{ matrix.name }} (${{ matrix.device }}${{ matrix.interface != 'none' && format('-{0}', matrix.interface) || '' }})" + strategy: + fail-fast: false + matrix: + include: + - cluster: frontier + name: Oak Ridge | Frontier (CCE) + group: phoenix + labels: frontier + flag: f + device: gpu + interface: acc + build_script: "bash .github/workflows/frontier/build.sh gpu acc bench" + - cluster: frontier + name: Oak Ridge | Frontier (CCE) + group: phoenix + labels: frontier + flag: f + device: gpu + interface: omp + build_script: "bash .github/workflows/frontier/build.sh gpu omp bench" + runs-on: + group: ${{ matrix.group }} + labels: ${{ matrix.labels }} + timeout-minutes: 480 + env: + ACTIONS_RUNNER_FORCE_ACTIONS_NODE_VERSION: node16 + ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true + BENCH_TAG: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.tag != '' && github.event.inputs.tag || 'v5.1.3' }} + steps: + - name: Clone - PR + uses: actions/checkout@v4 + with: + path: pr + + - name: Clone - Master + uses: actions/checkout@v4 + with: + repository: MFlowCode/MFC + ref: master + path: master + + - name: Checkout PR repo + uses: actions/checkout@v3 + with: + path: pr + + - name: Setup & Build + run: | + (cd master && ${{ matrix.build_script }}) & + wait %1 + + - name: Bench (Master) + run: bash master/.github/scripts/run_parallel_benchmarks.sh ${{ matrix.device }} ${{ matrix.interface }} ${{ matrix.cluster }} + + - name: Print Logs + if: always() + run: | + cat master/bench-${{ matrix.device }}.* 2>/dev/null || true + + - name: Archive Logs (Frontier) + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.cluster }}-${{ matrix.device }} + path: | + master/bench-${{ matrix.device }}.* + master/build/benchmarks/* diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml deleted file mode 100644 index 2ccdfca87a..0000000000 --- a/.github/workflows/bench.yml +++ /dev/null @@ -1,124 +0,0 @@ -name: 'Benchmark' - -on: - pull_request: - pull_request_review: - types: [submitted] - workflow_dispatch: - -jobs: - file-changes: - name: Detect File Changes - runs-on: 'ubuntu-latest' - outputs: - checkall: ${{ steps.changes.outputs.checkall }} - steps: - - name: Clone - uses: actions/checkout@v4 - - - name: Detect Changes - uses: dorny/paths-filter@v3 - id: changes - with: - filters: ".github/file-filter.yml" - - self: - name: "${{ matrix.name }} (${{ matrix.device }}${{ matrix.interface != 'none' && format('-{0}', matrix.interface) || '' }})" - if: ${{ github.repository=='MFlowCode/MFC' && needs.file-changes.outputs.checkall=='true' && ((github.event_name=='pull_request_review' && github.event.review.state=='approved') || (github.event_name=='pull_request' && (github.event.pull_request.user.login=='sbryngelson' || github.event.pull_request.user.login=='wilfonba'))) }} - needs: file-changes - strategy: - fail-fast: false - matrix: - include: - - cluster: phoenix - name: Georgia Tech | Phoenix (NVHPC) - group: phoenix - labels: gt - flag: p - device: cpu - interface: none - build_script: "" - - cluster: phoenix - name: Georgia Tech | Phoenix (NVHPC) - group: phoenix - labels: gt - flag: p - device: gpu - interface: acc - build_script: "" - - cluster: phoenix - name: Georgia Tech | Phoenix (NVHPC) - group: phoenix - labels: gt - flag: p - device: gpu - interface: omp - build_script: "" - - cluster: frontier - name: Oak Ridge | Frontier (CCE) - group: phoenix - labels: frontier - flag: f - device: gpu - interface: acc - build_script: "bash .github/workflows/frontier/build.sh gpu acc bench" - - cluster: frontier - name: Oak Ridge | Frontier (CCE) - group: phoenix - labels: frontier - flag: f - device: gpu - interface: omp - build_script: "bash .github/workflows/frontier/build.sh gpu omp bench" - runs-on: - group: ${{ matrix.group }} - labels: ${{ matrix.labels }} - timeout-minutes: 480 - env: - ACTIONS_RUNNER_FORCE_ACTIONS_NODE_VERSION: node16 - ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true - steps: - - name: Clone - PR - uses: actions/checkout@v4 - with: - path: pr - - - name: Clone - Master - uses: actions/checkout@v4 - with: - repository: MFlowCode/MFC - ref: master - path: master - - - name: Setup & Build - if: matrix.build_script != '' - run: | - (cd pr && ${{ matrix.build_script }}) & - (cd master && ${{ matrix.build_script }}) & - wait %1 && wait %2 - - - name: Bench (Master v. PR) - run: bash pr/.github/scripts/run_parallel_benchmarks.sh ${{ matrix.device }} ${{ matrix.interface }} ${{ matrix.cluster }} - - - name: Generate & Post Comment - run: | - (cd pr && . ./mfc.sh load -c ${{ matrix.flag }} -m g) - (cd pr && ./mfc.sh bench_diff ../master/bench-${{ matrix.device }}-${{ matrix.interface }}.yaml ../pr/bench-${{ matrix.device }}-${{ matrix.interface }}.yaml) - - - name: Print Logs - if: always() - run: | - cat pr/bench-${{ matrix.device }}-${{ matrix.interface }}.* 2>/dev/null || true - cat master/bench-${{ matrix.device }}-${{ matrix.interface }}.* 2>/dev/null || true - - # All other runners (non-Phoenix) just run without special env - - name: Archive Logs (Frontier) - if: always() && matrix.cluster != 'phoenix' - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.cluster }}-${{ matrix.device }}-${{ matrix.interface }} - path: | - pr/bench-${{ matrix.device }}-${{ matrix.interface }}.* - pr/build/benchmarks/* - master/bench-${{ matrix.device }}-${{ matrix.interface }}.* - master/build/benchmarks/* diff --git a/.github/workflows/cleanliness.yml b/.github/workflows/cleanliness.yml deleted file mode 100644 index b02df12898..0000000000 --- a/.github/workflows/cleanliness.yml +++ /dev/null @@ -1,127 +0,0 @@ -name: Cleanliness - -on: [push, pull_request, workflow_dispatch] - -jobs: - file-changes: - name: Detect File Changes - runs-on: 'ubuntu-latest' - outputs: - checkall: ${{ steps.changes.outputs.checkall }} - steps: - - name: Clone - uses: actions/checkout@v4 - - - name: Detect Changes - uses: dorny/paths-filter@v3 - id: changes - with: - filters: ".github/file-filter.yml" - - cleanliness: - name: Code Cleanliness Check - if: needs.file-changes.outputs.checkall == 'true' - needs: file-changes - runs-on: "ubuntu-latest" - env: - pr_everything: 0 - master_everything: 0 - steps: - - name: Clone - PR - uses: actions/checkout@v4 - with: - path: pr - - name: Clone - Master - uses: actions/checkout@v4 - with: - repository: MFlowCode/MFC - ref: master - path: master - - - name: Setup Ubuntu - run: | - sudo apt update -y - sudo apt install -y tar wget make cmake gcc g++ python3 python3-dev "openmpi-*" libopenmpi-dev libblas-dev liblapack-dev - - - name: Build - run: | - (cd pr && /bin/bash mfc.sh build -j $(nproc) --debug 2> ../pr.txt) - (cd master && /bin/bash mfc.sh build -j $(nproc) --debug 2> ../master.txt) - sed -i '/\/pr\//d' pr.txt - sed -i '/\/master\//d' master.txt - - - name: Unused Variables Diff - continue-on-error: true - run: | - grep -F 'Wunused-variable' master.txt > mUnused.txt - grep -F 'Wunused-variable' pr.txt > prUnused.txt - diff prUnused.txt mUnused.txt - - - name: Unused Dummy Arguments Diff - continue-on-error: true - run: | - grep -F 'Wunused-dummy-argument' pr.txt > prDummy.txt - grep -F 'Wunused-dummy-argument' master.txt > mDummy.txt - diff prDummy.txt mDummy.txt - - - name: Unused Value Diff - continue-on-error: true - run: | - grep -F 'Wunused-value' pr.txt > prUnused_val.txt - grep -F 'Wunused-value' master.txt > mUnused_val.txt - diff prUnused_val.txt mUnused_val.txt - - - name: Maybe Uninitialized Variables Diff - continue-on-error: true - run: | - grep -F 'Wmaybe-uninitialized' pr.txt > prMaybe.txt - grep -F 'Wmaybe-uninitialized' master.txt > mMaybe.txt - diff prMaybe.txt mMaybe.txt - - - - name: Everything Diff - continue-on-error: true - run: | - grep '\-W' pr.txt > pr_every.txt - grep '\-W' master.txt > m_every.txt - diff pr_every.txt m_every.txt - - - name: List of Warnings - run: | - cat pr_every.txt - - - - name: Summary - continue-on-error: true - run: | - pr_variable=$(grep -c -F 'Wunused-variable' pr.txt) - pr_argument=$(grep -c -F 'Wunused-dummy-argument' pr.txt) - pr_value=$(grep -c -F 'Wunused-value' pr.txt) - pr_uninit=$(grep -c -F 'Wmaybe-uninitialized' pr.txt) - pr_everything=$(grep -c '\-W' pr.txt) - - master_variable=$(grep -c -F 'Wunused-variable' master.txt) - master_argument=$(grep -c -F 'Wunused-dummy-argument' master.txt) - master_value=$(grep -c -F 'Wunused-value' master.txt) - master_uninit=$(grep -c -F 'Wmaybe-uninitialized' master.txt) - master_everything=$(grep -c '\-W' master.txt ) - - echo "pr_everything=$pr_everything" >> $GITHUB_ENV - echo "master_everything=$master_everything" >> $GITHUB_ENV - - echo "Difference is how many warnings were added or removed from master to PR." - echo "Negative numbers are better since you are removing warnings." - echo " " - echo "Unused Variable Count: $pr_variable, Difference: $((pr_variable - master_variable))" - echo "Unused Dummy Argument: $pr_argument, Difference: $((pr_argument - master_argument))" - echo "Unused Value: $pr_value, Difference: $((pr_value - master_value))" - echo "Maybe Uninitialized: $pr_uninit, Difference: $((pr_uninit - master_uninit))" - echo "Everything: $pr_everything, Difference: $((pr_everything - master_everything))" - - - - name: Check Differences - if: env.pr_everything > env.master_everything - run: | - echo "Difference between warning count in PR is greater than in master." - - diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml deleted file mode 100644 index ad0ea7a220..0000000000 --- a/.github/workflows/coverage.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: Coverage Check - -on: [push, pull_request, workflow_dispatch] - -jobs: - file-changes: - name: Detect File Changes - runs-on: 'ubuntu-latest' - outputs: - checkall: ${{ steps.changes.outputs.checkall }} - steps: - - name: Clone - uses: actions/checkout@v4 - - - name: Detect Changes - uses: dorny/paths-filter@v3 - id: changes - with: - filters: ".github/file-filter.yml" - - run: - name: Coverage Test on CodeCov - if: needs.file-changes.outputs.checkall == 'true' - needs: file-changes - runs-on: "ubuntu-latest" - steps: - - name: Checkouts - uses: actions/checkout@v4 - - - name: Setup Ubuntu - run: | - sudo apt update -y - sudo apt install -y tar wget make cmake gcc g++ python3 \ - python3-dev "openmpi-*" libopenmpi-dev hdf5-tools \ - libfftw3-dev libhdf5-dev libblas-dev liblapack-dev - - - name: Build - run: /bin/bash mfc.sh build -j $(nproc) --gcov - - - name: Test - run: /bin/bash mfc.sh test -a -j $(nproc) - - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v4 - with: - fail_ci_if_error: false - verbose: true - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - diff --git a/.github/workflows/deploy-tap.yml b/.github/workflows/deploy-tap.yml deleted file mode 100644 index 769cce98aa..0000000000 --- a/.github/workflows/deploy-tap.yml +++ /dev/null @@ -1,120 +0,0 @@ -name: Deploy Homebrew Tap - -on: - # Test formula on PRs (audit only, don't deploy) - pull_request: - branches: [ master ] - paths: - - 'packaging/homebrew/mfc.rb' - - 'packaging/homebrew/README.md' - # Deploy to tap on push to master - push: - branches: [ master, homebrew-new ] - paths: - - 'packaging/homebrew/mfc.rb' - - 'packaging/homebrew/README.md' - tags: - - 'v*.*.*' - # Allow manual trigger for testing - workflow_dispatch: - -permissions: - contents: read - -jobs: - deploy-tap: - name: Audit and deploy formula - runs-on: macos-14 - permissions: - contents: write - pull-requests: write - steps: - - name: Checkout MFC repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Determine event metadata - id: meta - run: | - if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then - VERSION="${GITHUB_REF_NAME#v}" - URL="https://github.com/${{ github.repository }}/archive/refs/tags/v${VERSION}.tar.gz" - else - # Extract URL from current formula to re-audit and sync - URL="$(grep -Eo 'https://github.com/.*/archive/refs/tags/v[0-9]+\.[0-9]+\.[0-9]+\.tar\.gz' packaging/homebrew/mfc.rb | head -n1)" - VERSION="$(echo "${URL}" | sed -E 's/.*v([0-9]+\.[0-9]+\.[0-9]+)\.tar\.gz/\1/')" - fi - SHASUM="$(curl -sL "${URL}" | shasum -a 256 | awk '{print $1}')" - echo "version=${VERSION}" >> $GITHUB_OUTPUT - echo "url=${URL}" >> $GITHUB_OUTPUT - echo "sha256=${SHASUM}" >> $GITHUB_OUTPUT - echo "Event: ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY - echo "Version: ${VERSION}" >> $GITHUB_STEP_SUMMARY - if [[ "${{ github.event_name }}" == "pull_request" ]]; then - echo "Mode: Audit only (PR)" >> $GITHUB_STEP_SUMMARY - else - echo "Mode: Audit and deploy" >> $GITHUB_STEP_SUMMARY - fi - - - name: Update formula (for tag events) - if: github.ref_type == 'tag' - run: | - /usr/bin/sed -i '' "s@^ url \".*\"@ url \"${{ steps.meta.outputs.url }}\"@" packaging/homebrew/mfc.rb - /usr/bin/sed -i '' "s@^ sha256 \".*\"@ sha256 \"${{ steps.meta.outputs.sha256 }}\"@" packaging/homebrew/mfc.rb - - - name: Setup Homebrew - uses: Homebrew/actions/setup-homebrew@master - - - name: Audit/style formula before pushing - run: | - brew style packaging/homebrew/mfc.rb - # Create temporary tap to audit the formula - brew tap-new mfc/local - cp packaging/homebrew/mfc.rb "$(brew --repository)/Library/Taps/mfc/homebrew-local/Formula/mfc.rb" - brew audit --online --strict --new --except=homepage mfc/local/mfc || brew audit --online mfc/local/mfc - brew untap mfc/local - - - name: Clone or bootstrap tap repository - if: github.event_name != 'pull_request' - env: - TAP_TOKEN: ${{ secrets.TAP_REPO_TOKEN }} - run: | - set -euo pipefail - REPO="https://x-access-token:${TAP_TOKEN}@github.com/MFlowCode/homebrew-mfc.git" - if git ls-remote "${REPO}" HEAD >/dev/null 2>&1; then - git clone "${REPO}" tap-repo - else - # Repo exists but might be empty; fall back to bootstrap - mkdir -p tap-repo - cd tap-repo - git init -b main - git remote add origin "${REPO}" - touch .keep - git add .keep - git -c user.name="github-actions[bot]" -c user.email="github-actions[bot]@users.noreply.github.com" commit -m "Initialize tap" - git push -u origin main - fi - - - name: Copy formula and README into tap - if: github.event_name != 'pull_request' - run: | - mkdir -p tap-repo/Formula - cp packaging/homebrew/mfc.rb tap-repo/Formula/mfc.rb - cp packaging/homebrew/README.md tap-repo/README.md - - - name: Commit & push if changed - if: github.event_name != 'pull_request' - env: - TAP_TOKEN: ${{ secrets.TAP_REPO_TOKEN }} - run: | - cd tap-repo - git add Formula/mfc.rb README.md - if git diff --cached --quiet; then - echo "No changes in Formula/mfc.rb or README.md; skipping push." - exit 0 - fi - git -c user.name="github-actions[bot]" -c user.email="github-actions[bot]@users.noreply.github.com" \ - commit -m "mfc: v${{ steps.meta.outputs.version }}" - git push origin HEAD:main - diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml deleted file mode 100644 index b12c6cdc5f..0000000000 --- a/.github/workflows/docker.yml +++ /dev/null @@ -1,132 +0,0 @@ -name: Containerization - -on: - release: - types: [published] - workflow_dispatch: - inputs: - tag: - description: 'tag to containerize' - required: true - -concurrency: - group: Containerization - cancel-in-progress: false - -jobs: - Container: - strategy: - matrix: - config: - - { name: 'cpu', runner: 'ubuntu-22.04', base_image: 'ubuntu:22.04' } - - { name: 'gpu', runner: 'ubuntu-22.04', base_image: 'nvcr.io/nvidia/nvhpc:23.11-devel-cuda_multi-ubuntu22.04' } - - { name: 'gpu', runner: 'ubuntu-22.04-arm', base_image: 'nvcr.io/nvidia/nvhpc:23.11-devel-cuda_multi-ubuntu22.04' } - runs-on: ${{ matrix.config.runner }} - outputs: - tag: ${{ steps.clone.outputs.tag }} - steps: - - name: Free Disk Space - uses: jlumbroso/free-disk-space@main - with: - tool-cache: false - android: true - dotnet: true - haskell: true - large-packages: true - docker-images: true - swap-storage: true - - - name: Login - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} - - - name: Setup Buildx - uses: docker/setup-buildx-action@v3 - - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 - - - name: Clone - id: clone - run: | - TAG="${{ github.event.inputs.tag || github.ref_name }}" - echo "tag=$TAG" >> $GITHUB_OUTPUT - echo "TAG=$TAG" >> $GITHUB_ENV - git clone --branch "$TAG" --depth 1 https://github.com/MFlowCode/MFC.git mfc - - - name: Stage - run: | - sudo fallocate -l 8G /swapfile - sudo chmod 600 /swapfile - sudo mkswap /swapfile - sudo swapon /swapfile - sudo mkdir -p /home/runner/tmp - export TMPDIR=/home/runner/tmp - free -h - sudo mkdir -p /mnt/share - sudo chmod 777 /mnt/share - cp -r mfc/* /mnt/share/ - cp -r mfc/.git /mnt/share/.git - cp mfc/.github/Dockerfile /mnt/share/ - cp mfc/.github/.dockerignore /mnt/share/ - docker buildx create --name mfcbuilder --driver docker-container --use - - - name: Build and push image (cpu) - if: ${{ matrix.config.name == 'cpu' }} - uses: docker/build-push-action@v6 - with: - builder: mfcbuilder - context: /mnt/share - file: /mnt/share/Dockerfile - platforms: linux/amd64,linux/arm64 - build-args: | - BASE_IMAGE=${{ matrix.config.base_image }} - TARGET=${{ matrix.config.name }} - CC_COMPILER=${{ 'gcc' }} - CXX_COMPILER=${{ 'g++' }} - FC_COMPILER=${{ 'gfortran' }} - COMPILER_PATH=${{ '/usr/bin' }} - COMPILER_LD_LIBRARY_PATH=${{ '/usr/lib' }} - tags: ${{ secrets.DOCKERHUB_USERNAME }}/mfc:${{ env.TAG }}-${{ matrix.config.name }} - push: true - - - name: Build and push image (gpu) - if: ${{ matrix.config.name == 'gpu' }} - uses: docker/build-push-action@v5 - with: - builder: default - context: /mnt/share - file: /mnt/share/Dockerfile - build-args: | - BASE_IMAGE=${{ matrix.config.base_image }} - TARGET=${{ matrix.config.name }} - CC_COMPILER=${{ 'nvc' }} - CXX_COMPILER=${{ 'nvc++' }} - FC_COMPILER=${{ 'nvfortran' }} - COMPILER_PATH=${{ '/opt/nvidia/hpc_sdk/Linux_x86_64/compilers/bin' }} - COMPILER_LD_LIBRARY_PATH=${{ '/opt/nvidia/hpc_sdk/Linux_x86_64/compilers/lib' }} - tags: ${{ secrets.DOCKERHUB_USERNAME }}/mfc:${{ env.TAG }}-${{ matrix.config.name }}-${{ matrix.config.runner}} - push: true - - manifests: - runs-on: ubuntu-latest - needs: Container - steps: - - name: Login - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} - - - name: Create and Push Manifest Lists - env: - TAG: ${{ needs.Container.outputs.tag }} - REGISTRY: ${{ secrets.DOCKERHUB_USERNAME }}/mfc - run: | - docker buildx imagetools create -t $REGISTRY:latest-cpu $REGISTRY:$TAG-cpu - docker manifest create $REGISTRY:$TAG-gpu $REGISTRY:$TAG-gpu-ubuntu-22.04 $REGISTRY:$TAG-gpu-ubuntu-22.04-arm - docker manifest create $REGISTRY:latest-gpu $REGISTRY:$TAG-gpu-ubuntu-22.04 $REGISTRY:$TAG-gpu-ubuntu-22.04-arm - docker manifest push $REGISTRY:$TAG-gpu - docker manifest push $REGISTRY:latest-gpu \ No newline at end of file diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index 3613c38b10..0000000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,84 +0,0 @@ -name: Documentation - -on: - schedule: - - cron: '0 0 * * *' # This runs every day at midnight UTC - workflow_dispatch: - push: - pull_request: - -jobs: - docs: - name: Build & Publish - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - # We build doxygen from source because of - # https://github.com/doxygen/doxygen/issues/9016 - - name: Build Doxygen - run: | - sudo apt update -y - sudo apt install -y cmake ninja-build graphviz graphviz - git clone https://github.com/doxygen/doxygen.git ../doxygen - cd ../doxygen - git checkout 26b5403 - cd - - cmake -S ../doxygen -B ../doxygen/build -G Ninja - sudo ninja -C ../doxygen/build install - - - name: Build Documentation - run: | - pip3 install fypp - cmake -S . -B build -G Ninja --install-prefix=$(pwd)/build/install -D MFC_DOCUMENTATION=ON - ninja -C build install - - - name: Upload Built Documentation Artifact - uses: actions/upload-artifact@v4 - with: - name: mfc-docs - path: build/install/docs/mfc - if-no-files-found: error - retention-days: 7 - - # From here https://github.com/cicirello/generate-sitemap - - name: Generate the sitemap - id: sitemap - uses: cicirello/generate-sitemap@v1 - with: - base-url-path: https://mflowcode.github.io/ - path-to-root: build/install/docs/mfc - include-pdf: false - sitemap-format: txt - - - name: Output stats - run: | - echo "sitemap-path = ${{ steps.sitemap.outputs.sitemap-path }}" - echo "url-count = ${{ steps.sitemap.outputs.url-count }}" - echo "excluded-count = ${{ steps.sitemap.outputs.excluded-count }}" - - - name: Linkcheck - Lychee - uses: lycheeverse/lychee-action@v2 - with: - args: -c .lychee.toml build/install/docs/mfc/ - fail: false - - - name: Publish Documentation - if: github.repository == 'MFlowCode/MFC' && github.ref == 'refs/heads/master' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' ) - run: | - set +e - git ls-remote "${{ secrets.DOC_PUSH_URL }}" -q - if [ "$?" -ne "0" ]; then exit 0; fi - set -e - git config --global user.name 'MFC Action' - git config --global user.email '<>' - git clone "${{ secrets.DOC_PUSH_URL }}" ../www - rm -rf ../www/* - mv build/install/docs/mfc/* ../www/ - git -C ../www add -A - git -C ../www commit -m "Docs @ ${GITHUB_SHA::7}" || true - git -C ../www push - -# DOC_PUSH_URL should be of the format: -# --> https://:@github.com// diff --git a/.github/workflows/formatting.yml b/.github/workflows/formatting.yml deleted file mode 100644 index 16043daa95..0000000000 --- a/.github/workflows/formatting.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Pretty - -on: [push, pull_request, workflow_dispatch] - -jobs: - docs: - name: Formatting - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: MFC Python setup - run: ./mfc.sh init - - - name: Check formatting - run: | - ./mfc.sh format -j $(nproc) - git diff --exit-code diff --git a/.github/workflows/homebrew.yml b/.github/workflows/homebrew.yml deleted file mode 100644 index d7eced2952..0000000000 --- a/.github/workflows/homebrew.yml +++ /dev/null @@ -1,259 +0,0 @@ -name: Homebrew Formula Test - -on: - push: - paths: - - 'packaging/homebrew/**' - - '.github/workflows/homebrew.yml' - pull_request: - paths: - - 'packaging/homebrew/**' - - '.github/workflows/homebrew.yml' - workflow_dispatch: - -jobs: - # Fast smoke tests that run before expensive operations - smoke-test: - name: Quick Formula Validation - runs-on: ubuntu-latest # Use Linux for speed (Homebrew works on Linux too) - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Homebrew - uses: Homebrew/actions/setup-homebrew@master - - - name: Validate formula syntax with brew style - run: | - echo "Checking formula syntax..." - brew style packaging/homebrew/mfc.rb - - - name: Run brew audit (without installation) - run: | - echo "Configuring git for brew tap-new..." - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - - echo "Creating temporary local tap..." - brew tap-new mflowcode/test - cp packaging/homebrew/mfc.rb $(brew --repository)/Library/Taps/mflowcode/homebrew-test/Formula/mfc.rb - - echo "Running brew audit (online checks)..." - brew audit --online --skip-style mflowcode/test/mfc || true - - echo "Cleaning up tap..." - brew untap mflowcode/test - - - name: Validate Ruby syntax - run: | - echo "Checking Ruby syntax..." - ruby -c packaging/homebrew/mfc.rb - - - name: Check for common formula issues - run: | - echo "Checking for common issues..." - - # Check that required fields are present - grep -q 'desc "' packaging/homebrew/mfc.rb || (echo "❌ Missing desc"; exit 1) - grep -q 'homepage "' packaging/homebrew/mfc.rb || (echo "❌ Missing homepage"; exit 1) - grep -q 'url "' packaging/homebrew/mfc.rb || (echo "❌ Missing url"; exit 1) - grep -q 'sha256 "' packaging/homebrew/mfc.rb || (echo "❌ Missing sha256"; exit 1) - grep -q 'license "' packaging/homebrew/mfc.rb || (echo "❌ Missing license"; exit 1) - - # Check that install method exists - grep -q 'def install' packaging/homebrew/mfc.rb || (echo "❌ Missing install method"; exit 1) - - # Check that test block exists - grep -q 'test do' packaging/homebrew/mfc.rb || (echo "❌ Missing test block"; exit 1) - - echo "✅ All required formula components present" - - - name: Verify URL is reachable - run: | - echo "Checking that source URL is reachable..." - URL=$(grep -E 'url "https://[^"]+' packaging/homebrew/mfc.rb | head -1 | sed 's/.*url "\([^"]*\)".*/\1/') - - if [ -z "$URL" ]; then - echo "❌ Could not extract URL from formula" - exit 1 - fi - - echo "URL: $URL" - HTTP_CODE=$(curl -sI -w "%{http_code}" -o /dev/null "$URL") - - if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "302" ]; then - echo "✅ URL is reachable (HTTP $HTTP_CODE)" - else - echo "⚠️ URL returned HTTP $HTTP_CODE (may indicate an issue)" - # Don't fail here - could be a temporary issue - fi - - - name: Verify SHA256 checksum - run: | - echo "Verifying SHA256 checksum matches URL..." - URL=$(grep -E 'url "https://[^"]+' packaging/homebrew/mfc.rb | head -1 | sed 's/.*url "\([^"]*\)".*/\1/') - EXPECTED_SHA=$(grep 'sha256 "' packaging/homebrew/mfc.rb | head -1 | sed 's/.*sha256 "\([^"]*\)".*/\1/') - - if [ -z "$URL" ] || [ -z "$EXPECTED_SHA" ]; then - echo "❌ Could not extract URL or SHA256 from formula" - exit 1 - fi - - echo "Downloading tarball to compute checksum..." - ACTUAL_SHA=$(curl -sL "$URL" | shasum -a 256 | awk '{print $1}') - - echo "Expected SHA256: $EXPECTED_SHA" - echo "Actual SHA256: $ACTUAL_SHA" - - if [ "$EXPECTED_SHA" = "$ACTUAL_SHA" ]; then - echo "✅ SHA256 checksum matches!" - else - echo "❌ SHA256 mismatch!" - exit 1 - fi - - # Full installation test (only runs if smoke tests pass) - test-formula: - name: Full Installation Test - needs: smoke-test # Only run after smoke tests pass - runs-on: macos-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Homebrew - run: | - echo "Homebrew version:" - brew --version - echo "Updating Homebrew..." - brew update - - - name: Install formula dependencies - run: | - echo "Installing MFC dependencies..." - brew install cmake gcc python@3.12 boost fftw hdf5 open-mpi openblas - - - name: Install MFC from formula - run: | - echo "Creating temporary local tap..." - brew tap-new mflowcode/test - - echo "Copying formula to tap..." - cp packaging/homebrew/mfc.rb $(brew --repository)/Library/Taps/mflowcode/homebrew-test/Formula/mfc.rb - - echo "Installing MFC from local tap..." - # Note: brew may exit with code 1 due to dylib fixup warnings on some Python packages (non-fatal) - # We verify installation using brew commands rather than parsing log output - set +e # Don't fail immediately on error - brew install --build-from-source --verbose mflowcode/test/mfc 2>&1 | tee /tmp/brew-install.log - brew_exit_code=$? - set -e - - # Verify installation using brew list (more robust than log parsing) - if brew list mflowcode/test/mfc &>/dev/null; then - echo "✅ MFC installed successfully (ignoring dylib relocation warnings)" - # Optionally verify with brew info - brew info mflowcode/test/mfc - exit 0 - else - echo "❌ MFC installation failed" - exit $brew_exit_code - fi - - - name: Display error logs on failure - if: failure() - run: | - echo "=== Displaying last 200 lines of brew install log ===" - if [ -f /tmp/brew-install.log ]; then - tail -200 /tmp/brew-install.log - fi - - echo -e "\n=== Displaying Homebrew log files ===" - if [ -d ~/Library/Logs/Homebrew/mfc/ ]; then - for logfile in ~/Library/Logs/Homebrew/mfc/*; do - if [ -f "$logfile" ]; then - echo -e "\n\n====== $logfile ======" - cat "$logfile" - fi - done - fi - - echo -e "\n=== Searching for Cantera config.log ===" - cantera_config_log=$(find /private/tmp -name "config.log" -path "*/mfc--cantera*" 2>/dev/null | head -1) - if [ -n "$cantera_config_log" ] && [ -f "$cantera_config_log" ]; then - echo -e "\n\n====== Cantera config.log ======" - echo "Found at: $cantera_config_log" - cat "$cantera_config_log" - # Copy to a known location for artifact upload - mkdir -p /tmp/cantera-logs - cp "$cantera_config_log" /tmp/cantera-logs/config.log - else - echo "Cantera config.log not found" - echo "Searching in all /private/tmp directories:" - find /private/tmp -name "config.log" 2>/dev/null || echo "No config.log files found" - fi - - - name: Upload Homebrew logs on failure - if: failure() - uses: actions/upload-artifact@v4 - with: - name: homebrew-logs - path: | - /tmp/brew-install.log - /tmp/cantera-logs/ - ~/Library/Logs/Homebrew/mfc/ - if-no-files-found: ignore - - - name: Test MFC installation - run: | - echo "=== Testing MFC Installation ===" - - echo "1. Checking binaries exist and are executable..." - test -f $(brew --prefix)/bin/mfc && test -x $(brew --prefix)/bin/mfc - test -f $(brew --prefix)/bin/pre_process && test -x $(brew --prefix)/bin/pre_process - test -f $(brew --prefix)/bin/simulation && test -x $(brew --prefix)/bin/simulation - test -f $(brew --prefix)/bin/post_process && test -x $(brew --prefix)/bin/post_process - echo " ✓ All binaries exist and are executable" - - echo "2. Verifying installation structure..." - test -f $(brew --prefix mfc)/libexec/mfc.sh - test -d $(brew --prefix mfc)/toolchain - echo " ✓ Installation structure verified" - - echo "3. Checking Python venv..." - test -d $(brew --prefix mfc)/libexec/venv - test -f $(brew --prefix mfc)/libexec/venv/bin/python - test -f $(brew --prefix mfc)/libexec/venv/bin/pip - echo " ✓ Python venv exists" - - echo "4. Checking examples..." - test -d $(brew --prefix mfc)/examples - test -f $(brew --prefix mfc)/examples/1D_sodshocktube/case.py - echo " ✓ Examples installed" - - echo "5. Testing mfc wrapper..." - mfc --help - echo " ✓ mfc --help succeeded" - - echo "=== All tests passed! ===" - - - name: Run MFC test case - run: | - echo "Running a simple test case (1D Sod shock tube)..." - TESTDIR=$(mktemp -d) - cp $(brew --prefix mfc)/examples/1D_sodshocktube/case.py "$TESTDIR/" - - echo "Running with $(sysctl -n hw.ncpu) processors..." - # Use absolute path and shorthand syntax (mfc auto-detects and prepends 'run') - mfc "$TESTDIR/case.py" -j $(sysctl -n hw.ncpu) - - echo "Test case completed successfully!" - - - name: Uninstall and cleanup - if: always() - run: | - echo "Cleaning up..." - brew uninstall mfc || true - brew cleanup diff --git a/.github/workflows/line-count.yml b/.github/workflows/line-count.yml deleted file mode 100644 index 4cc6014e08..0000000000 --- a/.github/workflows/line-count.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Lines of Code - -on: [push, pull_request, workflow_dispatch] - -jobs: - file-changes: - name: Detect File Changes - runs-on: 'ubuntu-latest' - outputs: - checkall: ${{ steps.changes.outputs.checkall }} - steps: - - name: Clone - uses: actions/checkout@v4 - - - name: Detect Changes - uses: dorny/paths-filter@v3 - id: changes - with: - filters: ".github/file-filter.yml" - - sz: - name: Core MFC Line Difference - if: needs.file-changes.outputs.checkall == 'true' - needs: file-changes - permissions: - contents: read - pull-requests: write - runs-on: ubuntu-latest - steps: - - name: Checkout code from PR branch - uses: actions/checkout@v4 - with: - path: pr - - - name: Checkout code from MFC master - uses: actions/checkout@v4 - with: - repository: ${{ github.event.pull_request.repository }} - ref: ${{ github.event.pull_request.base.ref }} - path: base - # repository: MFlowCode/MFC - # ref: master - # path: base - - - name: Get Line Diff - run: | - BASE="$GITHUB_WORKSPACE/base" - PR="$GITHUB_WORKSPACE/pr" - cd $BASE - export MFC_PR=$PR - pwd - ./mfc.sh init &> tmp.txt - ./mfc.sh count_diff - diff --git a/.github/workflows/lint-source.yml b/.github/workflows/lint-source.yml deleted file mode 100644 index bc35b887ea..0000000000 --- a/.github/workflows/lint-source.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Lint Source - -on: [push, pull_request, workflow_dispatch] - -jobs: - file-changes: - name: Detect File Changes - runs-on: 'ubuntu-latest' - outputs: - checkall: ${{ steps.changes.outputs.checkall }} - steps: - - name: Clone - uses: actions/checkout@v4 - - - name: Detect Changes - uses: dorny/paths-filter@v3 - id: changes - with: - filters: ".github/file-filter.yml" - - lint-source: - name: Lint Source - runs-on: 'ubuntu-latest' - - steps: - - uses: actions/checkout@v4 - - - name: Initialize MFC - run: ./mfc.sh init - - - name: Looking for raw directives - run: | - ! grep -iR '!\$acc\|!\$omp' --exclude="parallel_macros.fpp" --exclude="acc_macros.fpp" --exclude="omp_macros.fpp" --exclude="shared_parallel_macros.fpp" --exclude="syscheck.fpp" ./src/* - - - name: No double precision intrinsics - run: | - ! grep -iR 'double_precision\|dsqrt\|dexp\|dlog\|dble\|dabs\|double\ precision\|real(8)\|real(4)\|dprod\|dmin\|dmax\|dfloat\|dreal\|dcos\|dsin\|dtan\|dsign\|dtanh\|dsinh\|dcosh\|d0' --exclude-dir=syscheck --exclude="*nvtx*" --exclude="*precision_select*" ./src/* - - - name: Looking for junk code - run: | - ! grep -iR -e '\.\.\.' -e '\-\-\-' -e '===' ./src/* - - - name: Looking for false integers - run: | - ! grep -onRP '(?/g - s/\[[[:space:]]*/=[[:space:]]*/>/g - s/[[:space:]]*<[[:space:]]*/[[:space:]]*/>/g - s/[[:space:]]*==[[:space:]]*/==/g - - # Remove full-line comments - /^\s*!/d - /^[cC*dD]/d - /^[ \t]*[cC*dD]/d - /^[[:space:]]*$/d - - # Remove end-of-line comments, preserving quoted strings - s/([^"'\''\\]*("[^"]*")?('\''[^'\'']*'\''?)?[^"'\''\\]*)[!].*$/\1/ - ' "$file" > "$TMP_FILE" - - if cmp -s "$file" "$TMP_FILE"; then - rm "$TMP_FILE" - else - # Overwrite the original file with the processed content - mv "$TMP_FILE" "$file" - fi - done - - "${PMD_HOME}/bin/pmd" cpd \ - --dir src \ - --language fortran \ - --minimum-tokens=20 \ - --no-fail-on-violation \ - --no-fail-on-error diff --git a/.github/workflows/spelling.yml b/.github/workflows/spelling.yml deleted file mode 100644 index accdc96288..0000000000 --- a/.github/workflows/spelling.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Spell Check - -on: [push, pull_request, workflow_dispatch] - -jobs: - run: - name: Spell Check - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: MFC Python Setup - run: ./mfc.sh init - - - name: Spell Check - run: ./mfc.sh spelling diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 251b276ace..0000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,162 +0,0 @@ -name: 'Test Suite' - -on: [push, pull_request, workflow_dispatch] - -jobs: - file-changes: - name: Detect File Changes - runs-on: 'ubuntu-latest' - outputs: - checkall: ${{ steps.changes.outputs.checkall }} - steps: - - name: Clone - uses: actions/checkout@v4 - - - name: Detect Changes - uses: dorny/paths-filter@v3 - id: changes - with: - filters: ".github/file-filter.yml" - - github: - name: Github - if: needs.file-changes.outputs.checkall == 'true' - needs: file-changes - strategy: - matrix: - os: ['ubuntu', 'macos'] - mpi: ['mpi'] - precision: [''] - debug: ['debug', 'no-debug'] - intel: [true, false] - exclude: - - os: macos - intel: true - - include: - - os: ubuntu - mpi: no-mpi - precision: single - debug: no-debug - intel: false - - fail-fast: false - continue-on-error: true - runs-on: ${{ matrix.os }}-latest - - steps: - - name: Clone - uses: actions/checkout@v4 - - - name: Setup MacOS - if: matrix.os == 'macos' - run: | - brew update - brew upgrade - brew install coreutils python fftw hdf5 gcc@15 boost open-mpi lapack - echo "FC=gfortran-15" >> $GITHUB_ENV - echo "BOOST_INCLUDE=/opt/homebrew/include/" >> $GITHUB_ENV - - - name: Setup Ubuntu - if: matrix.os == 'ubuntu' && matrix.intel == false - run: | - sudo apt update -y - sudo apt install -y cmake gcc g++ python3 python3-dev hdf5-tools \ - libfftw3-dev libhdf5-dev openmpi-bin libopenmpi-dev \ - libblas-dev liblapack-dev - - - name: Setup Ubuntu (Intel) - if: matrix.os == 'ubuntu' && matrix.intel == true - run: | - wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB - sudo apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB - sudo add-apt-repository "deb https://apt.repos.intel.com/oneapi all main" - sudo apt-get update - sudo apt-get install -y intel-oneapi-compiler-fortran intel-oneapi-mpi intel-oneapi-mpi-devel - source /opt/intel/oneapi/setvars.sh - printenv >> $GITHUB_ENV - - - name: Set up Python 3.14 - uses: actions/setup-python@v5 - with: - python-version: '3.14' - - - name: Build - run: | - /bin/bash mfc.sh test --dry-run -j $(nproc) --${{ matrix.debug }} --${{ matrix.mpi }} --${{ matrix.precision }} - - - name: Test - run: | - /bin/bash mfc.sh test --max-attempts 3 -j $(nproc) $OPT1 $OPT2 - env: - OPT1: ${{ matrix.mpi == 'mpi' && '--test-all' || '' }} - OPT2: ${{ matrix.debug == 'debug' && '-% 20' || '' }} - - self: - name: "${{ matrix.cluster_name }} (${{ matrix.device }}${{ matrix.interface != 'none' && format('-{0}', matrix.interface) || '' }})" - if: github.repository == 'MFlowCode/MFC' && needs.file-changes.outputs.checkall == 'true' - needs: file-changes - continue-on-error: false - timeout-minutes: 480 - strategy: - matrix: - include: - # Phoenix (GT) - - lbl: 'gt' - cluster_name: 'Georgia Tech | Phoenix' - device: 'gpu' - interface: 'acc' - - lbl: 'gt' - cluster_name: 'Georgia Tech | Phoenix' - device: 'gpu' - interface: 'omp' - - lbl: 'gt' - cluster_name: 'Georgia Tech | Phoenix' - device: 'cpu' - interface: 'none' - # Frontier (ORNL) - - lbl: 'frontier' - cluster_name: 'Oak Ridge | Frontier' - device: 'gpu' - interface: 'acc' - - lbl: 'frontier' - cluster_name: 'Oak Ridge | Frontier' - device: 'gpu' - interface: 'omp' - - lbl: 'frontier' - cluster_name: 'Oak Ridge | Frontier' - device: 'cpu' - interface: 'none' - runs-on: - group: phoenix - labels: ${{ matrix.lbl }} - env: - NODE_OPTIONS: ${{ matrix.lbl == 'gt' && '--max-old-space-size=2048' || '' }} - ACTIONS_RUNNER_FORCE_ACTIONS_NODE_VERSION: node16 - ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true - steps: - - name: Clone - uses: actions/checkout@v4 - - - name: Build & Test - if: matrix.lbl == 'gt' - run: bash .github/workflows/phoenix/submit.sh .github/workflows/phoenix/test.sh ${{ matrix.device }} ${{ matrix.interface }} - - - name: Build - if: matrix.lbl == 'frontier' - run: bash .github/workflows/frontier/build.sh ${{ matrix.device }} ${{ matrix.interface }} - - - name: Test - if: matrix.lbl == 'frontier' - run: bash .github/workflows/frontier/submit.sh .github/workflows/frontier/test.sh ${{matrix.device}} ${{ matrix.interface }} - - - name: Print Logs - if: always() - run: cat test-${{ matrix.device }}-${{ matrix.interface }}.out - - - name: Archive Logs - uses: actions/upload-artifact@v4 - if: matrix.lbl == 'frontier' - with: - name: logs-${{ strategy.job-index }}-${{ matrix.device }}-${{ matrix.interface }} - path: test-${{ matrix.device }}-${{ matrix.interface }}.out