Create selection on device in metatensor-core #3550
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Coverage | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| # Check all PR | |
| concurrency: | |
| group: coverage-${{ github.ref }} | |
| cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} | |
| jobs: | |
| coverage: | |
| runs-on: ubuntu-24.04 | |
| name: collect code coverage | |
| # Adapted from https://www.scivision.dev/github-actions-latest-llvm-clang-flang/ | |
| strategy: | |
| matrix: | |
| llvm-version: [20] | |
| env: | |
| CMAKE_C_COMPILER: clang-${{ matrix.llvm-version }} | |
| CMAKE_CXX_COMPILER: clang++-${{ matrix.llvm-version }} | |
| CC: clang-${{ matrix.llvm-version }} | |
| CXX: clang++-${{ matrix.llvm-version }} | |
| LLVM_COV: llvm-cov-${{ matrix.llvm-version }} | |
| LLVM_PROFDATA: llvm-profdata-${{ matrix.llvm-version }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: setup LLVM | |
| run: | | |
| wget https://apt.llvm.org/llvm.sh | |
| chmod +x llvm.sh | |
| sudo ./llvm.sh ${{ matrix.llvm-version }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| with: | |
| python-version: "3.14" | |
| enable-cache: true | |
| activate-environment: true | |
| - name: Install Rust toolchain | |
| uses: actions-rs/toolchain@v1 | |
| with: | |
| toolchain: stable | |
| components: llvm-tools-preview | |
| override: true | |
| - name: install cargo-llvm-cov | |
| uses: taiki-e/install-action@cargo-llvm-cov | |
| - name: install python dependencies | |
| run: | | |
| uv tool install tox --with tox-uv | |
| uv pip install coverage | |
| - name: cache tox environments | |
| uses: actions/cache@v5 | |
| with: | |
| path: .tox | |
| key: tox-${{ hashFiles('pyproject.toml', 'setup.cfg', 'tox.ini') }} | |
| - name: Cache Rust dependencies | |
| uses: Leafwing-Studios/cargo-cache@v2.6.1 | |
| with: | |
| sweep-cache: true | |
| # sccache is intentionally NOT used for the coverage job: cached objects | |
| # carry instrumentation hashes from a previous build that don't match | |
| # the profraw collected in this run, causing llvm-cov to discard | |
| # coverage for hundreds of functions ("N functions have mismatched data") | |
| # and report exercised code paths as uncovered. | |
| # Build the instrumented Rust workspace and run Rust + C++ tests via | |
| # cargo-llvm-cov. This produces an instrumented libmetatensor.so installed | |
| # at target/llvm-cov-target/tmp/cxx-install/deps/metatensor-core/usr/. | |
| # Use --no-report so we can merge in Python-side profraw before reporting. | |
| # Exclude metatensor-python: its run_python_tests integration test shells | |
| # out to `tox`, which builds and caches a metatensor-core wheel in | |
| # .tox/build-metatensor-core/tmp/dist/ BEFORE the next step sets | |
| # METATENSOR_CORE_PYTHON_USE_EXTERNAL_LIB=ON. That cached wheel then bundles | |
| # an uninstrumented libmetatensor.so, so the later "collect Python coverage" | |
| # step reinstalls it and no python-*.profraw is produced. | |
| - name: build and run Rust tests with coverage | |
| run: | | |
| cargo llvm-cov --all-features --workspace --exclude metatensor-python \ | |
| --no-fail-fast --no-report --include-ffi | |
| env: | |
| # PIP_EXTRA_INDEX_URL is read by tox.ini and converted to UV_EXTRA_INDEX_URL | |
| # UV_EXTRA_INDEX_URL is used directly by uv in Rust integration tests | |
| PIP_EXTRA_INDEX_URL: https://download.pytorch.org/whl/cpu | |
| UV_EXTRA_INDEX_URL: https://download.pytorch.org/whl/cpu | |
| UV_INDEX_STRATEGY: unsafe-best-match | |
| - name: locate cargo-llvm-cov environment | |
| id: covenv | |
| run: | | |
| # Extract the LLVM instrumentation environment configured by cargo-llvm-cov. | |
| # We require these variables to manually link the subsequent Python test | |
| # executions to the Rust coverage reporting pipeline. | |
| # Basically harmonizes setup between Rust and the rest of the coverage pipeline. | |
| # see https://github.com/taiki-e/cargo-llvm-cov/issues/320 | |
| # or later | |
| # https://github.com/near/nearcore/pull/10180/changes | |
| # for another approach. | |
| eval "$(cargo llvm-cov show-env --export-prefix)" | |
| # show-env prints LLVM_PROFILE_FILE as target/metatensor-%p-%32m.profraw | |
| # but cargo-llvm-cov stores its profraw in target/llvm-cov-target/. | |
| # Redirect Python profraw there so cargo llvm-cov report merges them. | |
| PYTHON_PROFILE_FILE="${{ github.workspace }}/target/llvm-cov-target/python-%p-%32m.profraw" | |
| echo "LLVM_PROFILE_FILE=$PYTHON_PROFILE_FILE" >> $GITHUB_ENV | |
| echo "MTS_INSTRUMENTED_PREFIX=${{ github.workspace }}/target/llvm-cov-target/tmp/cxx-install/deps/metatensor-core/usr" >> $GITHUB_ENV | |
| # Run Python tests with the INSTRUMENTED metatensor-core library so | |
| # profraw files capturing Python -> Rust C API coverage land in | |
| # cargo-llvm-cov's directory and get merged into rust_codecov.json below. | |
| # Without this, all the Rust code that Python tests exercise (a huge | |
| # fraction of the codebase) is invisible to the Rust coverage report. | |
| - name: collect Python coverage with instrumented library | |
| run: | | |
| tox run \ | |
| -e core-tests,operations-numpy-tests,operations-torch-tests,learn-numpy-tests,learn-torch-tests,torch-tests | |
| env: | |
| PIP_EXTRA_INDEX_URL: https://download.pytorch.org/whl/cpu | |
| UV_INDEX_STRATEGY: unsafe-best-match | |
| CMAKE_PREFIX_PATH: ${{ env.MTS_INSTRUMENTED_PREFIX }} | |
| METATENSOR_CORE_PYTHON_USE_EXTERNAL_LIB: "ON" | |
| - name: verify Python tests used instrumented library | |
| run: | | |
| # Diagnostic: confirm the installed metatensor-core package points | |
| # at the instrumented .so via _external.py, and that python-*.profraw | |
| # was produced by the Python test runs. | |
| echo "=== _external.py in each test env ===" | |
| find .tox -name '_external.py' -path '*/site-packages/metatensor/*' -print -exec cat {} \; | |
| echo "=== python-*.profraw files ===" | |
| ls -la target/llvm-cov-target/python-*.profraw 2>&1 | head -20 | |
| echo "=== all profraw count ===" | |
| find target/llvm-cov-target -maxdepth 1 -name '*.profraw' | wc -l | |
| - name: combine coverage files | |
| run: | | |
| coverage combine .tox/*/.coverage | |
| coverage xml | |
| - name: generate rust code coverage report | |
| id: coverage | |
| run: | | |
| cargo llvm-cov report --codecov \ | |
| --include-ffi \ | |
| --output-path rust_codecov.json | |
| # cargo llvm-cov report --codecov above only sees objects in the cargo | |
| # target tree. It ignores two cmake-built artefact sets: | |
| # - C++ test binaries under tmp/{cxx-tests,torch-tests}/ that cover | |
| # metatensor/*.hpp | |
| # - libmetatensor.so at tmp/cxx-install/ that Python tests load; its | |
| # counter IDs differ from the workspace .so, logged as | |
| # "N functions have mismatched data" | |
| # Merge all profraw once and run llvm-cov export with the cmake-side | |
| # objects to recover both. Codecov merges by file+line so the resulting | |
| # lcov augments rust_codecov.json. | |
| - name: export cmake-built coverage (C++ tests + Python-exercised Rust) | |
| run: | | |
| target_dir="${{ github.workspace }}/target/llvm-cov-target" | |
| mapfile -t profraw < <(find "$target_dir" -maxdepth 1 -name '*.profraw' -type f | sort) | |
| if [[ ${#profraw[@]} -eq 0 ]]; then | |
| echo "::warning::No profraw files found" | |
| : > cmake_coverage.lcov; exit 0 | |
| fi | |
| # --failure-mode=warn skips profraw from a different LLVM version | |
| # (e.g. system clang vs Rust's bundled LLVM) instead of aborting. | |
| "$LLVM_PROFDATA" merge --failure-mode=warn -sparse \ | |
| "${profraw[@]}" -o cmake.profdata | |
| # Test executables + the instrumented libmetatensor.so. Third-party | |
| # .so (libtorch etc.) under deps/ are excluded to keep llvm-cov | |
| # from complaining about objects it can't map. | |
| mapfile -t objects < <({ | |
| find "$target_dir/tmp" \ | |
| \( -path '*/cxx-tests/*' -o -path '*/torch-tests/*' \) \ | |
| -maxdepth 3 -executable -type f \ | |
| ! -path '*/CMakeFiles/*' ! -path '*/deps/*' \ | |
| ! -name '*.so' ! -name '*.dylib' ! -name '*.a' ! -name '*.o' | |
| find "$target_dir/tmp/cxx-install" -name 'libmetatensor.so' -type f 2>/dev/null | |
| } | sort -u) | |
| if [[ ${#objects[@]} -eq 0 ]]; then | |
| echo "::warning::No cmake-built objects found" | |
| : > cmake_coverage.lcov; exit 0 | |
| fi | |
| echo "Merging ${#profraw[@]} profraw files against ${#objects[@]} objects" | |
| args=( | |
| export -format=lcov | |
| -instr-profile cmake.profdata | |
| -ignore-filename-regex '(\.cargo/registry|/rustc/|/usr/include|metatensor-core/tests/|metatensor-torch/tests/|tests/cpp/external|/llvm-cov-target/tmp/)' | |
| "${objects[0]}" | |
| ) | |
| for obj in "${objects[@]:1}"; do args+=(-object "$obj"); done | |
| "$LLVM_COV" "${args[@]}" > cmake_coverage.lcov | |
| echo "Wrote $(wc -l < cmake_coverage.lcov) lines" | |
| - name: upload coverage artifacts | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: coverage-reports | |
| path: | | |
| cmake_coverage.lcov | |
| rust_codecov.json | |
| coverage.xml | |
| - name: upload to codecov.io | |
| uses: codecov/codecov-action@v6 | |
| with: | |
| disable_search: true | |
| fail_ci_if_error: true | |
| files: coverage.xml,rust_codecov.json,cmake_coverage.lcov | |
| token: ${{ secrets.CODECOV_TOKEN }} |