Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump min torch to 1.13.1 to mitigate CVE-2022-45907 unsafe usage of eval #8296

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
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
4 changes: 0 additions & 4 deletions .github/workflows/cron.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,12 @@ jobs:
strategy:
matrix:
environment:
- "PT110+CUDA113"
- "PT113+CUDA118"
- "PT210+CUDA121"
- "PT240+CUDA126"
- "PTLATEST+CUDA126"
include:
# https://docs.nvidia.com/deeplearning/frameworks/pytorch-release-notes
- environment: PT110+CUDA113
pytorch: "torch==1.10.2 torchvision==0.11.3 --extra-index-url https://download.pytorch.org/whl/cu113"
base: "nvcr.io/nvidia/pytorch:21.06-py3" # CUDA 11.3
- environment: PT113+CUDA118
pytorch: "torch==1.13.1 torchvision==0.14.1 --extra-index-url https://download.pytorch.org/whl/cu121"
base: "nvcr.io/nvidia/pytorch:22.10-py3" # CUDA 11.8
Expand Down
16 changes: 1 addition & 15 deletions .github/workflows/pythonapp-gpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,10 @@ jobs:
strategy:
matrix:
environment:
- "PT19+CUDA114DOCKER"
- "PT110+CUDA111"
- "PT112+CUDA118DOCKER"
- "PT113+CUDA116"
- "PT210+CUDA121DOCKER"
include:
# https://docs.nvidia.com/deeplearning/frameworks/pytorch-release-notes
- environment: PT110+CUDA111
pytorch: "torch==1.10.2 torchvision==0.11.3 --extra-index-url https://download.pytorch.org/whl/cu111"
base: "nvcr.io/nvidia/cuda:11.1.1-devel-ubuntu18.04"
- environment: PT112+CUDA118DOCKER
# 22.09: 1.13.0a0+d0d6b1f
pytorch: "-h" # we explicitly set pytorch to -h to avoid pip install error
base: "nvcr.io/nvidia/pytorch:22.09-py3"
- environment: PT113+CUDA116
pytorch: "torch==1.13.1 torchvision==0.14.1"
base: "nvcr.io/nvidia/cuda:11.6.1-devel-ubuntu18.04"
Expand All @@ -59,8 +49,7 @@ jobs:
apt-get update
apt-get install -y wget

if [ ${{ matrix.environment }} = "PT110+CUDA111" ] || \
[ ${{ matrix.environment }} = "PT113+CUDA116" ]
if [ ${{ matrix.environment }} = "PT113+CUDA116" ]
then
PYVER=3.9 PYSFX=3 DISTUTILS=python3-distutils && \
apt-get update && apt-get install -y --no-install-recommends \
Expand Down Expand Up @@ -94,9 +83,6 @@ jobs:
python get-pip.py && \
rm get-pip.py;
fi
- if: matrix.environment == 'PT19+CUDA114DOCKER'
name: Optional Cupy dependency (cuda114)
run: echo "cupy-cuda114" >> requirements-dev.txt
- name: Install dependencies
if: github.event.pull_request.merged != true
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pythonapp-min.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ jobs:
strategy:
fail-fast: false
matrix:
pytorch-version: ['1.10.2', '1.11.0', '1.12.1', '1.13', '2.0.1', 'latest']
pytorch-version: ['1.13.1', '2.0.1', 'latest']
timeout-minutes: 40
steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pythonapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ jobs:
# install the latest pytorch for testing
# however, "pip install monai*.tar.gz" will build cpp/cuda with an isolated
# fresh torch installation according to pyproject.toml
python -m pip install torch>=1.9 torchvision
python -m pip install torch>=1.13.1 torchvision
- name: Check packages
run: |
pip uninstall monai
Expand Down
4 changes: 2 additions & 2 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-f https://download.pytorch.org/whl/cpu/torch-1.12.1%2Bcpu-cp37-cp37m-linux_x86_64.whl
torch>=1.9
-f https://download.pytorch.org/whl/cpu/torch-1.13.1%2Bcpu-cp39-cp39-linux_x86_64.whl
torch>=1.13.1
pytorch-ignite==0.4.11
numpy>=1.20
itk>=5.2
Expand Down
2 changes: 1 addition & 1 deletion environment-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ channels:
- conda-forge
dependencies:
- numpy>=1.24,<2.0
- pytorch>=1.9
- pytorch>=1.13.1
- torchio
- torchvision
- pytorch-cuda>=11.6
Expand Down
5 changes: 1 addition & 4 deletions monai/apps/auto3dseg/transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import torch

from monai.config import KeysCollection
from monai.networks.utils import pytorch_after
from monai.transforms import MapTransform
from monai.utils.misc import ImageMetaKey

Expand Down Expand Up @@ -74,9 +73,7 @@ def __call__(self, data: Mapping[Hashable, torch.Tensor]) -> dict[Hashable, torc
f", the metadata was not updated {filename}."
)
d[key] = torch.nn.functional.interpolate(
input=d[key].unsqueeze(0),
size=image_shape,
mode="nearest-exact" if pytorch_after(1, 11) else "nearest",
input=d[key].unsqueeze(0), size=image_shape, mode="nearest-exact"
).squeeze(0)
else:
raise ValueError(
Expand Down
19 changes: 6 additions & 13 deletions monai/data/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
issequenceiterable,
look_up_option,
optional_import,
pytorch_after,
)

pd, _ = optional_import("pandas")
Expand Down Expand Up @@ -450,12 +449,9 @@ def collate_meta_tensor_fn(batch, *, collate_fn_map=None):
Collate a sequence of meta tensor into a single batched metatensor. This is called by `collage_meta_tensor`
and so should not be used as a collate function directly in dataloaders.
"""
if pytorch_after(1, 13):
from torch.utils.data._utils.collate import collate_tensor_fn # imported here for pylint/mypy issues
from torch.utils.data._utils.collate import collate_tensor_fn # imported here for pylint/mypy issues

collated = collate_tensor_fn(batch)
else:
collated = default_collate(batch)
collated = collate_tensor_fn(batch)

meta_dicts = [i.meta or TraceKeys.NONE for i in batch]
common_ = set.intersection(*[set(d.keys()) for d in meta_dicts if isinstance(d, dict)])
Expand Down Expand Up @@ -494,18 +490,15 @@ def list_data_collate(batch: Sequence):
Need to use this collate if apply some transforms that can generate batch data.

"""
from torch.utils.data._utils.collate import default_collate_fn_map

if pytorch_after(1, 13):
# needs to go here to avoid circular import
from torch.utils.data._utils.collate import default_collate_fn_map

from monai.data.meta_tensor import MetaTensor
from monai.data.meta_tensor import MetaTensor

default_collate_fn_map.update({MetaTensor: collate_meta_tensor_fn})
default_collate_fn_map.update({MetaTensor: collate_meta_tensor_fn})
elem = batch[0]
data = [i for k in batch for i in k] if isinstance(elem, list) else batch
key = None
collate_fn = default_collate if pytorch_after(1, 13) else collate_meta_tensor
collate_fn = default_collate
try:
if config.USE_META_DICT:
data = pickle_operations(data) # bc 0.9.0
Expand Down
3 changes: 1 addition & 2 deletions monai/inferers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,10 @@
fall_back_tuple,
look_up_option,
optional_import,
pytorch_after,
)

tqdm, _ = optional_import("tqdm", name="tqdm")
_nearest_mode = "nearest-exact" if pytorch_after(1, 11) else "nearest"
_nearest_mode = "nearest-exact"

__all__ = ["sliding_window_inference"]

Expand Down
16 changes: 2 additions & 14 deletions monai/losses/dice.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from monai.losses.spatial_mask import MaskedLoss
from monai.losses.utils import compute_tp_fp_fn
from monai.networks import one_hot
from monai.utils import DiceCEReduction, LossReduction, Weight, look_up_option, pytorch_after
from monai.utils import DiceCEReduction, LossReduction, Weight, look_up_option


class DiceLoss(_Loss):
Expand Down Expand Up @@ -738,20 +738,14 @@ def __init__(
batch=batch,
weight=dice_weight,
)
if pytorch_after(1, 10):
self.cross_entropy = nn.CrossEntropyLoss(
weight=weight, reduction=reduction, label_smoothing=label_smoothing
)
else:
self.cross_entropy = nn.CrossEntropyLoss(weight=weight, reduction=reduction)
self.cross_entropy = nn.CrossEntropyLoss(weight=weight, reduction=reduction, label_smoothing=label_smoothing)
self.binary_cross_entropy = nn.BCEWithLogitsLoss(pos_weight=weight, reduction=reduction)
if lambda_dice < 0.0:
raise ValueError("lambda_dice should be no less than 0.0.")
if lambda_ce < 0.0:
raise ValueError("lambda_ce should be no less than 0.0.")
self.lambda_dice = lambda_dice
self.lambda_ce = lambda_ce
self.old_pt_ver = not pytorch_after(1, 10)

def ce(self, input: torch.Tensor, target: torch.Tensor) -> torch.Tensor:
"""
Expand All @@ -764,12 +758,6 @@ def ce(self, input: torch.Tensor, target: torch.Tensor) -> torch.Tensor:
if n_pred_ch != n_target_ch and n_target_ch == 1:
target = torch.squeeze(target, dim=1)
target = target.long()
elif self.old_pt_ver:
warnings.warn(
f"Multichannel targets are not supported in this older Pytorch version {torch.__version__}. "
"Using argmax (as a workaround) to convert target to a single channel."
)
target = torch.argmax(target, dim=1)
elif not torch.is_floating_point(target):
target = target.to(dtype=input.dtype)

Expand Down
4 changes: 1 addition & 3 deletions monai/losses/ds_loss.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
import torch.nn.functional as F
from torch.nn.modules.loss import _Loss

from monai.utils import pytorch_after


class DeepSupervisionLoss(_Loss):
"""
Expand All @@ -42,7 +40,7 @@ def __init__(self, loss: _Loss, weight_mode: str = "exp", weights: list[float] |
self.loss = loss
self.weight_mode = weight_mode
self.weights = weights
self.interp_mode = "nearest-exact" if pytorch_after(1, 11) else "nearest"
self.interp_mode = "nearest-exact"

def get_weights(self, levels: int = 1) -> list[float]:
"""
Expand Down
16 changes: 2 additions & 14 deletions monai/networks/layers/simplelayers.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
issequenceiterable,
look_up_option,
optional_import,
pytorch_after,
)

_C, _ = optional_import("monai._C")
Expand Down Expand Up @@ -293,14 +292,7 @@ def apply_filter(x: torch.Tensor, kernel: torch.Tensor, **kwargs) -> torch.Tenso
x = x.view(1, kernel.shape[0], *spatials)
conv = [F.conv1d, F.conv2d, F.conv3d][n_spatial - 1]
if "padding" not in kwargs:
if pytorch_after(1, 10):
kwargs["padding"] = "same"
else:
# even-sized kernels are not supported
kwargs["padding"] = [(k - 1) // 2 for k in kernel.shape[2:]]
elif kwargs["padding"] == "same" and not pytorch_after(1, 10):
# even-sized kernels are not supported
kwargs["padding"] = [(k - 1) // 2 for k in kernel.shape[2:]]
kwargs["padding"] = "same"

if "stride" not in kwargs:
kwargs["stride"] = 1
Expand Down Expand Up @@ -372,11 +364,7 @@ def _make_coeffs(window_length, order):
a = idx ** torch.arange(order + 1, dtype=torch.float, device="cpu").reshape(-1, 1)
y = torch.zeros(order + 1, dtype=torch.float, device="cpu")
y[0] = 1.0
return (
torch.lstsq(y, a).solution.squeeze() # type: ignore
if not pytorch_after(1, 11)
else torch.linalg.lstsq(a, y).solution.squeeze()
)
return torch.linalg.lstsq(a, y).solution.squeeze()


class HilbertTransform(nn.Module):
Expand Down
20 changes: 4 additions & 16 deletions monai/networks/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from monai.apps.utils import get_logger
from monai.config import PathLike
from monai.utils.misc import ensure_tuple, save_obj, set_determinism
from monai.utils.module import look_up_option, optional_import, pytorch_after
from monai.utils.module import look_up_option, optional_import
from monai.utils.type_conversion import convert_to_dst_type, convert_to_tensor

onnx, _ = optional_import("onnx")
Expand Down Expand Up @@ -676,15 +676,6 @@ def convert_to_onnx(
torch_versioned_kwargs["verify"] = verify
verify = False
else:
if not pytorch_after(1, 10):
if "example_outputs" not in kwargs:
# https://github.com/pytorch/pytorch/blob/release/1.9/torch/onnx/__init__.py#L182
raise TypeError(
"example_outputs is required in scripting mode before PyTorch 1.10."
"Please provide example outputs or use trace mode to export onnx model."
)
torch_versioned_kwargs["example_outputs"] = kwargs["example_outputs"]
del kwargs["example_outputs"]
mode_to_export = torch.jit.script(model, **kwargs)

if torch.is_tensor(inputs) or isinstance(inputs, dict):
Expand Down Expand Up @@ -746,8 +737,7 @@ def convert_to_onnx(
# compare onnx/ort and PyTorch results
for r1, r2 in zip(torch_out, onnx_out):
if isinstance(r1, torch.Tensor):
assert_fn = torch.testing.assert_close if pytorch_after(1, 11) else torch.testing.assert_allclose
assert_fn(r1.cpu(), convert_to_tensor(r2, dtype=r1.dtype), rtol=rtol, atol=atol) # type: ignore
torch.testing.assert_close(r1.cpu(), convert_to_tensor(r2, dtype=r1.dtype), rtol=rtol, atol=atol) # type: ignore

return onnx_model

Expand Down Expand Up @@ -817,8 +807,7 @@ def convert_to_torchscript(
# compare TorchScript and PyTorch results
for r1, r2 in zip(torch_out, torchscript_out):
if isinstance(r1, torch.Tensor) or isinstance(r2, torch.Tensor):
assert_fn = torch.testing.assert_close if pytorch_after(1, 11) else torch.testing.assert_allclose
assert_fn(r1, r2, rtol=rtol, atol=atol) # type: ignore
torch.testing.assert_close(r1, r2, rtol=rtol, atol=atol) # type: ignore

return script_module

Expand Down Expand Up @@ -1031,8 +1020,7 @@ def convert_to_trt(
# compare TorchScript and PyTorch results
for r1, r2 in zip(torch_out, trt_out):
if isinstance(r1, torch.Tensor) or isinstance(r2, torch.Tensor):
assert_fn = torch.testing.assert_close if pytorch_after(1, 11) else torch.testing.assert_allclose
assert_fn(r1, r2, rtol=rtol, atol=atol) # type: ignore
torch.testing.assert_close(r1, r2, rtol=rtol, atol=atol) # type: ignore

return trt_model

Expand Down
7 changes: 1 addition & 6 deletions monai/transforms/croppad/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@
ensure_tuple_rep,
fall_back_tuple,
look_up_option,
pytorch_after,
)

__all__ = [
Expand Down Expand Up @@ -392,11 +391,7 @@ def compute_slices(
roi_center_t = convert_to_tensor(data=roi_center, dtype=torch.int16, wrap_sequence=True, device="cpu")
roi_size_t = convert_to_tensor(data=roi_size, dtype=torch.int16, wrap_sequence=True, device="cpu")
_zeros = torch.zeros_like(roi_center_t)
half = (
torch.divide(roi_size_t, 2, rounding_mode="floor")
if pytorch_after(1, 8)
else torch.floor_divide(roi_size_t, 2)
)
half = torch.divide(roi_size_t, 2, rounding_mode="floor")
roi_start_t = torch.maximum(roi_center_t - half, _zeros)
roi_end_t = torch.maximum(roi_start_t + roi_size_t, roi_start_t)
else:
Expand Down
3 changes: 1 addition & 2 deletions monai/transforms/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
look_up_option,
min_version,
optional_import,
pytorch_after,
unsqueeze_left,
unsqueeze_right,
)
Expand Down Expand Up @@ -2255,7 +2254,7 @@ def _to_torch_resample_interp_mode(interp_mode):
if ret is not None:
return ret
_mapping = {
SplineMode.ZERO: InterpolateMode.NEAREST_EXACT if pytorch_after(1, 11) else InterpolateMode.NEAREST,
SplineMode.ZERO: InterpolateMode.NEAREST_EXACT,
SplineMode.ONE: InterpolateMode.LINEAR,
SplineMode.THREE: InterpolateMode.BICUBIC,
}
Expand Down
10 changes: 0 additions & 10 deletions monai/utils/tf32.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,6 @@ def detect_default_tf32() -> bool:
if not has_ampere_or_later():
return False

from monai.utils.module import pytorch_after

if pytorch_after(1, 7, 0) and not pytorch_after(1, 12, 0):
warnings.warn(
"torch.backends.cuda.matmul.allow_tf32 = True by default.\n"
" This value defaults to True when PyTorch version in [1.7, 1.11] and may affect precision.\n"
" See https://docs.monai.io/en/latest/precision_accelerating.html#precision-and-accelerating"
)
may_enable_tf32 = True

override_tf32_env_vars = {"NVIDIA_TF32_OVERRIDE": "1"} # TORCH_ALLOW_TF32_CUBLAS_OVERRIDE not checked #6907
for name, override_val in override_tf32_env_vars.items():
if os.environ.get(name) == override_val:
Expand Down
Loading
Loading