Skip to content
Merged
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
68 changes: 64 additions & 4 deletions .github/workflows/pythonapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ on:
pull_request:

jobs:
# caching of these jobs:
# - docker-20-03-py3-pip- (shared)
# - ubuntu py37 pip-
# - os-latest-pip- (shared)
flake8-py3:
runs-on: ubuntu-latest
steps:
Expand All @@ -16,10 +20,20 @@ jobs:
uses: actions/setup-python@v1
with:
python-version: 3.7
- name: cache weekly timestamp
id: pip-cache
run: |
echo "::set-output name=datew::$(date '+%Y-%V')"
- name: cache for pip
uses: actions/cache@v2
id: cache
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ steps.pip-cache.outputs.datew }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip wheel
pip install -r requirements-dev.txt
python -m pip install -r requirements-dev.txt
- name: Lint with black formater
run: |
$(pwd)/runtests.sh --nounittests --black
Expand Down Expand Up @@ -51,6 +65,18 @@ jobs:
run: |
which python
python -m pip install --upgrade pip wheel
- name: cache weekly timestamp
id: pip-cache
run: |
echo "::set-output name=datew::$(date '+%Y-%V')"
echo "::set-output name=dir::$(pip cache dir)"
shell: bash
- name: cache for pip
uses: actions/cache@v2
id: cache
with:
path: ${{ steps.pip-cache.outputs.dir }}
key: ${{ matrix.os }}-latest-pip-${{ steps.pip-cache.outputs.datew }}
- if: runner.os == 'windows'
name: Install torch cpu from pytorch.org (Windows only)
run: |
Expand All @@ -63,6 +89,7 @@ jobs:
cat "requirements-dev.txt"
python -m pip install -r requirements-dev.txt
python -m pip list
python setup.py develop # compile the cpp extensions
- name: Run quick tests (CPU ${{ runner.os }})
run: |
python -c 'import torch; print(torch.__version__); print(torch.rand(5,3))'
Expand All @@ -77,6 +104,16 @@ jobs:
runs-on: [self-hosted, linux, x64]
steps:
- uses: actions/checkout@v2
- name: cache weekly timestamp
id: pip-cache
run: |
echo "::set-output name=datew::$(date '+%Y-%V')"
- name: cache for pip
uses: actions/cache@v2
id: cache
with:
path: ~/.cache/pip
key: docker-20-03-py3-pip-${{ steps.pip-cache.outputs.datew }}
- name: Install the dependencies
run: |
which python
Expand All @@ -93,7 +130,6 @@ jobs:
python -c "import torch; print(torch.__version__); print('{} of GPUs available'.format(torch.cuda.device_count()))"
python -c 'import torch; print(torch.rand(5,3, device=torch.device("cuda:0")))'
./runtests.sh --quick
pip list
coverage xml
- name: Upload coverage
uses: codecov/codecov-action@v1
Expand All @@ -110,9 +146,23 @@ jobs:
uses: actions/setup-python@v1
with:
python-version: '3.x'
- name: Install setuptools
- name: cache weekly timestamp
id: pip-cache
run: |
echo "::set-output name=datew::$(date '+%Y-%V')"
- name: cache for pip
uses: actions/cache@v2
id: cache
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ steps.pip-cache.outputs.datew }}
- name: Install dependencies
run: |
python -m pip install --user --upgrade pip setuptools wheel twine
# 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.4
- name: Test source archive and wheel file
run: |
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
Expand Down Expand Up @@ -158,10 +208,20 @@ jobs:
uses: actions/setup-python@v1
with:
python-version: 3.7
- name: cache weekly timestamp
id: pip-cache
run: |
echo "::set-output name=datew::$(date '+%Y-%V')"
- name: cache for pip
uses: actions/cache@v2
id: cache
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ steps.pip-cache.outputs.datew }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip wheel
pip install -r docs/requirements.txt
python -m pip install -r docs/requirements.txt
- name: Make html
run: |
cd docs/
Expand Down
50 changes: 49 additions & 1 deletion .github/workflows/setupapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,37 @@ on:
- master

jobs:
# caching of these jobs:
# - docker-20-03-py3-pip- (shared)
# - ubuntu py36 37 38-pip-
# - os-latest-pip (shared)
coverage-py3:
container:
image: nvcr.io/nvidia/pytorch:20.03-py3
options: --gpus all
runs-on: [self-hosted, linux, x64]
steps:
- uses: actions/checkout@v2
- name: cache weekly timestamp
id: pip-cache
run: |
echo "::set-output name=datew::$(date '+%Y-%V')"
- name: cache for pip
uses: actions/cache@v2
id: cache
with:
path: ~/.cache/pip
key: docker-20-03-py3-pip-${{ steps.pip-cache.outputs.datew }}
- name: Install the dependencies
run: |
which python
python -m pip install --upgrade pip wheel
python -m pip uninstall -y torch torchvision
python -m pip install torch==1.4
python -m pip install -r requirements-dev.txt
python -m pip list
- name: Run unit tests report coverage
run: |
python -m pip list
nvidia-smi
export CUDA_VISIBLE_DEVICES=$(python -m tests.utils)
echo $CUDA_VISIBLE_DEVICES
Expand All @@ -50,13 +64,24 @@ jobs:
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
- name: cache weekly timestamp
id: pip-cache
run: |
echo "::set-output name=datew::$(date '+%Y-%V')"
- name: cache for pip
uses: actions/cache@v2
id: cache
with:
path: ~/.cache/pip
key: ${{ runner.os }}-${{ matrix.python-version }}-pip-${{ steps.pip-cache.outputs.datew }}
- name: Install the dependencies
run: |
python -m pip install --upgrade pip wheel
python -m pip install torch==1.4
python -m pip install -r requirements-dev.txt
- name: Run quick tests CPU ubuntu
run: |
python -m pip list
python -c 'import torch; print(torch.__version__); print(torch.rand(5,3))'
./runtests.sh --quick
coverage xml
Expand All @@ -83,6 +108,18 @@ jobs:
run: |
which python
python -m pip install --upgrade pip wheel
- name: cache weekly timestamp
id: pip-cache
run: |
echo "::set-output name=datew::$(date '+%Y-%V')"
echo "::set-output name=dir::$(pip cache dir)"
shell: bash
- name: cache for pip
uses: actions/cache@v2
id: cache
with:
path: ${{ steps.pip-cache.outputs.dir }}
key: ${{ matrix.os }}-latest-pip-${{ steps.pip-cache.outputs.datew }}
- if: runner.os == 'windows'
name: Install torch cpu from pytorch.org (Windows only)
run: |
Expand All @@ -95,6 +132,7 @@ jobs:
cat "requirements-dev.txt"
python -m pip install -r requirements-dev.txt
python -m pip list
python setup.py develop # to compile extensions using the system native torch
- name: Run quick tests (CPU ${{ runner.os }})
run: |
python -c 'import torch; print(torch.__version__); print(torch.rand(5,3))'
Expand All @@ -109,6 +147,16 @@ jobs:
uses: actions/setup-python@v1
with:
python-version: 3.7
- name: cache weekly timestamp
id: pip-cache
run: |
echo "::set-output name=datew::$(date '+%Y-%V')"
- name: cache for pip
uses: actions/cache@v2
id: cache
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ steps.pip-cache.outputs.datew }}
- name: Install the default branch
run: |
pip install git+https://github.com/Project-MONAI/MONAI#egg=MONAI
Expand Down
9 changes: 6 additions & 3 deletions docs/source/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,13 @@ This command will create a ``MONAI/`` folder in your current directory.
You can install it by running:
```bash
cd MONAI/
pip install -e .
python setup.py develop

# to uninstall the package please run:
python setup.py develop --uninstall
```
or simply adding the root directory of the cloned source code (e.g., ``/workspace/Documents/MONAI``) to your ``$PYTHONPATH``
and the codebase is ready to use.
and the codebase is ready to use (without the additional features of MONAI C++/CUDA extensions).


## Validating the install
Expand Down Expand Up @@ -128,7 +131,7 @@ Since MONAI v0.2.0, the extras syntax such as `pip install 'monai[nibabel]'` is
```
[nibabel, skimage, pillow, tensorboard, gdown, ignite]
```
which correspond to `nibabel`, `scikit-image`, `pillow`, `tensorboard`,
which correspond to `nibabel`, `scikit-image`, `pillow`, `tensorboard`,
`gdown`, and `pytorch-ignite` respectively.

- `pip install 'monai[all]'` installs all the optional dependencies.
5 changes: 5 additions & 0 deletions docs/source/networks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ Layers
.. autoclass:: monai.networks.layers.AffineTransform
:members:

`LLTM`
~~~~~~
.. autoclass:: LLTM
:members:

`Utilities`
~~~~~~~~~~~
.. automodule:: monai.networks.layers.convutils
Expand Down
4 changes: 3 additions & 1 deletion monai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@

__basedir__ = os.path.dirname(__file__)

excludes = "^(handlers)" # the handlers have some external decorators the users may not have installed
# handlers_* have some external decorators the users may not have installed
# *.so files and folder "_C" may not exist when the cpp extensions are not compiled
excludes = "(^(handlers))|((\\.so)$)|(_C)"

# load directory modules only, skip loading individual files
load_submodules(sys.modules[__name__], False, exclude_pattern=excludes)
Expand Down
103 changes: 103 additions & 0 deletions monai/networks/extensions/lltm/lltm.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
Copyright 2020 MONAI Consortium
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include <torch/extension.h>

#include <vector>

// s'(z) = (1 - s(z)) * s(z)
torch::Tensor d_sigmoid(torch::Tensor z) {
auto s = torch::sigmoid(z);
return (1 - s) * s;
}

// tanh'(z) = 1 - tanh^2(z)
torch::Tensor d_tanh(torch::Tensor z) {
return 1 - z.tanh().pow(2);
}

// elu'(z) = relu'(z) + { alpha * exp(z) if (alpha * (exp(z) - 1)) < 0, else 0}
torch::Tensor d_elu(torch::Tensor z, torch::Scalar alpha = 1.0) {
auto e = z.exp();
auto mask = (alpha * (e - 1)) < 0;
return (z > 0).type_as(z) + mask.type_as(z) * (alpha * e);
}

std::vector<torch::Tensor> lltm_forward(
torch::Tensor input,
torch::Tensor weights,
torch::Tensor bias,
torch::Tensor old_h,
torch::Tensor old_cell) {
auto X = torch::cat({old_h, input}, /*dim=*/1);

auto gate_weights = torch::addmm(bias, X, weights.transpose(0, 1));
auto gates = gate_weights.chunk(3, /*dim=*/1);

auto input_gate = torch::sigmoid(gates[0]);
auto output_gate = torch::sigmoid(gates[1]);
auto candidate_cell = torch::elu(gates[2], /*alpha=*/1.0);

auto new_cell = old_cell + candidate_cell * input_gate;
auto new_h = torch::tanh(new_cell) * output_gate;

return {new_h,
new_cell,
input_gate,
output_gate,
candidate_cell,
X,
gate_weights};
}

std::vector<torch::Tensor> lltm_backward(
torch::Tensor grad_h,
torch::Tensor grad_cell,
torch::Tensor new_cell,
torch::Tensor input_gate,
torch::Tensor output_gate,
torch::Tensor candidate_cell,
torch::Tensor X,
torch::Tensor gate_weights,
torch::Tensor weights) {
auto d_output_gate = torch::tanh(new_cell) * grad_h;
auto d_tanh_new_cell = output_gate * grad_h;
auto d_new_cell = d_tanh(new_cell) * d_tanh_new_cell + grad_cell;

auto d_old_cell = d_new_cell;
auto d_candidate_cell = input_gate * d_new_cell;
auto d_input_gate = candidate_cell * d_new_cell;

auto gates = gate_weights.chunk(3, /*dim=*/1);
d_input_gate *= d_sigmoid(gates[0]);
d_output_gate *= d_sigmoid(gates[1]);
d_candidate_cell *= d_elu(gates[2]);

auto d_gates =
torch::cat({d_input_gate, d_output_gate, d_candidate_cell}, /*dim=*/1);

auto d_weights = d_gates.t().mm(X);
auto d_bias = d_gates.sum(/*dim=*/0, /*keepdim=*/true);

auto d_X = d_gates.mm(weights);
const auto state_size = grad_h.size(1);
auto d_old_h = d_X.slice(/*dim=*/1, 0, state_size);
auto d_input = d_X.slice(/*dim=*/1, state_size);

return {d_old_h, d_input, d_weights, d_bias, d_old_cell};
}

PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
m.def("lltm_forward", &lltm_forward, "LLTM forward");
m.def("lltm_backward", &lltm_backward, "LLTM backward");
}
Loading