diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml deleted file mode 100644 index 63c14ad7ad..0000000000 --- a/.github/workflows/bench.yml +++ /dev/null @@ -1,111 +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 }})" - 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') - ) }} - needs: file-changes - strategy: - fail-fast: false - matrix: - include: - - cluster: phoenix - name: Georgia Tech | Phoenix (NVHPC) - group: phoenix - labels: gt - flag: p - device: cpu - build_script: "" - - cluster: phoenix - name: Georgia Tech | Phoenix (NVHPC) - group: phoenix - labels: gt - flag: p - device: gpu - build_script: "" - - cluster: frontier - name: Oak Ridge | Frontier (CCE) - group: phoenix - labels: frontier - flag: f - device: gpu - build_script: "bash .github/workflows/frontier/build.sh gpu bench" - runs-on: - group: ${{ matrix.group }} - labels: ${{ matrix.labels }} - timeout-minutes: 1400 - 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: | - (cd pr && bash .github/workflows/${{ matrix.cluster }}/submit-bench.sh .github/workflows/${{ matrix.cluster }}/bench.sh ${{ matrix.device }}) & - (cd master && bash .github/workflows/${{ matrix.cluster }}/submit-bench.sh .github/workflows/${{ matrix.cluster }}/bench.sh ${{ matrix.device }}) & - wait %1 && wait %2 - - - 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 }}.yaml ../pr/bench-${{ matrix.device }}.yaml) - - - name: Print Logs - if: always() - run: | - cat pr/bench-${{ matrix.device }}.* 2>/dev/null || true - cat master/bench-${{ matrix.device }}.* 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 }} - path: | - pr/bench-${{ matrix.device }}.* - pr/build/benchmarks/* - master/bench-${{ matrix.device }}.* - master/build/benchmarks/* diff --git a/.github/workflows/cleanliness.yml b/.github/workflows/cleanliness.yml deleted file mode 100644 index ec472dce98..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 - - - 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 7487d8e550..0000000000 --- a/.github/workflows/coverage.yml +++ /dev/null @@ -1,48 +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 - - - 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/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index d161d80342..0000000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,76 +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 - - # 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/frontier/bench.sh b/.github/workflows/frontier/bench.sh deleted file mode 100644 index 31a514d45d..0000000000 --- a/.github/workflows/frontier/bench.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -n_ranks=12 - -if [ "$job_device" = "gpu" ]; then - gpus=$(rocm-smi --showid | awk '{print $1}' | grep -Eo '[0-9]+' | uniq | tr '\n' ' ') - n_ranks=$(echo "$gpus" | wc -w) # number of GPUs on node - gpu_ids=$(echo "$gpus" | tr ' ' '\n' | tr '\n' ' ' | sed 's/ $//') # GPU IDs from rocm-smi - device_opts="--gpu -g $gpu_ids" -fi - -if [ "$job_device" = "gpu" ]; then - ./mfc.sh bench --mem 12 -j $n_ranks -o "$job_slug.yaml" -- -c frontier $device_opts -n $n_ranks -else - ./mfc.sh bench --mem 1 -j $(nproc) -o "$job_slug.yaml" -- -c frontier $device_opts -n $n_ranks -fi diff --git a/.github/workflows/frontier/build.sh b/.github/workflows/frontier/build.sh deleted file mode 100644 index c2e1893427..0000000000 --- a/.github/workflows/frontier/build.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -build_opts="" -if [ "$1" = "gpu" ]; then - build_opts="--gpu" -fi - -. ./mfc.sh load -c f -m g - -if [ "$2" == "bench" ]; then - for dir in benchmarks/*/; do - dirname=$(basename "$dir") - ./mfc.sh run "$dir/case.py" --case-optimization -j 8 --dry-run $build_opts - done -else - ./mfc.sh test --dry-run -j 8 $build_opts -fi diff --git a/.github/workflows/frontier/submit-bench.sh b/.github/workflows/frontier/submit-bench.sh deleted file mode 100644 index 4e498a6090..0000000000 --- a/.github/workflows/frontier/submit-bench.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash - -set -e - -usage() { - echo "Usage: $0 [script.sh] [cpu|gpu]" -} - -if [ ! -z "$1" ]; then - sbatch_script_contents=`cat $1` -else - usage - exit 1 -fi - -if [ "$2" = "cpu" ]; then - sbatch_device_opts="\ -#SBATCH -n 32 # Number of cores required" -elif [ "$2" = "gpu" ]; then - sbatch_device_opts="\ -#SBATCH -n 8 # Number of cores required" -else - usage; exit 1 -fi - - -job_slug="`basename "$1" | sed 's/\.sh$//' | sed 's/[^a-zA-Z0-9]/-/g'`-$2" - -sbatch < 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 68c07d6c18..0000000000 --- a/.github/workflows/lint-source.yml +++ /dev/null @@ -1,55 +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: Lint the full source - run: | - source build/venv/bin/activate - find ./src -type f -not -name '*nvtx*' -exec sh -c 'fortitude check "$1" | grep -v E001' _ {} \; - find ./src -type f -not -name '*nvtx*' -exec sh -c 'fortitude check "$1" | grep -v E001' _ {} \; | wc -l | xargs -I{} sh -c '[ {} -gt 0 ] && exit 1 || exit 0' - - - 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 '(?/dev/null 2>&1 || :' EXIT - -# ────────── Poll until SLURM job finishes ────────── -while :; do - # Try sacct first - STATE=$(sacct -j "$JOBID" --format=State --noheader --parsable2 | head -n1) - - # Fallback to squeue if sacct is empty - if [[ -z "$STATE" ]]; then - STATE=$(squeue -j "$JOBID" -h -o "%T" || echo "") - fi - - # If it’s one of SLURM’s terminal states, break immediately - case "$STATE" in - COMPLETED|FAILED|CANCELLED|TIMEOUT) - echo "βœ… SLURM job $JOBID reached terminal state: $STATE" - break - ;; - "") - echo "βœ… SLURM job $JOBID no longer in queue; assuming finished" - break - ;; - *) - echo "⏳ SLURM job $JOBID state: $STATE" - sleep 10 - ;; - esac -done - -# Now retrieve the exit code and exit with it -EXIT_CODE=$(sacct -j "$JOBID" --noheader --format=ExitCode | head -1 | cut -d: -f1) -echo "πŸ”š SLURM job $JOBID exit code: $EXIT_CODE" -exit "$EXIT_CODE" diff --git a/.github/workflows/phoenix/submit.sh b/.github/workflows/phoenix/submit.sh deleted file mode 100644 index 182d7a2532..0000000000 --- a/.github/workflows/phoenix/submit.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -usage() { - echo "Usage: $0 [script.sh] [cpu|gpu]" - exit 1 -} - -[[ $# -eq 2 ]] || usage - -sbatch_script="$1" -device="$2" - -job_slug="`basename "$1" | sed 's/\.sh$//' | sed 's/[^a-zA-Z0-9]/-/g'`-$2" - -# read the body of the user script -sbatch_body=$(<"$sbatch_script") - -# common SBATCH directives -sbatch_common_opts="\ -#SBATCH -J shb-${sbatch_script%%.sh}-$device # job name -#SBATCH --account=gts-sbryngelson3 # account -#SBATCH -N1 # nodes -#SBATCH -t 03:00:00 # walltime -#SBATCH -q embers # QOS -#SBATCH -o $job_slug.out # stdout+stderr -#SBATCH --mem-per-cpu=2G # default mem (overridden below) -" - -# CPU vs GPU overrides -if [[ "$device" == "cpu" ]]; then - sbatch_device_opts="\ -#SBATCH -p cpu-small -#SBATCH --ntasks-per-node=24 -" -elif [[ "$device" == "gpu" ]]; then - sbatch_device_opts="\ -#SBATCH -p gpu-v100,gpu-a100,gpu-h100,gpu-l40s -#SBATCH --ntasks-per-node=4 -#SBATCH -G2 -" -else - usage -fi - -# submit and capture the JobID -JOBID=$(sbatch <<-EOT | awk '{print $4}' - #!/usr/bin/env bash - ${sbatch_common_opts} - ${sbatch_device_opts} - - set -e -x - - cd "\$SLURM_SUBMIT_DIR" - echo "Running in \$(pwd):" - - # load your modules & env - . ./mfc.sh load -c p -m $device - - # user script contents - ${sbatch_body} -EOT -) - -echo "πŸš€ Submitted SLURM job $JOBID" - -# if this wrapper is killed/canceled, make sure SLURM job is cleaned up -trap '[[ -n "${JOBID:-}" ]] && scancel "$JOBID" >/dev/null 2>&1 || :' EXIT - -# ────────── Poll until SLURM job finishes ────────── -while :; do - # Try sacct first - STATE=$(sacct -j "$JOBID" --format=State --noheader --parsable2 | head -n1) - - # Fallback to squeue if sacct is empty - if [[ -z "$STATE" ]]; then - STATE=$(squeue -j "$JOBID" -h -o "%T" || echo "") - fi - - # If it’s one of SLURM’s terminal states, break immediately - case "$STATE" in - COMPLETED|FAILED|CANCELLED|TIMEOUT) - echo "βœ… SLURM job $JOBID reached terminal state: $STATE" - break - ;; - "") - echo "βœ… SLURM job $JOBID no longer in queue; assuming finished" - break - ;; - *) - echo "⏳ SLURM job $JOBID state: $STATE" - sleep 10 - ;; - esac -done - -# Now retrieve the exit code and exit with it -EXIT_CODE=$(sacct -j "$JOBID" --noheader --format=ExitCode | head -1 | cut -d: -f1) -echo "πŸ”š SLURM job $JOBID exit code: $EXIT_CODE" -exit "$EXIT_CODE" diff --git a/.github/workflows/phoenix/test.sh b/.github/workflows/phoenix/test.sh deleted file mode 100644 index 60b9920f51..0000000000 --- a/.github/workflows/phoenix/test.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -tmpbuild=/storage/scratch1/6/sbryngelson3/mytmp_build -currentdir=$tmpbuild/run-$(( RANDOM % 900 )) -mkdir -p $tmpbuild -mkdir -p $currentdir -export TMPDIR=$currentdir - -n_test_threads=8 - -build_opts="" -if [ "$job_device" = "gpu" ]; then - build_opts="--gpu" -fi - -./mfc.sh test --dry-run -j $n_test_threads $build_opts - -if [ "$job_device" = "gpu" ]; then - gpu_count=$(nvidia-smi -L | wc -l) # number of GPUs on node - gpu_ids=$(seq -s ' ' 0 $(($gpu_count-1))) # 0,1,2,...,gpu_count-1 - device_opts="-g $gpu_ids" - n_test_threads=`expr $gpu_count \* 2` -fi - -./mfc.sh test --max-attempts 3 -a -j $n_test_threads $device_opts -- -c phoenix - -sleep 10 -rm -rf "$currentdir" || true - -unset TMPDIR diff --git a/.github/workflows/pmd.yml b/.github/workflows/pmd.yml deleted file mode 100644 index 24361e777c..0000000000 --- a/.github/workflows/pmd.yml +++ /dev/null @@ -1,131 +0,0 @@ -name: Source DRYness - -on: [push, pull_request, workflow_dispatch] - -jobs: - pmd: - name: PMD - runs-on: "ubuntu-latest" - env: - pr_everything: 0 - steps: - - name: Clone - PR - uses: actions/checkout@v4 - - - name: Set up Java - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: '17' - - - name: Run CPD for Fortran - continue-on-error: true - run: | - # Get latest PMD version from GitHub API - PMD_VERSION=$(curl -s https://api.github.com/repos/pmd/pmd/releases/latest | grep '"tag_name":' | cut -d'"' -f4 | sed 's/pmd_releases\///') - echo "Using PMD version: $PMD_VERSION" - - curl -sSL -o pmd.zip \ - "https://github.com/pmd/pmd/releases/download/pmd_releases/${PMD_VERSION}/pmd-dist-${PMD_VERSION}-bin.zip" - unzip -q pmd.zip - PMD_HOME="pmd-bin-${PMD_VERSION}" - - SOURCE_DIR="${1:-src}" - total_files=$(find "$SOURCE_DIR" -type f \( -name "*.f" -o -name "*.f90" -o -name "*.for" -o -name "*.fpp" -o -name "*.F" -o -name "*.F90" \) | wc -l) - processed=0 - - find "$SOURCE_DIR" -type f \( -name "*.f" -o -name "*.f90" -o -name "*.for" -o -name "*.fpp" -o -name "*.F" -o -name "*.F90" \) -print0 | - while IFS= read -r -d $'\0' file; do - processed=$((processed + 1)) - - # Create a temporary file with same permissions as original - TMP_FILE=$(mktemp) - if [ $? -ne 0 ]; then - echo -e "Failed to create temporary file for $file, skipping" - continue - fi - - # Copy permissions from original file - chmod --reference="$file" "$TMP_FILE" - - # More comprehensive sed command to handle different Fortran comment styles: - # 1. Replace lines that are entirely comments with an empty line: - # - Lines starting with '!' (free form comments) - # - Lines starting with 'c', 'C', '*', 'd', 'D' in column 1 (fixed form comments) - # 2. Remove end-of-line comments (anything after '!' that isn't in a string) - # 3. Preserve strings containing '!' characters - sed -E ' - # First handle & continuation style (modern Fortran) - :ampersand_loop - /&[[:space:]]*$/ { - N - s/&[[:space:]]*\n[[:space:]]*(&)?/ /g - tampersand_loop - } - - # Handle fixed-form continuation (column 6 indicator) - :fixed_form_loop - /^[[:space:]]{0,5}[^[:space:]!&]/ { - N - s/\n[[:space:]]{5}[^[:space:]]/ /g - tfixed_form_loop - } - - # Remove any remaining continuation markers - s/&//g - - # Normalize spacing - replace multiple spaces with single space - s/[[:space:]]{2,}/ /g - - # Remove spaces around mathematical operators - s/[[:space:]]*\*[[:space:]]*/*/g - s/[[:space:]]*\+[[:space:]]*/+/g - s/[[:space:]]*-[[:space:]]*/-/g - s/[[:space:]]*\/[[:space:]]*/\//g - s/[[:space:]]*\*\*[[:space:]]*/\*\*/g - - # Remove spaces in common Fortran constructs (array indexing, function calls) - s/\([[:space:]]*([^,)[:space:]]+)[[:space:]]*,/(\1,/g # First argument - s/,[[:space:]]*([^,)[:space:]]+)[[:space:]]*,/,\1,/g # Middle arguments - s/,[[:space:]]*([^,)[:space:]]+)[[:space:]]*\)/,\1)/g # Last argument - s/\([[:space:]]*([^,)[:space:]]+)[[:space:]]*\)/(\1)/g # Single argument - - # Remove spaces around brackets and parentheses - s/\[[[:space:]]*//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 db618bea46..0000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,132 +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 cmake fftw hdf5 gcc@15 boost open-mpi - 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 - - - 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: 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: Self Hosted - if: github.repository == 'MFlowCode/MFC' && needs.file-changes.outputs.checkall == 'true' - needs: file-changes - continue-on-error: false - timeout-minutes: 1400 - strategy: - matrix: - device: ['cpu', 'gpu'] - lbl: ['gt', 'frontier'] - 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 }} - - - name: Build - if: matrix.lbl == 'frontier' - run: bash .github/workflows/frontier/build.sh ${{ matrix.device }} - - - name: Test - if: matrix.lbl == 'frontier' - run: bash .github/workflows/frontier/submit.sh .github/workflows/frontier/test.sh ${{matrix.device}} - - - name: Print Logs - if: always() - run: cat test-${{ matrix.device }}.out - - - name: Archive Logs - uses: actions/upload-artifact@v4 - if: matrix.lbl == 'frontier' - with: - name: logs-${{ strategy.job-index }}-${{ matrix.device }} - path: test-${{ matrix.device }}.out diff --git a/.github/workflows/verrou.yml b/.github/workflows/verrou.yml new file mode 100644 index 0000000000..cae32161ca --- /dev/null +++ b/.github/workflows/verrou.yml @@ -0,0 +1,39 @@ +name: Floating-Point Compliance + +on: [pull_request, push] + +jobs: + Floating-Point_Compliance: + runs-on: ubuntu-latest + steps: + - name: Clone PR + uses: actions/checkout@v4 + + - name: Verrou Setup + run: | + # get recent release of valgrind from GitHub API + VERROU_VERSION=$(curl -s https://api.github.com/repos/edf-hpc/verrou/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")') + VERROU_NUMBER=${VERROU_VERSION#v} + + wget -P pr https://github.com/edf-hpc/verrou/releases/download/${VERROU_VERSION}/valgrind-3.23.0_verrou-${VERROU_NUMBER}.tar.gz + cd pr + tar -xzf valgrind-3.23.0_verrou-${VERROU_NUMBER}.tar.gz + cd valgrind-3.23.0+verrou-${VERROU_NUMBER} + ./autogen.sh + ./configure --prefix=$HOME/.local + make + make install + cd ../.. + rm -rf pr/valgrind-* + + - name: Run Tests + 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 + + valgrind --tool=verrou ./mfc.sh test -a --dry-run + + - name: Check Compliance + run: | + echo "Checking floating point compliance..."