Skip to content

Commit 0688959

Browse files
Merge branch 'dev' into patch-8
2 parents da45347 + d3d0209 commit 0688959

78 files changed

Lines changed: 3350 additions & 265 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.dockerignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
__pycache__/
44
docs/
55

6+
.vscode
7+
.git
8+
.mypy_cache
9+
.ruff_cache
10+
.pytype
611
.coverage
712
.coverage.*
813
.coverage/
914
coverage.xml
1015
.readthedocs.yml
11-
*.toml
1216

1317
!README.md

.github/workflows/setupapp.yml

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ jobs:
8181
runs-on: ubuntu-latest
8282
strategy:
8383
matrix:
84-
python-version: ['3.9', '3.10', '3.11']
84+
python-version: ['3.10', '3.11', '3.12']
8585
steps:
8686
- uses: actions/checkout@v6
8787
with:
@@ -90,23 +90,12 @@ jobs:
9090
uses: actions/setup-python@v6
9191
with:
9292
python-version: ${{ matrix.python-version }}
93-
- name: cache weekly timestamp
94-
id: pip-cache
95-
run: |
96-
echo "datew=$(date '+%Y-%V')" >> $GITHUB_OUTPUT
97-
- name: cache for pip
98-
uses: actions/cache@v5
99-
id: cache
100-
with:
101-
path: |
102-
~/.cache/pip
103-
~/.cache/torch
104-
key: ${{ runner.os }}-${{ matrix.python-version }}-pip-${{ steps.pip-cache.outputs.datew }}
93+
cache: pip
10594
- name: Install the dependencies
10695
run: |
10796
find /opt/hostedtoolcache/* -maxdepth 0 ! -name 'Python' -exec rm -rf {} \;
10897
python -m pip install --upgrade pip wheel
109-
python -m pip install -r requirements-dev.txt
98+
python -m pip install --no-build-isolation -r requirements-dev.txt
11099
- name: Run quick tests CPU ubuntu
111100
env:
112101
NGC_API_KEY: ${{ secrets.NGC_API_KEY }}
@@ -115,8 +104,8 @@ jobs:
115104
run: |
116105
python -m pip list
117106
python -c 'import torch; print(torch.__version__); print(torch.rand(5,3))'
118-
BUILD_MONAI=0 ./runtests.sh --build --quick --unittests
119-
BUILD_MONAI=1 ./runtests.sh --build --quick --min
107+
BUILD_MONAI=0 ./runtests.sh --build --coverage --quick --unittests
108+
BUILD_MONAI=1 ./runtests.sh --build --coverage --quick --min
120109
coverage xml --ignore-errors
121110
- name: Upload coverage
122111
uses: codecov/codecov-action@v5

CONTRIBUTING.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,8 @@ All code review comments should be specific, constructive, and actionable.
380380

381381
### Release a new version
382382

383-
The `dev` branch's `HEAD` always corresponds to MONAI docker image's latest tag: `projectmonai/monai:latest`.
383+
The `dev` branch's `HEAD` always corresponds to MONAI Docker image's latest tag: `projectmonai/monai:latest`. (No
384+
release is currently done for the slim MONAI image, this is built locally by users.)
384385
The `main` branch's `HEAD` always corresponds to the latest MONAI milestone release.
385386

386387
When major features are ready for a milestone, to prepare for a new release:

Dockerfile.slim

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Copyright (c) MONAI Consortium
2+
# Licensed under the Apache License, Version 2.0 (the "License");
3+
# you may not use this file except in compliance with the License.
4+
# You may obtain a copy of the License at
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
# Unless required by applicable law or agreed to in writing, software
7+
# distributed under the License is distributed on an "AS IS" BASIS,
8+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
# See the License for the specific language governing permissions and
10+
# limitations under the License.
11+
12+
# This is a slimmed down version of the MONAI Docker image using a smaller base image and multi-stage building. Not all
13+
# NVIDIA tools will be present but all libraries and compiled code are included. This image isn't provided through
14+
# Dockerhub so users must build locally: `docker build -t monai_slim -f Dockerfile.slim .`
15+
# Containers may require more shared memory, eg.: `docker run -ti --rm --gpus all --shm-size=10gb monai_slim /bin/bash`
16+
17+
ARG IMAGE=debian:12-slim
18+
19+
FROM ${IMAGE} AS build
20+
21+
ARG TORCH_CUDA_ARCH_LIST="7.5 8.0 8.6 8.9 9.0+PTX"
22+
23+
ENV DEBIAN_FRONTEND=noninteractive
24+
ENV APT_INSTALL="apt install -y --no-install-recommends"
25+
26+
RUN apt update && apt upgrade -y && \
27+
${APT_INSTALL} ca-certificates python3-pip python-is-python3 git wget libopenslide0 unzip python3-dev && \
28+
wget https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/cuda-keyring_1.1-1_all.deb && \
29+
dpkg -i cuda-keyring_1.1-1_all.deb && \
30+
apt update && \
31+
${APT_INSTALL} cuda-toolkit-12 && \
32+
rm -rf /usr/lib/python*/EXTERNALLY-MANAGED /var/lib/apt/lists/* && \
33+
python -m pip install --upgrade --no-cache-dir --no-build-isolation pip
34+
35+
# TODO: remark for issue [revise the dockerfile](https://github.com/zarr-developers/numcodecs/issues/431)
36+
RUN if [[ $(uname -m) =~ "aarch64" ]]; then \
37+
CFLAGS="-O3" DISABLE_NUMCODECS_SSE2=true DISABLE_NUMCODECS_AVX2=true python -m pip install numcodecs; \
38+
fi
39+
40+
# NGC Client
41+
WORKDIR /opt/tools
42+
ARG NGC_CLI_URI="https://ngc.nvidia.com/downloads/ngccli_linux.zip"
43+
RUN wget -q ${NGC_CLI_URI} && unzip ngccli_linux.zip && chmod u+x ngc-cli/ngc && \
44+
find ngc-cli/ -type f -exec md5sum {} + | LC_ALL=C sort | md5sum -c ngc-cli.md5 && \
45+
rm -rf ngccli_linux.zip ngc-cli.md5
46+
47+
WORKDIR /opt/monai
48+
49+
# copy relevant parts of repo
50+
COPY requirements.txt requirements-min.txt requirements-dev.txt versioneer.py setup.py setup.cfg pyproject.toml ./
51+
COPY LICENSE CHANGELOG.md CODE_OF_CONDUCT.md CONTRIBUTING.md README.md MANIFEST.in runtests.sh ./
52+
COPY tests ./tests
53+
COPY monai ./monai
54+
55+
# install full deps
56+
RUN python -m pip install --no-cache-dir --no-build-isolation -r requirements-dev.txt
57+
58+
# compile ext
59+
RUN CUDA_HOME=/usr/local/cuda FORCE_CUDA=1 USE_COMPILED=1 BUILD_MONAI=1 python setup.py develop
60+
61+
# recreate the image without the installed CUDA packages then copy the installed MONAI and Python directories
62+
FROM ${IMAGE} AS build2
63+
64+
ENV DEBIAN_FRONTEND=noninteractive
65+
ENV APT_INSTALL="apt install -y --no-install-recommends"
66+
67+
RUN apt update && apt upgrade -y && \
68+
${APT_INSTALL} ca-certificates python3-pip python-is-python3 git libopenslide0 && \
69+
apt clean && \
70+
rm -rf /usr/lib/python*/EXTERNALLY-MANAGED /var/lib/apt/lists/* && \
71+
python -m pip install --upgrade --no-cache-dir --no-build-isolation pip
72+
73+
COPY --from=build /opt/monai /opt/monai
74+
COPY --from=build /opt/tools /opt/tools
75+
ARG PYTHON_VERSION=3.11
76+
COPY --from=build /usr/local/lib/python${PYTHON_VERSION}/dist-packages /usr/local/lib/python${PYTHON_VERSION}/dist-packages
77+
COPY --from=build /usr/local/bin /usr/local/bin
78+
79+
RUN rm -rf /opt/monai/build /opt/monai/monai.egg-info && \
80+
find /opt /usr/local/lib -type d -name __pycache__ -exec rm -rf {} +
81+
82+
# flatten all layers down to one
83+
FROM ${IMAGE}
84+
LABEL maintainer="monai.contact@gmail.com"
85+
86+
COPY --from=build2 / /
87+
88+
WORKDIR /opt/monai
89+
90+
ENV PATH=${PATH}:/opt/tools:/opt/tools/ngc-cli
91+
ENV POLYGRAPHY_AUTOINSTALL_DEPS=1
92+
ENV CUDA_HOME=/usr/local/cuda
93+
ENV BUILD_MONAI=1

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ Examples and notebook tutorials are located at [Project-MONAI/tutorials](https:/
6161

6262
Technical documentation is available at [docs.monai.io](https://docs.monai.io).
6363

64+
## Docker
65+
66+
The MONAI Docker image is available from [Dockerhub](https://hub.docker.com/r/projectmonai/monai),
67+
tagged as `latest` for the latest state of `dev` or with a release version. A slimmed down image can also be built
68+
locally using `Dockerfile.slim`, see that file for instructions.
69+
70+
To get started with the latest MONAI, use `docker run -ti --rm --gpus all projectmonai/monai:latest /bin/bash`.
71+
6472
## Citation
6573

6674
If you have used MONAI in your research, please cite us! The citation can be exported from: <https://arxiv.org/abs/2211.02701>.

docs/source/handlers.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ Panoptic Quality metrics handler
8383
:members:
8484

8585

86+
Calibration Error metrics handler
87+
---------------------------------
88+
.. autoclass:: CalibrationError
89+
:members:
90+
91+
8692
Mean squared error metrics handler
8793
----------------------------------
8894
.. autoclass:: MeanSquaredError

docs/source/losses.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ Segmentation Losses
9898
.. autoclass:: NACLLoss
9999
:members:
100100

101+
`MCCLoss`
102+
~~~~~~~~~
103+
.. autoclass:: MCCLoss
104+
:members:
105+
101106
Registration Losses
102107
-------------------
103108

docs/source/metrics.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,15 @@ Metrics
185185
.. autoclass:: MetricsReloadedCategorical
186186
:members:
187187

188+
`Calibration Error`
189+
-------------------
190+
.. autofunction:: calibration_binning
191+
192+
.. autoclass:: CalibrationReduction
193+
:members:
194+
195+
.. autoclass:: CalibrationErrorMetric
196+
:members:
188197

189198

190199
Utilities

monai/apps/detection/transforms/box_ops.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ def convert_box_to_mask(
267267
boxes_only_mask = np.ones(box_size, dtype=np.int16) * np.int16(labels_np[b])
268268
# apply to global mask
269269
slicing = [b]
270-
slicing.extend(slice(boxes_np[b, d], boxes_np[b, d + spatial_dims]) for d in range(spatial_dims)) # type:ignore
270+
slicing.extend(slice(boxes_np[b, d], boxes_np[b, d + spatial_dims]) for d in range(spatial_dims)) # type: ignore
271271
boxes_mask_np[tuple(slicing)] = boxes_only_mask
272272
return convert_to_dst_type(src=boxes_mask_np, dst=boxes, dtype=torch.int16)[0]
273273

monai/apps/detection/transforms/dictionary.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,11 +1137,14 @@ def generate_fg_center_boxes_np(self, boxes: NdarrayOrTensor, image_size: Sequen
11371137
extended_boxes[:, axis] = boxes_start[:, axis] - self.spatial_size[axis] // 2 + 1
11381138
extended_boxes[:, axis + spatial_dims] = boxes_stop[:, axis] + self.spatial_size[axis] // 2 - 1
11391139
else:
1140+
# the cropper will extend an additional pixel to the left side when the size is even
1141+
radius_left = self.spatial_size[axis] // 2
1142+
radius_right = self.spatial_size[axis] - radius_left - 1 # we subtract 1 for the center voxel
11401143
# extended box start
1141-
extended_boxes[:, axis] = boxes_stop[:, axis] - self.spatial_size[axis] // 2 - 1
1144+
extended_boxes[:, axis] = boxes_stop[:, axis] - radius_right
11421145
extended_boxes[:, axis] = np.minimum(extended_boxes[:, axis], boxes_start[:, axis])
11431146
# extended box stop
1144-
extended_boxes[:, axis + spatial_dims] = extended_boxes[:, axis] + self.spatial_size[axis] // 2
1147+
extended_boxes[:, axis + spatial_dims] = boxes_start[:, axis] + radius_left
11451148
extended_boxes[:, axis + spatial_dims] = np.maximum(
11461149
extended_boxes[:, axis + spatial_dims], boxes_stop[:, axis]
11471150
)

0 commit comments

Comments
 (0)