Skip to content

Commit

Permalink
Merge branch 'master' into optional_num_classes
Browse files Browse the repository at this point in the history
  • Loading branch information
Borda authored Jan 6, 2025
2 parents 9d832e4 + f7235c9 commit 255db5f
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 76 deletions.
13 changes: 12 additions & 1 deletion .github/actions/pull-caches/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ inputs:
description: cache restore/dump key
required: false
default: "pypi-packages"
cache-torch-HF:
description: "cache torch and HF"
required: false
default: "true"
cache-references:
description: "cache metrics references"
required: false
default: "false"

runs:
using: "composite"
Expand Down Expand Up @@ -67,6 +75,7 @@ runs:
shell: bash

- name: Cache Torch & HF
if: inputs.cache-torch-HF == 'true' # since the input is string
continue-on-error: true
uses: actions/cache/restore@v3
with:
Expand All @@ -75,6 +84,7 @@ runs:
key: ci-caches

- name: Restored Torch & HF
if: inputs.cache-torch-HF == 'true' # since the input is string
run: |
mkdir -p $CACHES_DIR
pip install -q py-tree
Expand All @@ -83,14 +93,15 @@ runs:

- name: Cache References
# do not use this cache for dispatch and crone, to enable rebuild caches if needed
if: github.event_name != 'workflow_dispatch' && github.event_name != 'schedule'
if: github.event_name != 'workflow_dispatch' && github.event_name != 'schedule' && inputs.cache-references == 'true'
continue-on-error: true
uses: actions/cache/restore@v3
with:
path: tests/_cache-references
key: cache-references

- name: Restored References
if: inputs.cache-references == 'true' # since the input is string
continue-on-error: true
working-directory: tests/
run: |
Expand Down
83 changes: 41 additions & 42 deletions .github/actions/push-caches/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ inputs:
description: location to pull PyTorch from
required: false
default: "https://download.pytorch.org/whl/cpu/torch_stable.html"
cache-artifact-appendix:
description: "unique name or running index"
required: false
default: ""
cache-torch-HF:
description: "cache torch and HF"
required: false
default: "true"
cache-references:
description: "cache metrics references"
required: false
default: "false"

runs:
using: "composite"
Expand All @@ -23,66 +35,50 @@ runs:
shell: bash

- name: Freeze local emv.
if: inputs.cache-artifact-appendix != ''
run: |
pip freeze > requirements.dump
cat requirements.dump
shell: bash

#- name: Filter self pkg
# run: |
# import os
# fp = 'requirements.dump'
# with open(fp) as fopen:
# lines = [ln.strip() for ln in fopen.readlines()]
# lines = [ln.split('+')[0] for ln in lines if '-e ' not in ln]
# with open(fp, 'w') as fwrite:
# fwrite.writelines([ln + os.linesep for ln in lines])
# shell: python

- name: Dump wheels
if: inputs.cache-artifact-appendix != ''
run: |
pip wheel -r requirements/_devel.txt --prefer-binary \
--wheel-dir=.pip-wheels \
--wheel-dir=_pip-wheels \
-f ${{ inputs.torch-url }} -f ${{ inputs.pypi-dir }}
ls -lh .pip-wheels
ls -lh _pip-wheels
shell: bash

- name: Cache pull packages
uses: actions/cache/restore@v3
with:
enableCrossOsArchive: true
path: ${{ inputs.pypi-dir }}
key: ${{ inputs.pypi-key }}

- name: Find diff
id: wheels-diff
- name: Move new packages to staging
if: inputs.cache-artifact-appendix != ''
run: |
import os, glob
wheels = [os.path.basename(p) for p in glob.glob(".pip-wheels/*")]
pkgs = [os.path.basename(p) for p in glob.glob("${{ inputs.pypi-dir }}/*")]
diff = [w for w in wheels if w not in pkgs]
print(diff)
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
print(f'count-new={len(diff)}', file=fh)
shell: python

- run: cp .pip-wheels/* ${{ inputs.pypi-dir }}
if: ${{ steps.wheels-diff.outputs.count-new != 0 }}
mkdir -p _pip-staging
python .github/assistant.py move_new_packages \
--dir-cache="${{ inputs.pypi-dir }}" \
--dir_local="_pip-wheels" \
--dir_staging="_pip-staging"
ls -lh _pip-staging/
# count files in the staging dir
file_count=$(ls -1 "_pip-staging/" | wc -l)
echo "NUM_PACKAGES=$file_count" >> $GITHUB_ENV
shell: bash

- name: Cache push packages
if: ${{ steps.wheels-diff.outputs.count-new != 0 }}
uses: actions/cache/save@v3
- name: Upload new packages
if: inputs.cache-artifact-appendix != '' && env.NUM_PACKAGES != 0
uses: actions/upload-artifact@v4
with:
enableCrossOsArchive: true
path: ${{ inputs.pypi-dir }}
key: ${{ inputs.pypi-key }}
name: ${{ inputs.pypi-key }}-run-${{ inputs.cache-artifact-appendix }}
path: _pip-staging
retention-days: 1

- name: Post Torch & HF
if: inputs.cache-torch-HF == 'true' # since the input is string
run: py-tree $CACHES_DIR
shell: bash

- name: Cache Torch & HF
if: inputs.cache-torch-HF == 'true' # since the input is string
continue-on-error: true
uses: actions/cache/save@v3
with:
Expand All @@ -91,13 +87,16 @@ runs:
key: ci-caches

- name: Cache references
if: inputs.cache-references == 'true' # since the input is string
continue-on-error: true
uses: actions/cache/save@v3
with:
#enableCrossOsArchive: true
path: tests/_cache-references
key: cache-references

- name: Post References
run: py-tree tests/_cache-references/ --show_hidden
shell: bash
#- name: Post References
# # This print taken soo many lines, so it is commented out
# if: inputs.cache-references == 'true' # since the input is string
# run: py-tree tests/_cache-references/ --show_hidden
# shell: bash
65 changes: 50 additions & 15 deletions .github/assistant.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import fire
from packaging.version import parse
from pkg_resources import parse_requirements

_REQUEST_TIMEOUT = 10
_PATH_ROOT = os.path.dirname(os.path.dirname(__file__))
Expand Down Expand Up @@ -58,6 +57,9 @@ def set_min_torch_by_python(fpath: str = "requirements/base.txt") -> None:
>>> AssistantCLI.set_min_torch_by_python("../requirements/base.txt")
"""
# ToDo: `pkg_resources` is deprecates and shall be updated
from pkg_resources import parse_requirements

py_ver = f"{sys.version_info.major}.{sys.version_info.minor}"
if py_ver not in LUT_PYTHON_TORCH:
return
Expand Down Expand Up @@ -114,29 +116,42 @@ def changed_domains(
"""Determine what domains were changed in particular PR."""
import github

# define some edge case return cases
_return_all = "unittests" if not as_list else ["torchmetrics"]
_return_empty = [] if as_list else ""

# early return if no PR number
if not pr:
return "unittests"
gh = github.Github()
return _return_all
gh = github.Github(login_or_token=auth_token)
pr = gh.get_repo("Lightning-AI/torchmetrics").get_pull(pr)
files = [f.filename for f in pr.get_files()]

# filter out all integrations as they run in separate suit
files = [fn for fn in files if not fn.startswith("tests/integrations")]
if not files:
logging.debug("Only integrations was changed so not reason for deep testing...")
return ""
return _return_empty
# filter only docs files
files_ = [fn for fn in files if fn.startswith("docs")]
if len(files) == len(files_):
files_docs = [fn for fn in files if fn.startswith("docs")]
if len(files) == len(files_docs):
logging.debug("Only docs was changed so not reason for deep testing...")
return ""
return _return_empty
# files in requirements folder
files_req = [fn for fn in files if fn.startswith("requirements")]
req_domains = [fn.split("/")[1] for fn in files_req]
# cleaning up determining domains
req_domains = [req.replace(".txt", "").replace("_test", "") for req in req_domains if not req.endswith("_")]
# if you touch base, you need to run everything
if "base" in req_domains:
return _return_all

# filter only package files and skip inits
_is_in_test = lambda fn: fn.startswith("tests")
_filter_pkg = lambda fn: _is_in_test(fn) or (fn.startswith("src/torchmetrics") and "__init__.py" not in fn)
files_pkg = [fn for fn in files if _filter_pkg(fn)]
if not files_pkg:
return "unittests"
return _return_all

# parse domains
def _crop_path(fname: str, paths: list[str]) -> str:
Expand All @@ -151,15 +166,35 @@ def _crop_path(fname: str, paths: list[str]) -> str:
tm_modules = [md for md in tm_modules if md not in general_sub_pkgs]
if len(files_pkg) > len(tm_modules):
logging.debug("Some more files was changed -> rather test everything...")
return "unittests"
# keep only unique
if as_list:
return list(tm_modules)
tm_modules = [f"unittests/{md}" for md in set(tm_modules)]
not_exists = [p for p in tm_modules if os.path.exists(p)]
return _return_all

# compose the final list with requirements and touched modules
test_modules = set(tm_modules + list(req_domains))
if as_list: # keep only unique
return list(test_modules)

test_modules = [f"unittests/{md}" for md in set(test_modules)]
not_exists = [p for p in test_modules if os.path.exists(p)]
if not_exists:
raise ValueError(f"Missing following paths: {not_exists}")
return " ".join(tm_modules)
return " ".join(test_modules)

@staticmethod
def move_new_packages(dir_cache: str, dir_local: str, dir_staging: str) -> None:
"""Move unique packages from local folder to staging."""
assert os.path.isdir(dir_cache), f"Missing folder with saved packages: '{dir_cache}'" # noqa: S101
assert os.path.isdir(dir_local), f"Missing folder with local packages: '{dir_local}'" # noqa: S101
assert os.path.isdir(dir_staging), f"Missing folder for staging: '{dir_staging}'" # noqa: S101

import shutil

for pkg in os.listdir(dir_local):
if not os.path.isfile(pkg):
continue
if pkg in os.listdir(dir_cache):
continue
logging.info(f"Moving '{pkg}' to staging...")
shutil.move(os.path.join(dir_cache, pkg), os.path.join(dir_staging, pkg))


if __name__ == "__main__":
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/_focus-diff.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ jobs:
set -e
echo $PR_NUMBER
pip install -q -U packaging fire pyGithub pyopenssl
# python .github/assistant.py changed-domains $PR_NUMBER
echo "focus=$(python .github/assistant.py changed-domains $PR_NUMBER)" >> $GITHUB_OUTPUT
- run: echo "${{ steps.diff-domains.outputs.focus }}"
57 changes: 57 additions & 0 deletions .github/workflows/_merge_cache.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Collect new packages and upload cache

on:
workflow_call:
inputs:
pypi-key:
description: cache restore/dump key
required: false
type: string
default: "pypi-packages"
pypi-dir:
description: location of local PyPI cache
required: false
type: string
default: "_ci-cache_PyPI"
cache-artifact-appendix:
description: "unique name for the job"
required: true
type: string

jobs:
merge-caches:
runs-on: ubuntu-latest
steps:
- name: Download 📥 artifacts
uses: actions/download-artifact@v4
with:
pattern: ${{ inputs.pypi-key }}-run-${{ inputs.cache-artifact-appendix }}*
merge-multiple: true
path: _local-packages
- name: Cache pull packages
uses: actions/cache/restore@v3
with:
enableCrossOsArchive: true
path: ${{ inputs.pypi-dir }}
key: ${{ inputs.pypi-key }}

- name: show 📦
run: |
# create the directory if it doesn't exist - no artifact were found
mkdir -p _local-packages
ls -lh _local-packages
ls -lh ${{ inputs.pypi-dir }}
# count files in the staging dir
file_count=$(ls -1 "_local-packages/" | wc -l)
echo "NUM_PACKAGES=$file_count" >> $GITHUB_ENV
- name: Move collected 📦
if: env.NUM_PACKAGES != 0
run: mv _local-packages/* ${{ inputs.pypi-dir }}

- name: Cache push packages
if: env.NUM_PACKAGES != 0
uses: actions/cache/save@v3
with:
enableCrossOsArchive: true
path: ${{ inputs.pypi-dir }}
key: ${{ inputs.pypi-key }}
Loading

0 comments on commit 255db5f

Please sign in to comment.