├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── PyTorch.png
├── PyTorchUtils
├── CMakeLists.txt
├── PyTorchUtils.py
├── Resources
│ ├── Icons
│ │ └── PyTorchUtils.png
│ └── UI
│ │ └── PyTorchUtils.ui
└── Testing
│ ├── CMakeLists.txt
│ └── Python
│ └── CMakeLists.txt
├── PyTorch_128.png
├── README.md
├── logo_gimp.xcf
└── project_week_diagram.png
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
131 | .vscode
132 | .idea
133 |
134 | .DS_Store
135 |
136 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.13.4)
2 |
3 | project(PyTorch)
4 |
5 | #-----------------------------------------------------------------------------
6 | # Extension meta-information
7 | set(EXTENSION_HOMEPAGE "https://github.com/fepegar/SlicerPyTorch")
8 | set(EXTENSION_CATEGORY "Utilities")
9 | set(EXTENSION_CONTRIBUTORS "Fernando Pérez-García (University College London and King's College London), Andras Lasso (PerkLab Queen's University)")
10 | set(EXTENSION_DESCRIPTION "Utilities to install and use PyTorch within 3D Slicer.")
11 | set(EXTENSION_ICONURL "https://raw.githubusercontent.com/fepegar/SlicerPyTorch/master/PyTorch.png")
12 | set(EXTENSION_SCREENSHOTURLS "https://raw.githubusercontent.com/fepegar/SlicerPyTorch/master/project_week_diagram.png")
13 | set(EXTENSION_DEPENDS "NA") # Specified as a list or "NA" if no dependencies
14 |
15 | #-----------------------------------------------------------------------------
16 | # Extension dependencies
17 | find_package(Slicer REQUIRED)
18 | include(${Slicer_USE_FILE})
19 |
20 | #-----------------------------------------------------------------------------
21 | # Extension modules
22 | add_subdirectory(PyTorchUtils)
23 | ## NEXT_MODULE
24 |
25 | #-----------------------------------------------------------------------------
26 | include(${Slicer_EXTENSION_GENERATE_CONFIG})
27 | include(${Slicer_EXTENSION_CPACK})
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | For more information, please see:
3 |
4 | http://www.slicer.org
5 |
6 | The 3D Slicer license below is a BSD style license, with extensions
7 | to cover contributions and other issues specific to 3D Slicer.
8 |
9 |
10 | 3D Slicer Contribution and Software License Agreement ("Agreement")
11 | Version 1.0 (December 20, 2005)
12 |
13 | This Agreement covers contributions to and downloads from the 3D
14 | Slicer project ("Slicer") maintained by The Brigham and Women's
15 | Hospital, Inc. ("Brigham"). Part A of this Agreement applies to
16 | contributions of software and/or data to Slicer (including making
17 | revisions of or additions to code and/or data already in Slicer). Part
18 | B of this Agreement applies to downloads of software and/or data from
19 | Slicer. Part C of this Agreement applies to all transactions with
20 | Slicer. If you distribute Software (as defined below) downloaded from
21 | Slicer, all of the paragraphs of Part B of this Agreement must be
22 | included with and apply to such Software.
23 |
24 | Your contribution of software and/or data to Slicer (including prior
25 | to the date of the first publication of this Agreement, each a
26 | "Contribution") and/or downloading, copying, modifying, displaying,
27 | distributing or use of any software and/or data from Slicer
28 | (collectively, the "Software") constitutes acceptance of all of the
29 | terms and conditions of this Agreement. If you do not agree to such
30 | terms and conditions, you have no right to contribute your
31 | Contribution, or to download, copy, modify, display, distribute or use
32 | the Software.
33 |
34 | PART A. CONTRIBUTION AGREEMENT - License to Brigham with Right to
35 | Sublicense ("Contribution Agreement").
36 |
37 | 1. As used in this Contribution Agreement, "you" means the individual
38 | contributing the Contribution to Slicer and the institution or
39 | entity which employs or is otherwise affiliated with such
40 | individual in connection with such Contribution.
41 |
42 | 2. This Contribution Agreement applies to all Contributions made to
43 | Slicer, including without limitation Contributions made prior to
44 | the date of first publication of this Agreement. If at any time you
45 | make a Contribution to Slicer, you represent that (i) you are
46 | legally authorized and entitled to make such Contribution and to
47 | grant all licenses granted in this Contribution Agreement with
48 | respect to such Contribution; (ii) if your Contribution includes
49 | any patient data, all such data is de-identified in accordance with
50 | U.S. confidentiality and security laws and requirements, including
51 | but not limited to the Health Insurance Portability and
52 | Accountability Act (HIPAA) and its regulations, and your disclosure
53 | of such data for the purposes contemplated by this Agreement is
54 | properly authorized and in compliance with all applicable laws and
55 | regulations; and (iii) you have preserved in the Contribution all
56 | applicable attributions, copyright notices and licenses for any
57 | third party software or data included in the Contribution.
58 |
59 | 3. Except for the licenses granted in this Agreement, you reserve all
60 | right, title and interest in your Contribution.
61 |
62 | 4. You hereby grant to Brigham, with the right to sublicense, a
63 | perpetual, worldwide, non-exclusive, no charge, royalty-free,
64 | irrevocable license to use, reproduce, make derivative works of,
65 | display and distribute the Contribution. If your Contribution is
66 | protected by patent, you hereby grant to Brigham, with the right to
67 | sublicense, a perpetual, worldwide, non-exclusive, no-charge,
68 | royalty-free, irrevocable license under your interest in patent
69 | rights covering the Contribution, to make, have made, use, sell and
70 | otherwise transfer your Contribution, alone or in combination with
71 | any other code.
72 |
73 | 5. You acknowledge and agree that Brigham may incorporate your
74 | Contribution into Slicer and may make Slicer available to members
75 | of the public on an open source basis under terms substantially in
76 | accordance with the Software License set forth in Part B of this
77 | Agreement. You further acknowledge and agree that Brigham shall
78 | have no liability arising in connection with claims resulting from
79 | your breach of any of the terms of this Agreement.
80 |
81 | 6. YOU WARRANT THAT TO THE BEST OF YOUR KNOWLEDGE YOUR CONTRIBUTION
82 | DOES NOT CONTAIN ANY CODE THAT REQURES OR PRESCRIBES AN "OPEN
83 | SOURCE LICENSE" FOR DERIVATIVE WORKS (by way of non-limiting
84 | example, the GNU General Public License or other so-called
85 | "reciprocal" license that requires any derived work to be licensed
86 | under the GNU General Public License or other "open source
87 | license").
88 |
89 | PART B. DOWNLOADING AGREEMENT - License from Brigham with Right to
90 | Sublicense ("Software License").
91 |
92 | 1. As used in this Software License, "you" means the individual
93 | downloading and/or using, reproducing, modifying, displaying and/or
94 | distributing the Software and the institution or entity which
95 | employs or is otherwise affiliated with such individual in
96 | connection therewith. The Brigham and Women's Hospital,
97 | Inc. ("Brigham") hereby grants you, with right to sublicense, with
98 | respect to Brigham's rights in the software, and data, if any,
99 | which is the subject of this Software License (collectively, the
100 | "Software"), a royalty-free, non-exclusive license to use,
101 | reproduce, make derivative works of, display and distribute the
102 | Software, provided that:
103 |
104 | (a) you accept and adhere to all of the terms and conditions of this
105 | Software License;
106 |
107 | (b) in connection with any copy of or sublicense of all or any portion
108 | of the Software, all of the terms and conditions in this Software
109 | License shall appear in and shall apply to such copy and such
110 | sublicense, including without limitation all source and executable
111 | forms and on any user documentation, prefaced with the following
112 | words: "All or portions of this licensed product (such portions are
113 | the "Software") have been obtained under license from The Brigham and
114 | Women's Hospital, Inc. and are subject to the following terms and
115 | conditions:"
116 |
117 | (c) you preserve and maintain all applicable attributions, copyright
118 | notices and licenses included in or applicable to the Software;
119 |
120 | (d) modified versions of the Software must be clearly identified and
121 | marked as such, and must not be misrepresented as being the original
122 | Software; and
123 |
124 | (e) you consider making, but are under no obligation to make, the
125 | source code of any of your modifications to the Software freely
126 | available to others on an open source basis.
127 |
128 | 2. The license granted in this Software License includes without
129 | limitation the right to (i) incorporate the Software into
130 | proprietary programs (subject to any restrictions applicable to
131 | such programs), (ii) add your own copyright statement to your
132 | modifications of the Software, and (iii) provide additional or
133 | different license terms and conditions in your sublicenses of
134 | modifications of the Software; provided that in each case your use,
135 | reproduction or distribution of such modifications otherwise
136 | complies with the conditions stated in this Software License.
137 |
138 | 3. This Software License does not grant any rights with respect to
139 | third party software, except those rights that Brigham has been
140 | authorized by a third party to grant to you, and accordingly you
141 | are solely responsible for (i) obtaining any permissions from third
142 | parties that you need to use, reproduce, make derivative works of,
143 | display and distribute the Software, and (ii) informing your
144 | sublicensees, including without limitation your end-users, of their
145 | obligations to secure any such required permissions.
146 |
147 | 4. The Software has been designed for research purposes only and has
148 | not been reviewed or approved by the Food and Drug Administration
149 | or by any other agency. YOU ACKNOWLEDGE AND AGREE THAT CLINICAL
150 | APPLICATIONS ARE NEITHER RECOMMENDED NOR ADVISED. Any
151 | commercialization of the Software is at the sole risk of the party
152 | or parties engaged in such commercialization. You further agree to
153 | use, reproduce, make derivative works of, display and distribute
154 | the Software in compliance with all applicable governmental laws,
155 | regulations and orders, including without limitation those relating
156 | to export and import control.
157 |
158 | 5. The Software is provided "AS IS" and neither Brigham nor any
159 | contributor to the software (each a "Contributor") shall have any
160 | obligation to provide maintenance, support, updates, enhancements
161 | or modifications thereto. BRIGHAM AND ALL CONTRIBUTORS SPECIFICALLY
162 | DISCLAIM ALL EXPRESS AND IMPLIED WARRANTIES OF ANY KIND INCLUDING,
163 | BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR
164 | A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
165 | BRIGHAM OR ANY CONTRIBUTOR BE LIABLE TO ANY PARTY FOR DIRECT,
166 | INDIRECT, SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES
167 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY ARISING IN ANY WAY
168 | RELATED TO THE SOFTWARE, EVEN IF BRIGHAM OR ANY CONTRIBUTOR HAS
169 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. TO THE MAXIMUM
170 | EXTENT NOT PROHIBITED BY LAW OR REGULATION, YOU FURTHER ASSUME ALL
171 | LIABILITY FOR YOUR USE, REPRODUCTION, MAKING OF DERIVATIVE WORKS,
172 | DISPLAY, LICENSE OR DISTRIBUTION OF THE SOFTWARE AND AGREE TO
173 | INDEMNIFY AND HOLD HARMLESS BRIGHAM AND ALL CONTRIBUTORS FROM AND
174 | AGAINST ANY AND ALL CLAIMS, SUITS, ACTIONS, DEMANDS AND JUDGMENTS
175 | ARISING THEREFROM.
176 |
177 | 6. None of the names, logos or trademarks of Brigham or any of
178 | Brigham's affiliates or any of the Contributors, or any funding
179 | agency, may be used to endorse or promote products produced in
180 | whole or in part by operation of the Software or derived from or
181 | based on the Software without specific prior written permission
182 | from the applicable party.
183 |
184 | 7. Any use, reproduction or distribution of the Software which is not
185 | in accordance with this Software License shall automatically revoke
186 | all rights granted to you under this Software License and render
187 | Paragraphs 1 and 2 of this Software License null and void.
188 |
189 | 8. This Software License does not grant any rights in or to any
190 | intellectual property owned by Brigham or any Contributor except
191 | those rights expressly granted hereunder.
192 |
193 | PART C. MISCELLANEOUS
194 |
195 | This Agreement shall be governed by and construed in accordance with
196 | the laws of The Commonwealth of Massachusetts without regard to
197 | principles of conflicts of law. This Agreement shall supercede and
198 | replace any license terms that you may have agreed to previously with
199 | respect to Slicer.
200 |
--------------------------------------------------------------------------------
/PyTorch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fepegar/SlicerPyTorch/e1c85cc0a62e92fa6c38223cd88c611906adb60e/PyTorch.png
--------------------------------------------------------------------------------
/PyTorchUtils/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | #-----------------------------------------------------------------------------
2 | set(MODULE_NAME PyTorchUtils)
3 |
4 | #-----------------------------------------------------------------------------
5 | set(MODULE_PYTHON_SCRIPTS
6 | ${MODULE_NAME}.py
7 | )
8 |
9 | set(MODULE_PYTHON_RESOURCES
10 | Resources/Icons/${MODULE_NAME}.png
11 | Resources/UI/${MODULE_NAME}.ui
12 | )
13 |
14 | #-----------------------------------------------------------------------------
15 | slicerMacroBuildScriptedModule(
16 | NAME ${MODULE_NAME}
17 | SCRIPTS ${MODULE_PYTHON_SCRIPTS}
18 | RESOURCES ${MODULE_PYTHON_RESOURCES}
19 | WITH_GENERIC_TESTS
20 | )
21 |
22 | #-----------------------------------------------------------------------------
23 | if(BUILD_TESTING)
24 |
25 | # Register the unittest subclass in the main script as a ctest.
26 | # Note that the test will also be available at runtime.
27 | slicer_add_python_unittest(SCRIPT ${MODULE_NAME}.py)
28 |
29 | # Additional build-time testing
30 | add_subdirectory(Testing)
31 | endif()
32 |
--------------------------------------------------------------------------------
/PyTorchUtils/PyTorchUtils.py:
--------------------------------------------------------------------------------
1 | import qt
2 | import logging
3 |
4 | import slicer
5 | from slicer.ScriptedLoadableModule import (
6 | ScriptedLoadableModule,
7 | ScriptedLoadableModuleWidget,
8 | ScriptedLoadableModuleLogic,
9 | ScriptedLoadableModuleTest,
10 | )
11 |
12 |
13 | class PyTorchUtils(ScriptedLoadableModule):
14 | def __init__(self, parent):
15 | ScriptedLoadableModule.__init__(self, parent)
16 | self.parent.title = "PyTorch Utils"
17 | self.parent.categories = ['Utilities']
18 | self.parent.dependencies = []
19 | self.parent.contributors = [
20 | "Fernando Perez-Garcia (University College London and King's College London)",
21 | "Andras Lasso (PerkLab Queen's University)",
22 | ]
23 | self.parent.helpText = 'This hidden module containing some tools to work with PyTorch inside Slicer.'
24 | self.parent.acknowledgementText = (
25 | 'This work was funded by the Engineering and Physical Sciences'
26 | ' Research Council (EPSRC) and supported by the UCL Centre for Doctoral'
27 | ' Training in Intelligent, Integrated Imaging in Healthcare, the UCL'
28 | ' Wellcome / EPSRC Centre for Interventional and Surgical Sciences (WEISS),'
29 | ' and the School of Biomedical Engineering & Imaging Sciences (BMEIS)'
30 | " of King's College London."
31 | )
32 |
33 |
34 | class PyTorchUtilsWidget(ScriptedLoadableModuleWidget):
35 |
36 | def setup(self):
37 | super().setup()
38 |
39 | self.logic = PyTorchUtilsLogic()
40 |
41 | # Load widget from .ui file (created by Qt Designer).
42 | # Additional widgets can be instantiated manually and added to self.layout.
43 | uiWidget = slicer.util.loadUI(self.resourcePath('UI/PyTorchUtils.ui'))
44 | self.layout.addWidget(uiWidget)
45 | self.ui = slicer.util.childWidgetVariables(uiWidget)
46 |
47 | self.ui.detectPushButton.clicked.connect(self.onDetect)
48 | self.ui.installPushButton.clicked.connect(self.onInstallTorch)
49 | self.ui.uninstallPushButton.clicked.connect(self.onUninstallTorch)
50 | self.ui.restartPushButton.clicked.connect(self.onApplicationRestart)
51 |
52 | self.updateVersionInformation()
53 |
54 | def onDetect(self):
55 | with slicer.util.tryWithErrorDisplay("Failed to detect compatible computation backends.", waitCursor=True):
56 | torchVersionRequirement = self.ui.torchVersionLineEdit.text
57 | backends = PyTorchUtilsLogic.getCompatibleComputationBackends(torchVersionRequirement=torchVersionRequirement)
58 | currentBackend = self.ui.backendComboBox.currentText
59 | self.ui.backendComboBox.clear()
60 | self.ui.backendComboBox.addItem("automatic")
61 | for backend in backends:
62 | self.ui.backendComboBox.addItem(backend)
63 | self.ui.backendComboBox.currentText = currentBackend
64 | self.ui.backendComboBox.showPopup()
65 | self.updateVersionInformation()
66 |
67 | def onInstallTorch(self):
68 | with slicer.util.tryWithErrorDisplay("Failed to install PyTorch. Some PyTorch files may be in use or corrupted. Please restart the application, uninstall PyTorch, and try installing again.", waitCursor=True):
69 | if PyTorchUtilsLogic.torchInstalled():
70 | torch = self.logic.torch
71 | slicer.util.delayDisplay(f'PyTorch {torch.__version__} is already installed, using {self.logic.getDevice()}.', autoCloseMsec=2000)
72 | else:
73 | backend = self.ui.backendComboBox.currentText
74 | automaticBackend = (backend == "automatic")
75 | askConfirmation = automaticBackend
76 | torchVersionRequirement = self.ui.torchVersionLineEdit.text
77 | torchvisionVersionRequirement = self.ui.torchvisionVersionLineEdit.text
78 | torch = self.logic.installTorch(askConfirmation, None if automaticBackend else backend, torchVersionRequirement, torchvisionVersionRequirement)
79 | if torch is not None:
80 | slicer.util.delayDisplay(f'PyTorch {torch.__version__} installed successfully using {self.logic.getDevice()}.', autoCloseMsec=2000)
81 | self.updateVersionInformation()
82 |
83 | def onUninstallTorch(self):
84 | with slicer.util.tryWithErrorDisplay("Failed to uninstall PyTorch. Probably PyTorch is already in use. Please restart the application and try again.", waitCursor=True):
85 | self.logic.uninstallTorch()
86 | slicer.util.delayDisplay(f'PyTorch uninstalled successfully.', autoCloseMsec=2000)
87 | self.updateVersionInformation()
88 |
89 | def updateVersionInformation(self):
90 | try:
91 | self.ui.torchVersionInformation.text = self.logic.torchVersionInformation
92 | except Exception as e:
93 | logging.error(str(e))
94 | self.ui.torchVersionInformation.text = "unknown (corrupted installation?)"
95 | try:
96 | self.ui.torchvisionVersionInformation.text = self.logic.torchvisionVersionInformation
97 | except Exception as e:
98 | logging.error(str(e))
99 | self.ui.torchvisionVersionInformation.text = "unknown (corrupted installation?)"
100 | try:
101 | info = self.logic.nvidiaDriverVersionInformation
102 | self.ui.nvidiaVersionInformation.text = info if info else "not found"
103 | except Exception as e:
104 | logging.error(str(e))
105 | self.ui.nvidiaVersionInformation.text = "not found"
106 |
107 | def onApplicationRestart(self):
108 | slicer.util.restart()
109 |
110 | class PyTorchUtilsLogic(ScriptedLoadableModuleLogic):
111 | def __init__(self):
112 | self._torch = None
113 |
114 | @property
115 | def nvidiaDriverVersionInformation(self):
116 | """Get NVIDIA driver version information as a string that can be displayed to the user.
117 | If light-the-torch is not installed yet then empty string is returned.
118 | """
119 |
120 | try:
121 | import light_the_torch._cb as computationBackend
122 | version = computationBackend._detect_nvidia_driver_version()
123 | if version is None:
124 | return ""
125 | else:
126 | return f"installed version {str(version)}"
127 | except Exception as e:
128 | # Don't install light-the-torch just for getting the NVIDIA driver version
129 | return ""
130 |
131 | @property
132 | def torchVersionInformation(self):
133 | """Get PyTorch version information as a string that can be displayed to the user.
134 | """
135 | if not PyTorchUtilsLogic.torchInstalled():
136 | return "not installed"
137 | import torch
138 | return f"installed version {torch.__version__}"
139 |
140 | @property
141 | def torchvisionVersionInformation(self):
142 | """Get TorchVision version information as a string that can be displayed to the user.
143 | """
144 | if not PyTorchUtilsLogic.torchvisionInstalled():
145 | return "not installed"
146 | import torchvision
147 | return f"installed version {torchvision.__version__}"
148 |
149 | @property
150 | def torch(self):
151 | """``torch`` Python module. it will be installed if necessary."""
152 | if self._torch is None:
153 | logging.info('Importing torch...')
154 | self._torch = self.importTorch()
155 | return self._torch
156 |
157 | @staticmethod
158 | def torchInstalled():
159 | # Attempt to import torch could load some files, which could prevent uninstalling a corrupted pytorch install
160 | import importlib.metadata
161 | try:
162 | metadataPath = [p for p in importlib.metadata.files('torch') if 'METADATA' in str(p)][0]
163 | except importlib.metadata.PackageNotFoundError as e:
164 | return False
165 | try:
166 | import torch
167 | installed = True
168 | except ModuleNotFoundError:
169 | installed = False
170 | return installed
171 |
172 | @staticmethod
173 | def torchvisionInstalled():
174 | try:
175 | import torchvision
176 | installed = True
177 | except ModuleNotFoundError:
178 | installed = False
179 | return installed
180 |
181 | def importTorch(self):
182 | """Import the ``torch`` Python module, installing it if necessary."""
183 | if PyTorchUtilsLogic.torchInstalled():
184 | import torch
185 | else:
186 | torch = self.installTorch()
187 | if torch is None:
188 | logging.warning('PyTorch was not installed')
189 | else:
190 | logging.info(f'PyTorch {torch.__version__} imported successfully')
191 | logging.info(f'CUDA available: {torch.cuda.is_available()}')
192 | return torch
193 |
194 | def installTorch(self, askConfirmation=False, forceComputationBackend=None, torchVersionRequirement=None, torchvisionVersionRequirement=None):
195 | """Install PyTorch and return the ``torch`` Python module.
196 |
197 | :param forceComputationBackend: optional parameter to set computation backend (cpu, cu116, cu117, ...)
198 | :param torchVersionRequirement: optional version requirement for torch (e.g., ">=1.12")
199 | :param torchvisionVersionRequirement: optional version requirement for torchvision (e.g., ">=0.8")
200 |
201 | If computation backend is not specified then the ``light-the-torch`` Python package is used to get the most recent version of
202 | PyTorch compatible with the installed NVIDIA drivers. If CUDA-compatible device is not found, a version compiled for CPU will be installed.
203 | """
204 |
205 | args = PyTorchUtilsLogic._getPipInstallArguments(forceComputationBackend, torchVersionRequirement, torchvisionVersionRequirement)
206 |
207 | if askConfirmation and not slicer.app.commandOptions().testingEnabled:
208 | install = slicer.util.confirmOkCancelDisplay(
209 | f'PyTorch will be downloaded and installed using light-the-torch (ltt {" ".join(args)}).'
210 | ' The process might take some minutes.'
211 | )
212 | if not install:
213 | logging.info('Installation of PyTorch aborted by user')
214 | return None
215 |
216 | logging.info(f"Install PyTorch using light-the-torch with arguments: {args}")
217 |
218 | try:
219 | import light_the_torch._patch
220 | except:
221 | PyTorchUtilsLogic._installLightTheTorch()
222 | import light_the_torch._patch
223 |
224 | slicer.util._executePythonModule('light_the_torch', args)
225 | import torch
226 | logging.info(f'PyTorch {torch.__version__} installed successfully.')
227 | return torch
228 |
229 | def uninstallTorch(self, askConfirmation=False, forceComputationBackend=None):
230 | """Uninstall PyTorch"""
231 | slicer.util.pip_uninstall('torch torchvision')
232 | logging.info(f'PyTorch uninstalled successfully.')
233 |
234 | @staticmethod
235 | def _getPipInstallArguments(forceComputationBackend=None, torchVersionRequirement=None, torchvisionVersionRequirement=None):
236 | if torchVersionRequirement is None:
237 | torchVersionRequirement = ""
238 | if torchvisionVersionRequirement is None:
239 | torchvisionVersionRequirement = ""
240 | args = ["install", "torch"+torchVersionRequirement, "torchvision"+torchvisionVersionRequirement]
241 | if forceComputationBackend is not None:
242 | args.append(f"--pytorch-computation-backend={forceComputationBackend}")
243 | return args
244 |
245 | @staticmethod
246 | def _installLightTheTorch():
247 | slicer.util.pip_install('light-the-torch>=0.5')
248 |
249 | @staticmethod
250 | def getCompatibleComputationBackends(forceComputationBackend=None, torchVersionRequirement=None):
251 | """Get the list of computation backends compatible with the available hardware.
252 |
253 | :param forceComputationBackend: optional parameter to set computation backend (cpu, cu116, cu117, ...)
254 | :param torchVersionRequirement: optional version requirement for torch (e.g., ">=1.12")
255 |
256 | If computation backend is not specified then the ``light-the-torch`` is used to get the most recent version of
257 | PyTorch compatible with the installed NVIDIA drivers.
258 | """
259 | try:
260 | import light_the_torch._patch
261 | except:
262 | PyTorchUtilsLogic._installLightTheTorch()
263 | import light_the_torch._patch
264 |
265 | args = PyTorchUtilsLogic._getPipInstallArguments(forceComputationBackend, torchVersionRequirement)
266 | try:
267 | backends = sorted(light_the_torch._patch.LttOptions.from_pip_argv(args).computation_backends)
268 | except Exception as e:
269 | logging.warning(str(e))
270 | raise ValueError(f"Failed to get computation backend. Requested computation backend: `{forceComputationBackend}`.")
271 |
272 | return backends
273 |
274 | def getPyTorchHubModel(self, repoOwner, repoName, modelName, addPretrainedKwarg=True, *args, **kwargs):
275 | """Use PyTorch Hub to download a PyTorch model, typically pre-trained.
276 |
277 | More information can be found at https://pytorch.org/hub/.
278 | """
279 | repo = f'{repoOwner}/{repoName}'
280 | if addPretrainedKwarg:
281 | kwargs['pretrained'] = True
282 | model = self.torch.hub.load(repo, modelName, *args, **kwargs)
283 | return model
284 |
285 | def getDevice(self):
286 | """Get CUDA device if available and CPU otherwise."""
287 | return self.torch.device('cuda') if self.torch.cuda.is_available() else 'cpu'
288 |
289 | @property
290 | def cuda(self):
291 | """Return True if a CUDA-compatible device is available."""
292 | return self.getDevice() != 'cpu'
293 |
294 |
295 | class PyTorchUtilsTest(ScriptedLoadableModuleTest):
296 |
297 | def runTest(self):
298 | self.test_PyTorchUtils()
299 |
300 | def _delayDisplay(self, message):
301 | if not slicer.app.testingEnabled():
302 | self.delayDisplay(message)
303 |
304 | def test_PyTorchUtils(self):
305 | self._delayDisplay('Starting the test')
306 | logic = PyTorchUtilsLogic()
307 | self._delayDisplay(f'CUDA available: {logic.torch.cuda.is_available()}')
308 | self._delayDisplay('Test passed!')
309 |
--------------------------------------------------------------------------------
/PyTorchUtils/Resources/Icons/PyTorchUtils.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fepegar/SlicerPyTorch/e1c85cc0a62e92fa6c38223cd88c611906adb60e/PyTorchUtils/Resources/Icons/PyTorchUtils.png
--------------------------------------------------------------------------------
/PyTorchUtils/Resources/UI/PyTorchUtils.ui:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |