Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 22 additions & 21 deletions .github/workflows/cicd_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,29 +70,30 @@ jobs:
run: |
echo "skip=1" >> $GITHUB_OUTPUT

mkdir -p /tmp/check_changes
if ! git diff --name-only HEAD^..HEAD ':!docs' > /tmp/check_changes/changed_files
then
echo "skip=0" >> "$GITHUB_OUTPUT"
exit 0
fi
# TEMPORARILY SKIP ALL CI TESTS, UNDO BEFORE MERGE
# mkdir -p /tmp/check_changes
# if ! git diff --name-only HEAD^..HEAD ':!docs' > /tmp/check_changes/changed_files
# then
# echo "skip=0" >> "$GITHUB_OUTPUT"
# exit 0
# fi

while read i
do
echo "Checking for changes: $i"
if ! git show HEAD^:$i > /tmp/check_changes/$(basename $i)
then
echo "New file found, or 'git show' failed, running tests."
elif ! python monai/utils/compare_sources.py $i /tmp/check_changes/$(basename $i)
then
echo "Change found, running tests."
else
continue
fi
# while read i
# do
# echo "Checking for changes: $i"
# if ! git show HEAD^:$i > /tmp/check_changes/$(basename $i)
# then
# echo "New file found, or 'git show' failed, running tests."
# elif ! python monai/utils/compare_sources.py $i /tmp/check_changes/$(basename $i)
# then
# echo "Change found, running tests."
# else
# continue
# fi

echo "skip=0" >> $GITHUB_OUTPUT
break
done < /tmp/check_changes/changed_files
# echo "skip=0" >> $GITHUB_OUTPUT
# break
# done < /tmp/check_changes/changed_files

static-checks: # Perform static type and other checks using runtests.sh
runs-on: ubuntu-latest
Expand Down
91 changes: 91 additions & 0 deletions .github/workflows/cicd_tests_gpu.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
name: tests

on:
# quick tests for pull requests and the releasing branches
push:
branches:
- dev
- main
- releasing/*
pull_request:
branches:
- dev
- main
- releasing/*

permissions:
contents: read

concurrency:
# automatically cancel the previously triggered workflows when there's a newer version
group: cicd-tests-gpu-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

# Supported versions of Python and PyTorch are listed here for use below and as documentation
env:
# supported versions of Python
PYTHON_VER1: '3.11'
PYTHON_VER2: '3.12'
PYTHON_VER3: '3.13'
PYTHON_VER4: '3.14'
# PYTHON_VER5: '3.14' # TODO: not compatible with Torchscript, re-enable once Torchscript removed from MONAI
# supported versions of PyTorch
PYTORCH_VER1: '2.12.1'
PYTORCH_VER2: '2.13.0'
PYTORCH_VER3: '2.14.0'
PYTORCH_VER4: '2.14.1'
TORCHVISION_VER1: '0.27.1' # used for testing with lowest PyTorch version (PYTORCH_VER1), update as needed

TQDM_DISABLE: 1 # squelch TQDM output to reduce log file size

PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION: python # https://github.com/Project-MONAI/MONAI/issues/4354

BUILD_MONAI: 1 # always build MONAI and ensure it tries to use the compiled extensions

# These jobs run the CICD tests, type checking, and testing packaging. These use the minimum supported versions of
# Python and PyTorch in many places using the above environment variables but also hard coded where necessary.
# When support is dropped for a version it is important to update these as appropriate.

jobs:

full-dep-gpu: # Test with full dependencies installed for different OS runners
runs-on: [self-hosted, linux, gpu] #ubuntu-24.04-gpu]
strategy:
fail-fast: false
timeout-minutes: 360
steps:
- uses: actions/checkout@v7
- name: Set up Python ${{ env.PYTHON_VER1 }}
uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_VER1 }}
cache: 'pip'
- name: Prepare pip wheel
run: |
which python
python -m pip install --upgrade pip wheel
- name: Install torch gpu
run: |
# install the lowest version of PyTorch supported
python -m pip install torch==${PYTORCH_VER1} torchvision==${TORCHVISION_VER1}
shell: bash
- name: Install the complete dependencies
run: |
python -m pip install --pre -U itk
python -m pip install --user --upgrade pip wheel tomli
python monai/config/print_dependencies.py build-system | xargs pip install --no-build-isolation
python -m pip install --no-build-isolation -e .[all,testing]
python -m pip list
shell: bash
- name: Run quick tests
run: |
python -c 'import monai._C' > /dev/null
nvidia-smi || true
python monai/config/check_env.py --env --monai
# python -m unittest -v
./runtests.sh --min
env:
QUICKTEST: True
NGC_API_KEY: ${{ secrets.NGC_API_KEY }}
NGC_ORG: ${{ secrets.NGC_ORG }}
NGC_TEAM: ${{ secrets.NGC_TEAM }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,5 @@ runs
*.pth

*zarr/*

uv.lock
6 changes: 3 additions & 3 deletions monai/engines/trainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def run(self) -> None: # type: ignore[override]
If call this function multiple times, it will continuously run from the previous state.

"""
self.scaler = torch.cuda.amp.GradScaler() if self.amp else None
self.scaler = torch.amp.GradScaler() if self.amp else None
super().run()

def get_stats(self, *vars):
Expand Down Expand Up @@ -613,8 +613,8 @@ def __init__(
self.g_inferer = SimpleInferer() if g_inferer is None else g_inferer
self.d_inferer = SimpleInferer() if d_inferer is None else d_inferer

self.state.g_scaler = torch.cuda.amp.GradScaler() if self.amp else None
self.state.d_scaler = torch.cuda.amp.GradScaler() if self.amp else None
self.state.g_scaler = torch.amp.GradScaler() if self.amp else None
self.state.d_scaler = torch.amp.GradScaler() if self.amp else None

self.optim_set_to_none = optim_set_to_none
self._complete_state_dict_user_keys()
Expand Down
2 changes: 1 addition & 1 deletion monai/engines/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def set_sampler_epoch(engine: Engine) -> None:
self.amp = amp
self.to_kwargs = {} if to_kwargs is None else to_kwargs
self.amp_kwargs = {} if amp_kwargs is None else amp_kwargs
self.scaler: torch.cuda.amp.GradScaler | None = None
self.scaler: torch.amp.GradScaler | None = None

if event_names is None:
event_names = [IterationEvents]
Expand Down
5 changes: 1 addition & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ name = "monai"
description = "AI Toolkit for Healthcare Imaging"
readme = { file = "README.md", content-type = "text/markdown" }
requires-python = ">=3.10"
license = { text = "Apache License 2.0" }
license-files = ["LICENSE"]
authors = [{ name = "MONAI Consortium", email = "monai.contact@gmail.com" }]
classifiers = [
"Intended Audience :: Developers",
Expand Down Expand Up @@ -186,9 +186,6 @@ testing = [
"types-setuptools"
]

[tool.setuptools]
license-files = ["LICENSE"]

[tool.setuptools.dynamic]
version = {attr = "monai.__version__"}

Expand Down
2 changes: 1 addition & 1 deletion tests/integration/test_integration_fast_train.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def test_train_timing(self):
# Novograd paper suggests to use a bigger LR than Adam,
# because Adam does normalization by element-wise second moments
optimizer = Novograd(model.parameters(), learning_rate * 10)
scaler = torch.cuda.amp.GradScaler()
scaler = torch.amp.GradScaler()

post_pred = AsDiscrete(argmax=True, to_onehot=2)
post_label = AsDiscrete(to_onehot=2)
Expand Down
Loading