From efb54dce0c53c888b56934d5881ef625f798dc3b Mon Sep 17 00:00:00 2001 From: Alexy Pellegrini Date: Fri, 3 Jun 2022 09:20:46 +0200 Subject: [PATCH] ENH: Remove ITKCudaCommon from the source tree Now builds with the remote module CudaCommon of ITK. Builds both as a remote module of ITK and as a standalone library. --- .github/workflows/build-test-cxx-cuda.yml | 1 + .../build-test-package-python-cuda.yml | 9 +- CMakeLists.txt | 13 - itk-module.cmake | 6 +- src/CMakeLists.txt | 6 +- utilities/ITKCudaCommon/CMakeLists.txt | 43 --- utilities/ITKCudaCommon/LICENSE | 202 ----------- utilities/ITKCudaCommon/README | 0 .../include/itkCudaContextManager.h | 66 ---- .../include/itkCudaDataManager.h | 257 -------------- .../ITKCudaCommon/include/itkCudaImage.h | 320 ------------------ .../ITKCudaCommon/include/itkCudaImage.hxx | 236 ------------- .../include/itkCudaImageDataManager.h | 102 ------ .../include/itkCudaImageDataManager.hxx | 156 --------- .../include/itkCudaImageToImageFilter.h | 113 ------- .../include/itkCudaImageToImageFilter.hxx | 120 ------- .../include/itkCudaInPlaceImageFilter.h | 115 ------- .../include/itkCudaInPlaceImageFilter.hxx | 133 -------- .../include/itkCudaMemoryProbe.h | 56 --- utilities/ITKCudaCommon/include/itkCudaUtil.h | 84 ----- .../include/itkCudaWin32Header.h | 34 -- utilities/ITKCudaCommon/itk-module.cmake | 15 - utilities/ITKCudaCommon/src/CMakeLists.txt | 36 -- .../src/itkCudaContextManager.cxx | 109 ------ .../ITKCudaCommon/src/itkCudaDataManager.cxx | 291 ---------------- .../ITKCudaCommon/src/itkCudaMemoryProbe.cxx | 38 --- utilities/ITKCudaCommon/src/itkCudaUtil.cxx | 218 ------------ wrapping/CMakeLists.txt | 2 +- wrapping/itkCudaDataManager.wrap | 5 - wrapping/itkCudaImage.wrap | 31 -- wrapping/itkCudaImageDataManager.wrap | 35 -- wrapping/itkCudaImageDataManagerRTK.wrap | 28 ++ wrapping/itkCudaImageRTK.wrap | 26 ++ 33 files changed, 65 insertions(+), 2841 deletions(-) delete mode 100644 utilities/ITKCudaCommon/CMakeLists.txt delete mode 100644 utilities/ITKCudaCommon/LICENSE delete mode 100644 utilities/ITKCudaCommon/README delete mode 100644 utilities/ITKCudaCommon/include/itkCudaContextManager.h delete mode 100644 utilities/ITKCudaCommon/include/itkCudaDataManager.h delete mode 100644 utilities/ITKCudaCommon/include/itkCudaImage.h delete mode 100644 utilities/ITKCudaCommon/include/itkCudaImage.hxx delete mode 100644 utilities/ITKCudaCommon/include/itkCudaImageDataManager.h delete mode 100644 utilities/ITKCudaCommon/include/itkCudaImageDataManager.hxx delete mode 100644 utilities/ITKCudaCommon/include/itkCudaImageToImageFilter.h delete mode 100644 utilities/ITKCudaCommon/include/itkCudaImageToImageFilter.hxx delete mode 100644 utilities/ITKCudaCommon/include/itkCudaInPlaceImageFilter.h delete mode 100644 utilities/ITKCudaCommon/include/itkCudaInPlaceImageFilter.hxx delete mode 100644 utilities/ITKCudaCommon/include/itkCudaMemoryProbe.h delete mode 100644 utilities/ITKCudaCommon/include/itkCudaUtil.h delete mode 100644 utilities/ITKCudaCommon/include/itkCudaWin32Header.h delete mode 100644 utilities/ITKCudaCommon/itk-module.cmake delete mode 100644 utilities/ITKCudaCommon/src/CMakeLists.txt delete mode 100644 utilities/ITKCudaCommon/src/itkCudaContextManager.cxx delete mode 100644 utilities/ITKCudaCommon/src/itkCudaDataManager.cxx delete mode 100644 utilities/ITKCudaCommon/src/itkCudaMemoryProbe.cxx delete mode 100644 utilities/ITKCudaCommon/src/itkCudaUtil.cxx delete mode 100644 wrapping/itkCudaDataManager.wrap delete mode 100644 wrapping/itkCudaImage.wrap delete mode 100644 wrapping/itkCudaImageDataManager.wrap create mode 100644 wrapping/itkCudaImageDataManagerRTK.wrap create mode 100644 wrapping/itkCudaImageRTK.wrap diff --git a/.github/workflows/build-test-cxx-cuda.yml b/.github/workflows/build-test-cxx-cuda.yml index 4c73a2c96..8c3f92496 100644 --- a/.github/workflows/build-test-cxx-cuda.yml +++ b/.github/workflows/build-test-cxx-cuda.yml @@ -4,6 +4,7 @@ on: [push,pull_request] env: itk-git-tag: "v5.3.0" + itk-module-deps: "CudaCommon@7f9a395c4c61e1757d0cdee82da7248b2117f3f2" jobs: build-test-cxx: diff --git a/.github/workflows/build-test-package-python-cuda.yml b/.github/workflows/build-test-package-python-cuda.yml index f0edb9f24..ca2de30dd 100644 --- a/.github/workflows/build-test-package-python-cuda.yml +++ b/.github/workflows/build-test-package-python-cuda.yml @@ -5,8 +5,9 @@ on: [push,pull_request] env: cmake-options: '-DRTK_BUILD_APPLICATIONS:BOOL=OFF -DRTK_CUDA_VERSION=11.6' itk-wheel-tag: 'v5.3.0' - itk-python-package-tag: 'ee05fd4fa5feedc32afbed32b84b9c9eb0518036' - itk-python-package-org: 'InsightSoftwareConsortium' + itk-python-package-tag: 'e41b75c7d7c5f1d74860e0765760e11b8ee5033c' + itk-python-package-org: 'SimonRit' + itk-module-deps: "RTKConsortium/ITKCudaCommon@7f9a395c4c61e1757d0cdee82da7248b2117f3f2" jobs: build-linux-cuda-python-packages: @@ -37,7 +38,7 @@ jobs: export ITKPYTHONPACKAGE_TAG=${{ env.itk-python-package-tag }} export ITKPYTHONPACKAGE_ORG=${{ env.itk-python-package-org }} export ITK_MODULE_PREQ=${{ env.itk-module-deps }} - CMAKE_OPTIONS="--cmake_options ${{ env.cmake-options }} -DCUDAToolkit_ROOT=/usr/lib64/cuda116 -DCMAKE_CUDA_COMPILER=/usr/lib64/cuda116/bin/nvcc" + CMAKE_OPTIONS=(--cmake_options "${{ env.cmake-options }} -DCUDAToolkit_ROOT=/usr/lib64/cuda116 -DCMAKE_CUDA_COMPILER=/usr/lib64/cuda116/bin/nvcc") export LD_LIBRARY_PATH="/home/srit/Downloads/cuda116:/home/srit/Downloads/cuda116/targets/x86_64-linux/lib:/home/srit/Downloads/cuda116/lib64/stubs" if test -e ../../ITKPythonBuilds-linux-manylinux2014.tar.zst ; then mv ../../*zst . @@ -48,7 +49,7 @@ jobs: export MANYLINUX_VERSION=`(echo ${MANYLINUX_PLATFORM} | cut -d '-' -f 1)` export TARGET_ARCH=`(echo ${MANYLINUX_PLATFORM} | cut -d '-' -f 2)` echo "Building for manylinux specialization ${MANYLINUX_VERSION} and target architecture ${TARGET_ARCH}" - ./dockcross-manylinux-download-cache-and-build-module-wheels.sh $CMAKE_OPTIONS -x "libcuda.so;libcuda.so.1;libcudart.so;libcudart.so.11.0;libcublas.so;libcublas.so.11;libcublasLt.so;libcublasLt.so.11;libcufft.so;libcufft.so.10" cp${{ matrix.python-version }} + ./dockcross-manylinux-download-cache-and-build-module-wheels.sh "${CMAKE_OPTIONS[@]}" -x "libcuda.so;libcuda.so.1;libcudart.so;libcudart.so.11.0;libcublas.so;libcublas.so.11;libcublasLt.so;libcublasLt.so.11;libcufft.so;libcufft.so.10" cp${{ matrix.python-version }} mv *zst ../.. - name: Publish Python package as GitHub Artifact diff --git a/CMakeLists.txt b/CMakeLists.txt index d913f77d3..6b0c25232 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -159,16 +159,6 @@ list(APPEND RTK_INCLUDE_DIRS "${LPSOLVE_INCLUDE_DIRS}") #========================================================= -# ITKCudaCommon -#========================================================= -if(RTK_USE_CUDA) - if(NOT TARGET ITKCudaCommon) - add_subdirectory(utilities/ITKCudaCommon) - endif() -endif() -list(APPEND RTK_INCLUDE_DIRS - ${ITKCudaCommon_INCLUDE_DIRS}) -#========================================================= # Include directories #========================================================= list(APPEND RTK_INCLUDE_DIRS @@ -223,9 +213,6 @@ if(NOT ITK_SOURCE_DIR) # This must be done after RTK has been loaded by ITK to make sure # ${itk-module} variables are defined for RTK. itk_module_target_export(lpsolve55) - if(RTK_USE_CUDA) - itk_module_target_export(ITKCudaCommon) - endif() if(${ITK_VERSION} VERSION_LESS 5.3) ## Set the default target properties for RTK diff --git a/itk-module.cmake b/itk-module.cmake index 1cf9d7954..becf1c6cd 100644 --- a/itk-module.cmake +++ b/itk-module.cmake @@ -37,10 +37,8 @@ set(RTK_TEST_DEPENDS # # ----------------------------------------- # # CUDA optional dependencies -if(ITK_SOURCE_DIR) - if(${RTK_USE_CUDA}) - list(APPEND RTK_DEPENDS ITKCudaCommon) - endif() +if(${RTK_USE_CUDA}) + list(APPEND RTK_DEPENDS CudaCommon) endif() #========================================================= diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 316b13ddc..b6bc47151 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -128,11 +128,9 @@ endif() #========================================================= itk_module_add_library(RTK ${RTK_SRCS}) -target_link_libraries(RTK LINK_PUBLIC lpsolve55) +target_link_libraries(RTK PUBLIC lpsolve55) if (RTK_USE_CUDA) - target_link_libraries(RTK LINK_PUBLIC ITKCudaCommon) - target_link_libraries(RTK LINK_PUBLIC CUDA::cufft) - target_link_libraries(RTK LINK_PUBLIC CUDA::cublas) + target_link_libraries(RTK PUBLIC CUDA::cufft CUDA::cublas) set_property(TARGET RTK PROPERTY CUDA_STANDARD ${CMAKE_CXX_STANDARD}) endif () diff --git a/utilities/ITKCudaCommon/CMakeLists.txt b/utilities/ITKCudaCommon/CMakeLists.txt deleted file mode 100644 index db2f48e7f..000000000 --- a/utilities/ITKCudaCommon/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -project(ITKCudaCommon) - -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/CMake) - -enable_language(CUDA) -find_package(CUDAToolkit REQUIRED) -include_directories(${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}) -set(CMAKE_CUDA_RUNTIME_LIBRARY Static) - -set(ITKCudaCommon_LIBRARIES ITKCudaCommon) -set(ITKCudaCommon_SYSTEM_INCLUDE_DIRS ${CUDA_INCLUDE_DIRS}) -set(ITKCudaCommon_SYSTEM_LIBRARY_DIRS ${CUDA_LIBRARIES}) -set(ITKCudaCommon_INCLUDE_DIRS ${ITKCudaCommon_SYSTEM_INCLUDE_DIRS} - ${ITKCudaCommon_SOURCE_DIR}/include PARENT_SCOPE) - -#========================================================= -# Installation variables -#========================================================= -if(NOT ITKCudaCommon_INSTALL_RUNTIME_DIR) - set(ITKCudaCommon_INSTALL_RUNTIME_DIR bin) -endif() -if(NOT ITKCudaCommon_INSTALL_LIB_DIR) - set(ITKCudaCommon_INSTALL_LIB_DIR lib) -endif() -if(NOT ITKCudaCommon_INSTALL_ARCHIVE_DIR) - set(ITKCudaCommon_INSTALL_ARCHIVE_DIR lib) -endif() -if(NOT ITKCudaCommon_INSTALL_INCLUDE_DIR) - set(ITKCudaCommon_INSTALL_INCLUDE_DIR include/ITKCudaCommon) -endif() -if(NOT ITKCudaCommon_INSTALL_PACKAGE_DIR) - set(ITKCudaCommon_INSTALL_PACKAGE_DIR "lib/cmake/ITKCudaCommon") -endif() - -include_directories(${ITKCudaCommon_INCLUDE_DIRS}) - -if(NOT ITK_SOURCE_DIR) - add_subdirectory(src) -else() - set(itk-module ITKCudaCommon) - init_module_vars() - itk_module_impl() -endif() diff --git a/utilities/ITKCudaCommon/LICENSE b/utilities/ITKCudaCommon/LICENSE deleted file mode 100644 index 62589edd1..000000000 --- a/utilities/ITKCudaCommon/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - https://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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 - - https://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. diff --git a/utilities/ITKCudaCommon/README b/utilities/ITKCudaCommon/README deleted file mode 100644 index e69de29bb..000000000 diff --git a/utilities/ITKCudaCommon/include/itkCudaContextManager.h b/utilities/ITKCudaCommon/include/itkCudaContextManager.h deleted file mode 100644 index 7b83cf8b6..000000000 --- a/utilities/ITKCudaCommon/include/itkCudaContextManager.h +++ /dev/null @@ -1,66 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkCudaContextManager_h -#define itkCudaContextManager_h - -#include "itkCudaUtil.h" -#include -#include "itkCudaWin32Header.h" - -// -// Singleton class for CudaContextManager -// - -/** \class CudaContextManager - * - * \brief Class to store the Cuda context. - * - * \ingroup ITKCudaCommon - */ -namespace itk -{ -class ITKCudaCommon_EXPORT CudaContextManager : public LightObject -{ -public: - static CudaContextManager * - GetInstance(); - - static void - DestroyInstance(); - - CUcontext * - GetCurrentContext(); - - int - GetCurrentDevice(); - -private: - CudaContextManager(); - ~CudaContextManager() override; - - CUcontext m_Context; - int m_Device; - int m_DeviceIdx; - int m_NumberOfDevices; - - static CudaContextManager * m_Instance; - static bool m_Initialized; -}; -} // namespace itk - -#endif diff --git a/utilities/ITKCudaCommon/include/itkCudaDataManager.h b/utilities/ITKCudaCommon/include/itkCudaDataManager.h deleted file mode 100644 index 4fc85b829..000000000 --- a/utilities/ITKCudaCommon/include/itkCudaDataManager.h +++ /dev/null @@ -1,257 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkCudaDataManager_h -#define itkCudaDataManager_h - -#include "itkObject.h" -#include "itkDataObject.h" -#include "itkObjectFactory.h" -#include "itkCudaUtil.h" -#include "itkCudaContextManager.h" -#include "itkCudaWin32Header.h" - -#include -#include - -//#define VERBOSE - -namespace itk -{ -class ITKCudaCommon_EXPORT GPUMemPointer : public Object -{ -public: - using Self = GPUMemPointer; - using Superclass = Object; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - - itkNewMacro(Self); - itkTypeMacro(GPUMemPointer, Object); - - void - Allocate(size_t bufferSize) - { -#ifdef VERBOSE - if (m_GPUBuffer) - std::cout << this << "::Freed GPU buffer of size " << m_BufferSize << " Bytes" - << " : " << m_GPUBuffer << std::endl; -#endif - m_BufferSize = bufferSize; - CUDA_CHECK(cudaFree(m_GPUBuffer)); - CUDA_CHECK(cudaMalloc(&m_GPUBuffer, bufferSize)); -#ifdef VERBOSE - std::cout << this << "::Allocate Create GPU buffer of size " << bufferSize << " Bytes" - << " : " << m_GPUBuffer << std::endl; -#endif - } - - void - Free() - { -#ifdef VERBOSE - if (m_GPUBuffer) - std::cout << this << "::Freed GPU buffer of size " << m_BufferSize << " Bytes" - << " : " << m_GPUBuffer << std::endl; -#endif - CUDA_CHECK(cudaFree(m_GPUBuffer)); - m_GPUBuffer = nullptr; - m_BufferSize = 0; - } - - ~GPUMemPointer() override - { - if (m_GPUBuffer) - { - this->Free(); - } - } - - void * - GetPointer() - { - return m_GPUBuffer; - } - - void * - GetPointerPtr() - { - return &m_GPUBuffer; - } - - size_t - GetBufferSize() const - { - return m_BufferSize; - } - -protected: - GPUMemPointer() - { - m_GPUBuffer = nullptr; - m_BufferSize = 0; - } - - void * m_GPUBuffer; - size_t m_BufferSize; -}; - -/** \class CudaDataManager - * \brief GPU memory manager implemented using Cuda. Required by CudaImage class. - * - * This class serves as a base class for Cuda data container for CudaImage class, - * which is similar to ImageBase class for Image class. However, all the image-related - * meta data will be already stored in image class (parent of CudaImage), therefore - * we did not name it CudaImageBase. Rather, this class is a Cuda-specific data manager - * that provides functionalities for RAM-GRAM data synchronization and grafting Cuda data. - * - * \ingroup ITKCudaCommon - */ -class ITKCudaCommon_EXPORT CudaDataManager : public Object -{ -public: - using Self = CudaDataManager; - using Superclass = Object; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - using ModifiedTimeType = unsigned long; - - itkNewMacro(Self); - itkTypeMacro(CudaDataManager, Object); - - /** total buffer size in bytes */ - void - SetBufferSize(size_t num); - - size_t - GetBufferSize() const - { - return m_BufferSize; - } - - void - SetBufferFlag(int flags); - - void - SetCPUBufferPointer(void * ptr); - - void - SetCPUDirtyFlag(bool isDirty); - - void - SetGPUDirtyFlag(bool isDirty); - - /** Make GPU up-to-date and mark CPU as dirty. - * Call this function when you want to modify CPU data */ - void - SetCPUBufferDirty(); - - /** Make CPU up-to-date and mark GPU as dirty. - * Call this function when you want to modify Cuda data */ - void - SetGPUBufferDirty(); - - bool - IsCPUBufferDirty() const - { - return m_IsCPUBufferDirty; - } - - bool - IsGPUBufferDirty() const - { - return m_IsGPUBufferDirty; - } - - /** actual Cuda->CPU memory copy takes place here */ - virtual void - UpdateCPUBuffer(); - - /** actual CPU->Cuda memory copy takes place here */ - virtual void - UpdateGPUBuffer(); - - void - Allocate(); - void - Free(); - - /** Synchronize CPU and Cuda buffers (using dirty flags) */ - bool - Update(); - - /** Method for grafting the content of one CudaDataManager into another one */ - virtual void - Graft(const CudaDataManager * data); - - /** Initialize CudaDataManager */ - virtual void - Initialize(); - - /** Get Cuda buffer pointer */ - void * - GetGPUBufferPointer(); - - /** Get CPU buffer pointer */ - void * - GetCPUBufferPointer(); - - /** Get Cuda buffer size without calling GetGPUBufferPointer, which - * which would trigger an unwanted CPU -> GPU memory transfer */ - size_t - GetGPUBufferSize() - { - return m_GPUBuffer->GetBufferSize(); - } - -protected: - CudaDataManager(); - ~CudaDataManager() override; - void - PrintSelf(std::ostream & os, Indent indent) const override; - -private: - CudaDataManager(const Self &) = delete; // purposely not implemented - void - operator=(const Self &) = delete; - -protected: - size_t m_BufferSize; // # of bytes - - CudaContextManager * m_ContextManager; - - /** buffer type */ - int m_MemFlags; - - /** buffer pointers */ - GPUMemPointer::Pointer m_GPUBuffer; - void * m_CPUBuffer; - - /** checks if buffer needs to be updated */ - bool m_IsGPUBufferDirty; - bool m_IsCPUBufferDirty; - - /** whether gpu buffers from gpu memory should be released when dirty */ - bool m_ReleaseDirtyGPUBuffer; - - /** Mutex lock to prevent r/w hazard for multithreaded code */ - std::mutex m_Mutex; -}; - -} // namespace itk - -#endif diff --git a/utilities/ITKCudaCommon/include/itkCudaImage.h b/utilities/ITKCudaCommon/include/itkCudaImage.h deleted file mode 100644 index c113be039..000000000 --- a/utilities/ITKCudaCommon/include/itkCudaImage.h +++ /dev/null @@ -1,320 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkCudaImage_h -#define itkCudaImage_h - -#include "itkImage.h" -#include "itkCudaImageDataManager.h" -#include "itkCudaWin32Header.h" -#include "itkVersion.h" -#include "itkObjectFactoryBase.h" - -namespace itk -{ -/** \class CudaImage - * \brief Templated n-dimensional image class for the Cuda. - * - * Derived from itk Image class to use with Cuda image filters. - * This class manages both CPU and Cuda memory implicitly, and - * can be used with non-Cuda itk filters as well. Memory transfer - * between CPU and Cuda is done automatically and implicitly. - * - * \ingroup ITKCudaCommon - */ -template -class ITK_TEMPLATE_EXPORT CudaImage : public Image -{ -public: - using Self = CudaImage; - using Superclass = Image; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - using ConstWeakPointer = WeakPointer; - - itkNewMacro(Self); - - itkTypeMacro(CudaImage, Image); - - static constexpr unsigned int ImageDimension = VImageDimension; - - using PixelType = typename Superclass::PixelType; - using ValueType = typename Superclass::ValueType; - using InternalPixelType = typename Superclass::InternalPixelType; - using IOPixelType = typename Superclass::IOPixelType; - using DirectionType = typename Superclass::DirectionType; - using SpacingType = typename Superclass::SpacingType; - using PixelContainer = typename Superclass::PixelContainer; - using SizeType = typename Superclass::SizeType; - using IndexType = typename Superclass::IndexType; - using OffsetType = typename Superclass::OffsetType; - using RegionType = typename Superclass::RegionType; - using PixelContainerPointer = typename PixelContainer::Pointer; - using PixelContainerConstPointer = typename PixelContainer::ConstPointer; - using AccessorType = typename Superclass::AccessorType; - - using ModifiedTimeType = unsigned long; - using AccessorFunctorType = DefaultPixelAccessorFunctor; - - using NeighborhoodAccessorFunctorType = NeighborhoodAccessorFunctor; - - /** - * example usage: - * using OutputImageType = typename ImageType::template Rebind< float >::Type; - * - */ - template - struct Rebind - { - using Type = itk::CudaImage; - }; - - // - // Allocate CPU and Cuda memory space - // - void - Allocate(bool initializePixels = false) override; - - void - Initialize() override; - - void - FillBuffer(const TPixel & value); - - void - SetPixel(const IndexType & index, const TPixel & value); - - const TPixel & - GetPixel(const IndexType & index) const; - - TPixel & - GetPixel(const IndexType & index); - - const TPixel & operator[](const IndexType & index) const; - - TPixel & operator[](const IndexType & index); - - /** Explicit synchronize CPU/Cuda buffers */ - void - UpdateBuffers(); - - // - // Get CPU buffer pointer - // - TPixel * - GetBufferPointer() override; - - const TPixel * - GetBufferPointer() const override; - - /** Return the Pixel Accessor object */ - AccessorType - GetPixelAccessor(void) - { - m_DataManager->SetGPUBufferDirty(); - return Superclass::GetPixelAccessor(); - } - - /** Return the Pixel Accesor object */ - const AccessorType - GetPixelAccessor(void) const - { - m_DataManager->UpdateCPUBuffer(); - return Superclass::GetPixelAccessor(); - } - - /** Return the NeighborhoodAccessor functor */ - NeighborhoodAccessorFunctorType - GetNeighborhoodAccessor() - { - m_DataManager->SetGPUBufferDirty(); - // return Superclass::GetNeighborhoodAccessor(); - return NeighborhoodAccessorFunctorType(); - } - - /** Return the NeighborhoodAccessor functor */ - const NeighborhoodAccessorFunctorType - GetNeighborhoodAccessor() const - { - m_DataManager->UpdateCPUBuffer(); - // return Superclass::GetNeighborhoodAccessor(); - return NeighborhoodAccessorFunctorType(); - } - - void - SetPixelContainer(PixelContainer * container); - - /** Return a pointer to the container. */ - PixelContainer * - GetPixelContainer() - { - m_DataManager->SetGPUBufferDirty(); - return Superclass::GetPixelContainer(); - } - - const PixelContainer * - GetPixelContainer() const - { - m_DataManager->UpdateCPUBuffer(); - return Superclass::GetPixelContainer(); - } - - itkGetModifiableObjectMacro(DataManager, CudaImageDataManager); - - CudaDataManager::Pointer - GetCudaDataManager() const; - - /** Overload the SetBufferedRegion function because if the size changes we need - * to invalidated the GPU buffer */ - void - SetBufferedRegion(const RegionType & region) override; - - /* Override DataHasBeenGenerated() in DataObject class. - * We need this because CPU time stamp is always bigger - * than Cuda's. That is because Modified() is called at - * the end of each filter in the pipeline so although we - * increment Cuda's time stamp in CudaGenerateData() the - * CPU's time stamp will be increased after that. - */ - void - DataHasBeenGenerated() override - { - Superclass::DataHasBeenGenerated(); - if (m_DataManager->IsCPUBufferDirty()) - { - m_DataManager->Modified(); - } - } - - /** Graft the data and information from one CudaImage to another. */ - void - Graft(const Self * data); - -protected: - void - Graft(const DataObject * data) override; - - CudaImage(); - virtual ~CudaImage(); - using Superclass::Graft; - -private: - // functions that are purposely not implemented - CudaImage(const Self &); - void - operator=(const Self &); - - typename CudaImageDataManager::Pointer m_DataManager; -}; - -class ITKCudaCommon_EXPORT CudaImageFactory : public itk::ObjectFactoryBase -{ -public: - using Self = CudaImageFactory; - using Superclass = itk::ObjectFactoryBase; - using Pointer = itk::SmartPointer; - using ConstPointer = itk::SmartPointer; - - /** Class methods used to interface with the registered factories. */ - const char * - GetITKSourceVersion() const override - { - return ITK_SOURCE_VERSION; - } - const char * - GetDescription() const override - { - return "A Factory for CudaImage"; - } - - /** Method for class instantiation. */ - itkFactorylessNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(CudaImageFactory, itk::ObjectFactoryBase); - - /** Register one factory of this type */ - static void - RegisterOneFactory(void) - { - CudaImageFactory::Pointer factory = CudaImageFactory::New(); - - itk::ObjectFactoryBase::RegisterFactory(factory); - } - -private: - CudaImageFactory(const Self &); // purposely not implemented - void - operator=(const Self &); // purposely not implemented - -#define OverrideImageTypeMacro(pt, dm) \ - this->RegisterOverride(typeid(itk::Image).name(), \ - typeid(itk::CudaImage).name(), \ - "Cuda Image Override", \ - true, \ - itk::CreateObjectFunction>::New()) - - CudaImageFactory() - { - if (IsCudaAvailable()) - { - // 1/2/3D - OverrideImageTypeMacro(unsigned char, 1); - OverrideImageTypeMacro(signed char, 1); - OverrideImageTypeMacro(int, 1); - OverrideImageTypeMacro(unsigned int, 1); - OverrideImageTypeMacro(float, 1); - OverrideImageTypeMacro(double, 1); - - OverrideImageTypeMacro(unsigned char, 2); - OverrideImageTypeMacro(signed char, 2); - OverrideImageTypeMacro(int, 2); - OverrideImageTypeMacro(unsigned int, 2); - OverrideImageTypeMacro(float, 2); - OverrideImageTypeMacro(double, 2); - - OverrideImageTypeMacro(unsigned char, 3); - OverrideImageTypeMacro(signed char, 3); - OverrideImageTypeMacro(int, 3); - OverrideImageTypeMacro(unsigned int, 3); - OverrideImageTypeMacro(float, 3); - OverrideImageTypeMacro(double, 3); - } - } -}; - -template -class ITK_TEMPLATE_EXPORT CudaTraits -{ -public: - using Type = T; -}; - -template -class CudaTraits> -{ -public: - using Type = CudaImage; -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkCudaImage.hxx" -#endif - -#endif diff --git a/utilities/ITKCudaCommon/include/itkCudaImage.hxx b/utilities/ITKCudaCommon/include/itkCudaImage.hxx deleted file mode 100644 index 4778b7d32..000000000 --- a/utilities/ITKCudaCommon/include/itkCudaImage.hxx +++ /dev/null @@ -1,236 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkCudaImage_hxx -#define itkCudaImage_hxx - -#include "itkCudaImage.h" - -namespace itk -{ -// -// Constructor -// -template -CudaImage::CudaImage() -{ - m_DataManager = CudaImageDataManager>::New(); -} - -template -CudaImage::~CudaImage() -{} - -template -void -CudaImage::Allocate(bool initializePixels) -{ - // allocate CPU memory - calling Allocate() in superclass - Superclass::Allocate(initializePixels); - - // allocate Cuda memory - this->ComputeOffsetTable(); - SizeValueType numPixel = this->GetOffsetTable()[VImageDimension]; - m_DataManager->SetBufferSize(sizeof(TPixel) * numPixel); - m_DataManager->SetImagePointer(this); - m_DataManager->SetCPUBufferPointer(Superclass::GetBufferPointer()); - - // When we allocate both buffers are dirty and set so to avoid useless transfers - // between GPU and CPU. - m_DataManager->SetGPUDirtyFlag(true); - m_DataManager->SetCPUDirtyFlag(true); - - // If initialize pixel is set then we set the CPU dirty flag to false - if (initializePixels) - { - m_DataManager->SetCPUDirtyFlag(false); - } -} - -template -void -CudaImage::Initialize() -{ - // CPU image initialize - Superclass::Initialize(); - - m_DataManager = CudaImageDataManager>::New(); -} - -template -void -CudaImage::SetBufferedRegion(const RegionType & region) -{ - // If the regions are the same we don't change - const RegionType currentRegion = this->GetBufferedRegion(); - bool sameRegions = true; - for (unsigned int i = 0; i < VImageDimension; i++) - { - if (region.GetSize()[i] != currentRegion.GetSize()[i] || region.GetIndex()[i] != currentRegion.GetIndex()[i]) - { - sameRegions = false; - break; - } - } - - if (sameRegions) - { - return; - } - - Superclass::SetBufferedRegion(region); - SizeValueType numPixel = this->GetOffsetTable()[VImageDimension]; - m_DataManager->SetBufferSize(sizeof(TPixel) * numPixel); - m_DataManager->SetCPUDirtyFlag(false); // prevent the GPU to copy to the CPU - m_DataManager->SetGPUBufferDirty(); -} - - -template -void -CudaImage::FillBuffer(const TPixel & value) -{ - m_DataManager->SetGPUBufferDirty(); - Superclass::FillBuffer(value); -} - -template -void -CudaImage::SetPixel(const IndexType & index, const TPixel & value) -{ - m_DataManager->SetGPUBufferDirty(); - Superclass::SetPixel(index, value); -} - -template -const TPixel & -CudaImage::GetPixel(const IndexType & index) const -{ - m_DataManager->UpdateCPUBuffer(); - return Superclass::GetPixel(index); -} - -template -TPixel & -CudaImage::GetPixel(const IndexType & index) -{ - m_DataManager->UpdateCPUBuffer(); - return Superclass::GetPixel(index); -} - -template -TPixel & CudaImage::operator[](const IndexType & index) -{ - m_DataManager->UpdateCPUBuffer(); - return Superclass::operator[](index); -} - -template -const TPixel & CudaImage::operator[](const IndexType & index) const -{ - m_DataManager->UpdateCPUBuffer(); - return Superclass::operator[](index); -} - -template -void -CudaImage::SetPixelContainer(PixelContainer * container) -{ - Superclass::SetPixelContainer(container); - m_DataManager->SetImagePointer(this); - m_DataManager->SetCPUBufferPointer(Superclass::GetBufferPointer()); - m_DataManager->SetCPUDirtyFlag(this->GetBufferPointer() == nullptr); - m_DataManager->SetGPUDirtyFlag(true); - SizeValueType numPixel = this->GetOffsetTable()[VImageDimension]; - m_DataManager->SetBufferSize(sizeof(TPixel) * numPixel); -} - -template -void -CudaImage::UpdateBuffers() -{ - m_DataManager->UpdateCPUBuffer(); - m_DataManager->UpdateGPUBuffer(); -} - -template -TPixel * -CudaImage::GetBufferPointer() -{ - /* less conservative version - if you modify pixel value using - * this pointer then you must set the image as modified manually!!! */ - m_DataManager->UpdateCPUBuffer(); - m_DataManager->SetGPUDirtyFlag(true); - return Superclass::GetBufferPointer(); -} - -template -const TPixel * -CudaImage::GetBufferPointer() const -{ - // const does not change buffer, but if CPU is dirty then make it up-to-date - m_DataManager->UpdateCPUBuffer(); - m_DataManager->SetGPUDirtyFlag(true); // THIS IS NEEDED BECAUSE NON-CONST ITERATORS USE THIS FUNCTION - return Superclass::GetBufferPointer(); -} - -template -CudaDataManager::Pointer -CudaImage::GetCudaDataManager() const -{ - using CudaImageDataSuperclass = typename CudaImageDataManager::Superclass; - using CudaImageDataSuperclassPointer = typename CudaImageDataSuperclass::Pointer; - - return static_cast(m_DataManager.GetPointer()); -} - -template -void -CudaImage::Graft(const Self * data) -{ - using CudaImageDataManagerType = CudaImageDataManager; - - // call the superclass' implementation - Superclass::Graft(dynamic_cast(data)); - m_DataManager = dynamic_cast(data->GetCudaDataManager().GetPointer()); - return; -} - -template -void -CudaImage::Graft(const DataObject * data) -{ - if (data) - { - // Attempt to cast data to an Image - const auto * const cuImgData = dynamic_cast(data); - if (cuImgData != nullptr) - { - this->Graft(cuImgData); - } - else - { - // pointer could not be cast back down - itkExceptionMacro(<< "itk::CudaImage::Graft() cannot cast " << typeid(data).name() << " to " - << typeid(const Self *).name()); - } - } -} - -} // namespace itk - -#endif diff --git a/utilities/ITKCudaCommon/include/itkCudaImageDataManager.h b/utilities/ITKCudaCommon/include/itkCudaImageDataManager.h deleted file mode 100644 index c6d4be5ab..000000000 --- a/utilities/ITKCudaCommon/include/itkCudaImageDataManager.h +++ /dev/null @@ -1,102 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkCudaImageDataManager_h -#define itkCudaImageDataManager_h - -#include -#include -#include -#include "itkCudaUtil.h" -#include "itkCudaDataManager.h" -#include "itkCudaContextManager.h" - -namespace itk -{ -/** - * \class CudaImageDataManager - * - * DataManager for CudaImage. This class will take care of data synchronization - * between CPU Image and Cuda Image. - * - * \ingroup ITKCudaCommon - */ -template -class ITK_TEMPLATE_EXPORT CudaImageDataManager : public CudaDataManager -{ -public: - using Self = CudaImageDataManager; - using Superclass = CudaDataManager; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - - using RegionType = typename ImageType::RegionType; - using IndexType = typename ImageType::IndexType; - using SizeType = typename ImageType::SizeType; - - itkNewMacro(Self); - itkTypeMacro(CudaImageDataManager, CudaDataManager); - - itkGetModifiableObjectMacro(GPUBufferedRegionIndex, CudaDataManager); - itkGetModifiableObjectMacro(GPUBufferedRegionSize, CudaDataManager); - - void - SetImagePointer(ImageType * img); - ImageType * - GetImagePointer() - { - return this->m_Image; - } - - /** actual Cuda->CPU memory copy takes place here */ - virtual void - MakeCPUBufferUpToDate(); - - /** actual CPU->Cuda memory copy takes place here */ - virtual void - MakeGPUBufferUpToDate(); - - /** Grafting Cuda Image Data */ - void - Graft(const CudaDataManager * data) override; - -protected: - CudaImageDataManager() {} - virtual ~CudaImageDataManager() {} - - void - PrintSelf(std::ostream & os, Indent indent) const override; - -private: - CudaImageDataManager(const Self &); // purposely not implemented - void - operator=(const Self &); - - ImageType * m_Image; - IndexType m_BufferedRegionIndex; - SizeType m_BufferedRegionSize; - typename CudaDataManager::Pointer m_GPUBufferedRegionIndex; - typename CudaDataManager::Pointer m_GPUBufferedRegionSize; -}; - -} // namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkCudaImageDataManager.hxx" -#endif - -#endif diff --git a/utilities/ITKCudaCommon/include/itkCudaImageDataManager.hxx b/utilities/ITKCudaCommon/include/itkCudaImageDataManager.hxx deleted file mode 100644 index 277c16ab2..000000000 --- a/utilities/ITKCudaCommon/include/itkCudaImageDataManager.hxx +++ /dev/null @@ -1,156 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkCudaImageDataManager_hxx -#define itkCudaImageDataManager_hxx - -#include "itkCudaImageDataManager.h" -#include "itkCudaUtil.h" -//#define VERBOSE - -namespace itk -{ - -template -void -CudaImageDataManager::SetImagePointer(ImageType * img) -{ - m_Image = img; - - RegionType region = m_Image->GetBufferedRegion(); - IndexType index = region.GetIndex(); - SizeType size = region.GetSize(); - - for (unsigned int d = 0; d < ImageType::ImageDimension; d++) - { - m_BufferedRegionIndex[d] = index[d]; - m_BufferedRegionSize[d] = size[d]; - } - - m_GPUBufferedRegionIndex = CudaDataManager::New(); - m_GPUBufferedRegionIndex->SetBufferSize(sizeof(int) * ImageType::ImageDimension); - m_GPUBufferedRegionIndex->SetCPUBufferPointer(&m_BufferedRegionIndex); - m_GPUBufferedRegionIndex->SetGPUBufferDirty(); - - m_GPUBufferedRegionSize = CudaDataManager::New(); - m_GPUBufferedRegionSize->SetBufferSize(sizeof(int) * ImageType::ImageDimension); - m_GPUBufferedRegionSize->SetCPUBufferPointer(&m_BufferedRegionSize); - m_GPUBufferedRegionSize->SetGPUBufferDirty(); -} - -template -void -CudaImageDataManager::MakeCPUBufferUpToDate() -{ - if (m_Image) - { - m_Mutex.lock(); - - TimeStamp gpu_time_stamp = this->GetTimeStamp(); - TimeStamp cpu_time_stamp = m_Image->GetTimeStamp(); - - /* Why we check dirty flag and time stamp together? - * Because existing CPU image filters do not use pixel/buffer - * access function in CudaImage and therefore dirty flag is not - * correctly managed. Therefore, we check the time stamp of - * CPU and Cuda data as well - */ - if ((m_IsCPUBufferDirty || (gpu_time_stamp > cpu_time_stamp)) && m_GPUBuffer.GetPointer() != nullptr && - m_CPUBuffer != nullptr) - { - cudaError_t errid; -#ifdef VERBOSE - std::cout << this << ": GPU->CPU data copy" << std::endl; -#endif - - CUDA_CHECK(cuCtxSetCurrent( - *(this->m_ContextManager->GetCurrentContext()))); // This is necessary when running multithread to bind the host - // CPU thread to the right context - errid = cudaMemcpy(m_CPUBuffer, m_GPUBuffer->GetPointer(), m_BufferSize, cudaMemcpyDeviceToHost); - CudaCheckError(errid, __FILE__, __LINE__, ITK_LOCATION); - - m_Image->Modified(); - - m_IsCPUBufferDirty = false; - m_IsGPUBufferDirty = false; - } - - m_Mutex.unlock(); - } -} - -template -void -CudaImageDataManager::MakeGPUBufferUpToDate() -{ - if (m_Image) - { - m_Mutex.lock(); - - TimeStamp gpu_time_stamp = this->GetTimeStamp(); - TimeStamp cpu_time_stamp = m_Image->GetTimeStamp(); - - /* Why we check dirty flag and time stamp together? - * Because existing CPU image filters do not use pixel/buffer - * access function in CudaImage and therefore dirty flag is not - * correctly managed. Therefore, we check the time stamp of - * CPU and GPU data as well - */ - if ((m_IsGPUBufferDirty || (gpu_time_stamp < cpu_time_stamp)) && m_CPUBuffer != nullptr && - m_GPUBuffer.GetPointer() != nullptr) - { - cudaError_t errid; -#ifdef VERBOSE - std::cout << "CPU->GPU data copy" << std::endl; -#endif - - CUDA_CHECK(cuCtxSetCurrent( - *(this->m_ContextManager->GetCurrentContext()))); // This is necessary when running multithread to bind the host - // CPU thread to the right context - errid = cudaMemcpy(m_GPUBuffer->GetPointer(), m_CPUBuffer, m_BufferSize, cudaMemcpyHostToDevice); - CudaCheckError(errid, __FILE__, __LINE__, ITK_LOCATION); - - this->SetTimeStamp(cpu_time_stamp); - - m_IsCPUBufferDirty = false; - m_IsGPUBufferDirty = false; - } - - m_Mutex.unlock(); - } -} - -template -void -CudaImageDataManager::Graft(const CudaDataManager * data) -{ - Superclass::Graft(data); -} - -template -void -CudaImageDataManager::PrintSelf(std::ostream & os, Indent indent) const -{ - Superclass::PrintSelf(os, indent); - - os << indent << "m_GPUBufferedRegionIndex: " << m_GPUBufferedRegionIndex << std::endl; - os << indent << "m_GPUBufferedRegionSize: " << m_GPUBufferedRegionSize << std::endl; -} - -} // namespace itk - -#endif diff --git a/utilities/ITKCudaCommon/include/itkCudaImageToImageFilter.h b/utilities/ITKCudaCommon/include/itkCudaImageToImageFilter.h deleted file mode 100644 index 075f0d9b6..000000000 --- a/utilities/ITKCudaCommon/include/itkCudaImageToImageFilter.h +++ /dev/null @@ -1,113 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkCudaImageToImageFilter_h -#define itkCudaImageToImageFilter_h - -#include "itkImageToImageFilter.h" -#include "itkCudaImage.h" - -namespace itk -{ - -/** \class CudaImageToImageFilter - * - * \brief class to abstract the behaviour of the Cuda filters. - * - * CudaImageToImageFilter is the Cuda version of ImageToImageFilter. - * This class can accept both CPU and GPU image as input and output, - * and apply filter accordingly. If Cuda is available for use, then - * GPUGenerateData() is called. Otherwise, GenerateData() in the - * parent class (i.e., ImageToImageFilter) will be called. - * - * \ingroup ITKCudaCommon - */ -template > -class ITK_TEMPLATE_EXPORT CudaImageToImageFilter : public TParentImageFilter -{ -public: - /** Standard class type alias. */ - using Self = CudaImageToImageFilter; - using Superclass = TParentImageFilter; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(CudaImageToImageFilter, TParentImageFilter); - - /** Superclass type alias. */ - using DataObjectIdentifierType = typename Superclass::DataObjectIdentifierType; - using OutputImageRegionType = typename Superclass::OutputImageRegionType; - using OutputImagePixelType = typename Superclass::OutputImagePixelType; - - /** Some convenient type alias. */ - using InputImageType = TInputImage; - using InputImagePointer = typename InputImageType::Pointer; - using InputImageConstPointer = typename InputImageType::ConstPointer; - using InputImageRegionType = typename InputImageType::RegionType; - using InputImagePixelType = typename InputImageType::PixelType; - - /** ImageDimension constants */ - static constexpr unsigned int InputImageDimension = TInputImage::ImageDimension; - static constexpr unsigned int OutputImageDimension = TOutputImage::ImageDimension; - - // macro to set if Cuda is used - itkSetMacro(GPUEnabled, bool); - itkGetConstMacro(GPUEnabled, bool); - itkBooleanMacro(GPUEnabled); - - void - GenerateData() override; - virtual void - GraftOutput(typename itk::CudaTraits::Type * output); - virtual void - GraftOutput(const DataObjectIdentifierType & key, typename itk::CudaTraits::Type * output); - -protected: - void - GraftOutput(DataObject * output) override; - void - GraftOutput(const DataObjectIdentifierType & key, DataObject * output) override; - CudaImageToImageFilter(); - ~CudaImageToImageFilter(); - - virtual void - PrintSelf(std::ostream & os, Indent indent) const; - - virtual void - GPUGenerateData() - {} - -private: - CudaImageToImageFilter(const Self &); // purposely not implemented - void - operator=(const Self &); // purposely not implemented - - bool m_GPUEnabled; -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkCudaImageToImageFilter.hxx" -#endif - -#endif diff --git a/utilities/ITKCudaCommon/include/itkCudaImageToImageFilter.hxx b/utilities/ITKCudaCommon/include/itkCudaImageToImageFilter.hxx deleted file mode 100644 index db6b44985..000000000 --- a/utilities/ITKCudaCommon/include/itkCudaImageToImageFilter.hxx +++ /dev/null @@ -1,120 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkCudaImageToImageFilter_hxx -#define itkCudaImageToImageFilter_hxx - -#include "itkCudaImageToImageFilter.h" - -namespace itk -{ - -template -CudaImageToImageFilter::CudaImageToImageFilter() - : m_GPUEnabled(true) -{} - -template -CudaImageToImageFilter::~CudaImageToImageFilter() -{} - -template -void -CudaImageToImageFilter::PrintSelf(std::ostream & os, Indent indent) const -{ - Superclass::PrintSelf(os, indent); - os << indent << "GPU: " << (m_GPUEnabled ? "Enabled" : "Disabled") << std::endl; -} - -template -void -CudaImageToImageFilter::GenerateData() -{ - if (!m_GPUEnabled) // call CPU update function - { - Superclass::GenerateData(); - } - else // call Cuda update function - { - // Call a method to allocate memory for the filter's outputs - this->AllocateOutputs(); - - GPUGenerateData(); - } -} - -template -void -CudaImageToImageFilter::GraftOutput( - typename itk::CudaTraits::Type * output) -{ - using CudaOutputImage = typename itk::CudaTraits::Type; - typename CudaOutputImage::Pointer cudaImage = dynamic_cast(this->GetOutput()); - - cudaImage->Graft(output); -} - -template -void -CudaImageToImageFilter::GraftOutput(DataObject * output) -{ - using CudaOutputImage = typename itk::CudaTraits::Type; - CudaOutputImage * cudaImage = dynamic_cast(output); - if (cudaImage) - { - this->GraftOutput(cudaImage); - } - else - { - itkExceptionMacro(<< "itk::CudaImageToImageFilter::GraftOutput() cannot cast " << typeid(output).name() << " to " - << typeid(CudaOutputImage *).name()); - } -} - -template -void -CudaImageToImageFilter::GraftOutput( - const DataObjectIdentifierType & key, - typename itk::CudaTraits::Type * output) -{ - using CudaOutputImage = typename itk::CudaTraits::Type; - typename CudaOutputImage::Pointer cudaImage = dynamic_cast(this->ProcessObject::GetOutput(key)); - - cudaImage->Graft(output); -} - -template -void -CudaImageToImageFilter::GraftOutput(const DataObjectIdentifierType & key, - DataObject * output) -{ - using CudaOutputImage = typename itk::CudaTraits::Type; - CudaOutputImage * cudaImage = dynamic_cast(output); - if (cudaImage) - { - this->GraftOutput(key, cudaImage); - } - else - { - itkExceptionMacro(<< "itk::CudaImageToImageFilter::GraftOutput() cannot cast " << typeid(output).name() << " to " - << typeid(CudaOutputImage *).name()); - } -} - -} // end namespace itk - -#endif diff --git a/utilities/ITKCudaCommon/include/itkCudaInPlaceImageFilter.h b/utilities/ITKCudaCommon/include/itkCudaInPlaceImageFilter.h deleted file mode 100644 index bfb9ecf57..000000000 --- a/utilities/ITKCudaCommon/include/itkCudaInPlaceImageFilter.h +++ /dev/null @@ -1,115 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkCudaInPlaceImageFilter_h -#define itkCudaInPlaceImageFilter_h - -#include "itkInPlaceImageFilter.h" -#include "itkCudaImageToImageFilter.h" - -namespace itk -{ -/** \class CudaInPlaceImageFilter - * \brief Base class for Cuda filters that take an image as input and overwrite that image as the output - * - * This class is the base class for Cuda inplace filter. The template parameter for parent class type - * must be InPlaceImageFilter type so that the Cuda superclass of this class can be correctly defined - * (NOTE: TParentImageFilter::Superclass is used to define CudaImageToImageFilter class). - * - * \ingroup ITKCudaCommon - */ -template > -class ITK_TEMPLATE_EXPORT CudaInPlaceImageFilter - : public CudaImageToImageFilter -{ -public: - /** Standard class type alias. */ - using Self = CudaInPlaceImageFilter; - using GPUSuperclass = CudaImageToImageFilter; - using CPUSuperclass = TParentImageFilter; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - - /** Run-time type information (and related methods). */ - itkTypeMacro(CudaInPlaceImageFilter, CudaImageToImageFilter); - - /** Superclass type alias. */ - using OutputImageType = typename GPUSuperclass::OutputImageType; - using OutputImagePointer = typename GPUSuperclass::OutputImagePointer; - using OutputImageRegionType = typename GPUSuperclass::OutputImageRegionType; - using OutputImagePixelType = typename GPUSuperclass::OutputImagePixelType; - - /** ImageDimension constants */ - static constexpr unsigned int InputImageDimension = TInputImage::ImageDimension; - static constexpr unsigned int OutputImageDimension = TOutputImage::ImageDimension; - - /** Some convenient type alias. */ - using InputImageType = TInputImage; - using InputImagePointer = typename InputImageType::Pointer; - using InputImageConstPointer = typename InputImageType::ConstPointer; - using InputImageRegionType = typename InputImageType::RegionType; - using InputImagePixelType = typename InputImageType::PixelType; - -protected: - CudaInPlaceImageFilter(); - ~CudaInPlaceImageFilter(); - - virtual void - PrintSelf(std::ostream & os, Indent indent) const; - - /** The GenerateData method normally allocates the buffers for all - * of the outputs of a filter. Since InPlaceImageFilter's can use an - * overwritten version of the input for its output, the output - * buffer should not be allocated. When possible, we graft the input - * to the filter to the output. If an InPlaceFilter has multiple - * outputs, then it would need to override this method to graft one - * of its outputs and allocate the remaining. If a filter is - * threaded (i.e. it provides an implementation of - * ThreadedGenerateData()), this method is called automatically. If - * an InPlaceFilter is not threaded (i.e. it provides an - * implementation of GenerateData()), then this method (or - * equivalent) must be called in GenerateData(). */ - virtual void - AllocateOutputs(); - - /** InPlaceImageFilter may transfer ownership of the input bulk data - * to the output object. Once the output object owns the bulk data - * (done in AllocateOutputs()), the input object must release its - * hold on the bulk data. ProcessObject::ReleaseInputs() only - * releases the input bulk data when the user has set the - * ReleaseDataFlag. InPlaceImageFilter::ReleaseInputs() also - * releases the input that it has overwritten. - * - * \sa ProcessObject::ReleaseInputs() */ - virtual void - ReleaseInputs(); - -private: - CudaInPlaceImageFilter(const Self &); // purposely not implemented - void - operator=(const Self &); // purposely not implemented -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkCudaInPlaceImageFilter.hxx" -#endif - -#endif diff --git a/utilities/ITKCudaCommon/include/itkCudaInPlaceImageFilter.hxx b/utilities/ITKCudaCommon/include/itkCudaInPlaceImageFilter.hxx deleted file mode 100644 index 09c94ba5c..000000000 --- a/utilities/ITKCudaCommon/include/itkCudaInPlaceImageFilter.hxx +++ /dev/null @@ -1,133 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkCudaInPlaceImageFilter_hxx -#define itkCudaInPlaceImageFilter_hxx - -#include "itkCudaInPlaceImageFilter.h" - -namespace itk -{ -/** - * - */ -template -CudaInPlaceImageFilter::CudaInPlaceImageFilter() -{} - -/** - * - */ -template -CudaInPlaceImageFilter::~CudaInPlaceImageFilter() -{} - -template -void -CudaInPlaceImageFilter::PrintSelf(std::ostream & os, Indent indent) const -{ - GPUSuperclass::PrintSelf(os, indent); -} - -template -void -CudaInPlaceImageFilter::ReleaseInputs() -{ - CPUSuperclass::ReleaseInputs(); - - /* - if (this->GetGPUEnabled()) - { - // do something - std::cout << "ToDo: CudaInPlaceImageFilter::ReleaseInputs()" << std::endl; - } - else - { - CPUSuperclass::ReleaseInputs(); - } - */ -} - -template -void -CudaInPlaceImageFilter::AllocateOutputs() -{ - CPUSuperclass::AllocateOutputs(); - /* - if (this->GetGPUEnabled()) - { - // if told to run in place and the types support it, - if (this->GetInPlace() && this->CanRunInPlace()) - { - // Graft this first input to the output. Later, we'll need to - // remove the input's hold on the bulk data. - // - OutputImagePointer inputAsOutput = - dynamic_cast< TOutputImage * >(const_cast< TInputImage * >(this->GetInput())); - if (inputAsOutput) - { - this->GraftOutput(inputAsOutput); - } - else - { - // if we cannot cast the input to an output type, then allocate - // an output usual. - OutputImagePointer outputPtr; - - outputPtr = this->GetOutput(0); - outputPtr->SetBufferedRegion(outputPtr->GetRequestedRegion()); - outputPtr->Allocate(); - } - - using ImageBaseType = ImageBase< OutputImageDimension >; - typename ImageBaseType::Pointer outputPtr; - - // If there are more than one outputs, allocate the remaining outputs - for (unsigned int i = 1; i < this->GetNumberOfOutputs(); i++) - { - // Check whether the output is an image of the appropriate - // dimension (use ProcessObject's version of the GetInput() - // method since it returns the input as a pointer to a - // DataObject as opposed to the subclass version which - // static_casts the input to an TInputImage). - outputPtr = dynamic_cast< ImageBaseType * >(this->ProcessObject::GetOutput(i)); - - if (outputPtr) - { - outputPtr->SetBufferedRegion(outputPtr->GetRequestedRegion()); - outputPtr->Allocate(); - } - // if the output is not of similar type then it is assumed the - // the derived class allocated the output if needed. - } - - } - else - { - CPUSuperclass::AllocateOutputs(); - } - } - else - { - CPUSuperclass::AllocateOutputs(); - } - */ -} - -} // end of namespace itk - -#endif diff --git a/utilities/ITKCudaCommon/include/itkCudaMemoryProbe.h b/utilities/ITKCudaCommon/include/itkCudaMemoryProbe.h deleted file mode 100644 index 767211eb4..000000000 --- a/utilities/ITKCudaCommon/include/itkCudaMemoryProbe.h +++ /dev/null @@ -1,56 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkCudaMemoryProbe_h -#define itkCudaMemoryProbe_h - -#include "itkResourceProbe.h" -#include "itkIntTypes.h" -#include "itkCudaWin32Header.h" - -namespace itk -{ -/** \class CudaMemoryProbe - * - * \brief Computes the Cuda memory allocated between two points in code. - * - * This class allows the user to trace the Cuda memory charge between the - * execution of two pieces of code. It can be started and stopped in order to - * evaluate the execution over multiple passes. The values of memory are - * taken from cudaMemGetInfo. - * - * \ingroup ITKCudaCommon - */ -class ITKCudaCommon_EXPORT CudaMemoryProbe : public ResourceProbe -{ -public: - CudaMemoryProbe(); - ~CudaMemoryProbe() override; - - /** Type for measuring memory. */ - using CudaMemoryLoadType = OffsetValueType; - - /** Type for measuring the average memory. */ - using MeanCudaMemoryLoadType = double; - -protected: - CudaMemoryLoadType - GetInstantValue() const override; -}; -} // end namespace itk - -#endif // itkCudaMemoryProbe_h diff --git a/utilities/ITKCudaCommon/include/itkCudaUtil.h b/utilities/ITKCudaCommon/include/itkCudaUtil.h deleted file mode 100644 index 644d4f3c4..000000000 --- a/utilities/ITKCudaCommon/include/itkCudaUtil.h +++ /dev/null @@ -1,84 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkCudaUtil_h -#define itkCudaUtil_h - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include "itkCudaWin32Header.h" - -namespace itk -{ - -/** Get the local block size based on the desired Image Dimension - * currently set as follows: - * Cuda workgroup (block) size for 1/2/3D - needs to be tuned based on the Cuda architecture - * 1D : 256 - * 2D : 16x16 = 256 - * 3D : 4x4x4 = 64 - */ -int -CudaGetLocalBlockSize(unsigned int ImageDim); - -std::pair -GetCudaComputeCapability(int device); - -/** Get the devices that are available */ -int -CudaGetAvailableDevices(std::vector & devices); - -/** Get the device that has the maximum FLOPS in the current context */ -int -CudaGetMaxFlopsDev(); - -/** Print device name and info */ -void -CudaPrintDeviceInfo(int device, bool verbose = false); - -/** Find the Cuda platform that matches the "name" */ -int -CudaSelectPlatform(const char * name); - -/** Check Cuda error */ -void ITKCudaCommon_EXPORT - CudaCheckError(cudaError_t error, const char * filename = "", int lineno = 0, const char * location = ""); - -void ITKCudaCommon_EXPORT - CudaCheckError(CUresult error, const char * filename = "", int lineno = 0, const char * location = ""); - -/** Check if Cuda-enabled Cuda is present. */ -bool -IsCudaAvailable(); - -#define CUDA_CHECK(_err_) CudaCheckError(_err_, __FILE__, __LINE__, ITK_LOCATION); -} // namespace itk - -#endif diff --git a/utilities/ITKCudaCommon/include/itkCudaWin32Header.h b/utilities/ITKCudaCommon/include/itkCudaWin32Header.h deleted file mode 100644 index 88f31bf92..000000000 --- a/utilities/ITKCudaCommon/include/itkCudaWin32Header.h +++ /dev/null @@ -1,34 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkCudaWin32Header_h -#define itkCudaWin32Header_h - -#include "itkConfigure.h" - -#if (defined(_WIN32) || defined(WIN32)) && defined(ITK_BUILD_SHARED_LIBS) -# ifdef ITKCudaCommon_EXPORTS -# define ITKCudaCommon_EXPORT __declspec(dllexport) -# else -# define ITKCudaCommon_EXPORT __declspec(dllimport) -# endif /* ITK_EXPORT */ -#else -/* unix needs nothing */ -# define ITKCudaCommon_EXPORT -#endif - -#endif diff --git a/utilities/ITKCudaCommon/itk-module.cmake b/utilities/ITKCudaCommon/itk-module.cmake deleted file mode 100644 index 86bb1206c..000000000 --- a/utilities/ITKCudaCommon/itk-module.cmake +++ /dev/null @@ -1,15 +0,0 @@ -if(ITK_SOURCE_DIR) - get_filename_component(_CURRENT_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) - file(READ "${_CURRENT_DIR}/README" DOCUMENTATION) - - itk_module(ITKCudaCommon - ENABLE_SHARED - EXCLUDE_FROM_DEFAULT - DEPENDS - ITKCommon - TEST_DEPENDS - ITKTestKernel - DESCRIPTION - "${DOCUMENTATION}" - ) -endif() diff --git a/utilities/ITKCudaCommon/src/CMakeLists.txt b/utilities/ITKCudaCommon/src/CMakeLists.txt deleted file mode 100644 index 63d3d1037..000000000 --- a/utilities/ITKCudaCommon/src/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -set(ITKCudaCommon_SRC - itkCudaContextManager.cxx - itkCudaDataManager.cxx - itkCudaUtil.cxx - itkCudaMemoryProbe.cxx - ) - -include_directories(${ITKCudaCommon_SOURCE_DIR}/include) -include_directories(${ITK_INCLUDE_DIRS}) -add_library(ITKCudaCommon ${ITK_LIBRARY_BUILD_TYPE} ${ITKCudaCommon_SRC}) -target_link_libraries(ITKCudaCommon LINK_PUBLIC ${ITKCommon_LIBRARIES} CUDA::cudart CUDA::cuda_driver) - -if (NOT ITK_SOURCE_DIR) - # Export to RTK build targets must be done after RTK has been loaded by ITK. - # When building externally we must do this after including ITKModuleExternal. - # See RTK/CMakeLists.txt. -else() - itk_module_target_export(ITKCudaCommon) -endif() - -#========================================================= -if(NOT RTK_INSTALL_NO_LIBRARIES) - target_include_directories(ITKCudaCommon PUBLIC $) - install(TARGETS ITKCudaCommon EXPORT RTK - RUNTIME DESTINATION ${ITKCudaCommon_INSTALL_RUNTIME_DIR} COMPONENT Runtime - LIBRARY DESTINATION ${ITKCudaCommon_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries - ARCHIVE DESTINATION ${ITKCudaCommon_INSTALL_ARCHIVE_DIR} COMPONENT Development - PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_PREFIX}/${ITKCudaCommon_INSTALL_INCLUDE_DIR}" - ) - install(TARGETS ITKCudaCommon EXPORT ITKTargets - RUNTIME DESTINATION ${ITKCudaCommon_INSTALL_RUNTIME_DIR} COMPONENT Runtime - LIBRARY DESTINATION ${ITKCudaCommon_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries - ARCHIVE DESTINATION ${ITKCudaCommon_INSTALL_ARCHIVE_DIR} COMPONENT Development - PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_PREFIX}/${ITKCudaCommon_INSTALL_INCLUDE_DIR}" - ) -endif() diff --git a/utilities/ITKCudaCommon/src/itkCudaContextManager.cxx b/utilities/ITKCudaCommon/src/itkCudaContextManager.cxx deleted file mode 100644 index 4c80479eb..000000000 --- a/utilities/ITKCudaCommon/src/itkCudaContextManager.cxx +++ /dev/null @@ -1,109 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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 -#include "itkCudaContextManager.h" -#include "cuda.h" -#include "cuda_runtime_api.h" - -namespace itk -{ -// static variable initialization -CudaContextManager * CudaContextManager::m_Instance = nullptr; -bool CudaContextManager::m_Initialized = false; - - -CudaContextManager * -CudaContextManager::GetInstance() -{ - if (m_Instance == nullptr) - { - m_Instance = new CudaContextManager(); - } - m_Instance->Register(); - return m_Instance; -} - -void -CudaContextManager::DestroyInstance() -{ - m_Instance->UnRegister(); - if (m_Instance->GetReferenceCount() == 1) - { - m_Instance->Delete(); - m_Instance = nullptr; - } -} - -CudaContextManager::CudaContextManager() -{ - m_DeviceIdx = -1; - m_Device = 0; - - if (!m_Initialized) - { - cuInit(0); - m_Initialized = true; - } - - std::vector devices; - m_NumberOfDevices = itk::CudaGetAvailableDevices(devices); - - if (m_NumberOfDevices) - { - CUdevice device = 0; - m_DeviceIdx = itk::CudaGetMaxFlopsDev(); - CUDA_CHECK(cuDeviceGet(&device, m_DeviceIdx)); - - CUDA_CHECK(cuCtxCreate(&m_Context, CU_CTX_SCHED_AUTO, device)); - - CUDA_CHECK(cuCtxSetCurrent(m_Context)); - - m_Device = device; - } - else - { - m_Context = nullptr; - m_Device = 0; - m_DeviceIdx = 0; - } -} - -CudaContextManager::~CudaContextManager() -{ - if (m_Context) - { - CUDA_CHECK(cuCtxDestroy(m_Context)); - } - cudaDeviceReset(); -} - -int -CudaContextManager::GetCurrentDevice() -{ - int device = -1; - CUDA_CHECK(cudaGetDevice(&device)); - return device; -} - -CUcontext * -CudaContextManager::GetCurrentContext() -{ - return &m_Context; -} - -} // namespace itk diff --git a/utilities/ITKCudaCommon/src/itkCudaDataManager.cxx b/utilities/ITKCudaCommon/src/itkCudaDataManager.cxx deleted file mode 100644 index 6db48703d..000000000 --- a/utilities/ITKCudaCommon/src/itkCudaDataManager.cxx +++ /dev/null @@ -1,291 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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 "itkCudaDataManager.h" -#include - -namespace itk -{ -// constructor -CudaDataManager::CudaDataManager() -{ - m_ContextManager = CudaContextManager::GetInstance(); - - // Creating the context in the constructor allows avoiding a memory leak. - // However, the cuda data manager is created even if there is no use of CUDA - // software and sometimes one compiles RTK with CUDA but wants to use it - // without CUDA. So if the context pointer is nullptr, which indicates that there - // is no CUDA device available, we just do not set the context (SR). This fixes - // the problem reported here: - // https://www.creatis.insa-lyon.fr/pipermail/rtk-users/2015-July/000570.html - CUcontext * ctx = m_ContextManager->GetCurrentContext(); - if (ctx) - CUDA_CHECK(cuCtxSetCurrent(*ctx)); - - m_CPUBuffer = nullptr; - m_GPUBuffer = GPUMemPointer::New(); - this->Initialize(); - - m_ReleaseDirtyGPUBuffer = true; - std::string relString; - if (itksys::SystemTools::GetEnv("ITK_RELEASE_DIRTY_GPU_BUFFERS", relString) && - (itksys::SystemTools::LowerCase(relString) == "false" || atoi(relString.c_str()) != 0)) - { -#ifdef VERBOSE - std::cout << "Releasing dirty GPU buffer" << std::endl; -#endif - m_ReleaseDirtyGPUBuffer = false; - } -} - -CudaDataManager::~CudaDataManager() -{ - m_GPUBuffer = nullptr; - CudaContextManager::DestroyInstance(); -} - -void -CudaDataManager::SetBufferSize(size_t num) -{ - m_BufferSize = num; -} - -void -CudaDataManager::SetBufferFlag(int flags) -{ - m_MemFlags = flags; -} - -void -CudaDataManager::Allocate() -{ - if (m_BufferSize > 0 && m_GPUBuffer->GetBufferSize() != m_BufferSize) - { - m_GPUBuffer->Allocate(m_BufferSize); - m_IsGPUBufferDirty = true; - } -} - -void -CudaDataManager::Free() -{ - std::string exceptionDetails; - bool exceptionOccured = false; - m_Mutex.lock(); - if (m_GPUBuffer->GetBufferSize() > 0) - { - try - { - CUDA_CHECK(cuCtxSetCurrent( - *(this->m_ContextManager->GetCurrentContext()))); // This is necessary when running multithread to bind the host - // CPU thread to the right context - m_GPUBuffer->Free(); - } - catch (itk::ExceptionObject & e) - { - exceptionOccured = true; - exceptionDetails = e.what(); - } - m_IsGPUBufferDirty = true; - } - m_Mutex.unlock(); - if (exceptionOccured) - { - if (exceptionDetails.empty()) - { - itkExceptionMacro("Exception occurred during CudaDataManager::Free"); - } - else - { - itkExceptionMacro(<< "Exception occurred during CudaDataManager::Free" << std::endl << exceptionDetails); - } - } -} - -void -CudaDataManager::SetCPUBufferPointer(void * ptr) -{ - m_CPUBuffer = ptr; -} - -void -CudaDataManager::SetCPUDirtyFlag(bool isDirty) -{ - m_IsCPUBufferDirty = isDirty; -} - -void -CudaDataManager::SetGPUDirtyFlag(bool isDirty) -{ - m_IsGPUBufferDirty = isDirty; - if (isDirty && m_ReleaseDirtyGPUBuffer) - this->Free(); -} - -void -CudaDataManager::SetGPUBufferDirty() -{ - this->UpdateCPUBuffer(); - m_IsGPUBufferDirty = true; - if (m_ReleaseDirtyGPUBuffer) - this->Free(); -} - -void -CudaDataManager::SetCPUBufferDirty() -{ - this->UpdateGPUBuffer(); - m_IsCPUBufferDirty = true; -} - -void -CudaDataManager::UpdateCPUBuffer() -{ - std::string exceptionDetails; - bool exceptionOccured = false; - m_Mutex.lock(); - if (m_IsGPUBufferDirty) - { - m_IsCPUBufferDirty = false; - } - else if (m_IsCPUBufferDirty && m_GPUBuffer && m_CPUBuffer) - { - try - { -#ifdef VERBOSE - std::cout << this << "::UpdateCPUBuffer GPU->CPU data copy " << m_GPUBuffer->GetPointer() << "->" << m_CPUBuffer - << " : " << m_BufferSize << std::endl; -#endif - CUDA_CHECK(cuCtxSetCurrent( - *(this->m_ContextManager->GetCurrentContext()))); // This is necessary when running multithread to bind the host - // CPU thread to the right context - CUDA_CHECK(cudaMemcpy(m_CPUBuffer, m_GPUBuffer->GetPointer(), m_BufferSize, cudaMemcpyDeviceToHost)); - m_IsCPUBufferDirty = false; - } - catch (itk::ExceptionObject & e) - { - exceptionOccured = true; - exceptionDetails = e.what(); - } - } - m_Mutex.unlock(); - if (exceptionOccured) - { - if (exceptionDetails.empty()) - { - itkExceptionMacro("Exception occurred during CudaDataManager::UpdateCPUBuffer"); - } - else - { - itkExceptionMacro(<< "Exception occurred during CudaDataManager::UpdateCPUBuffer" << std::endl - << exceptionDetails); - } - } -} - -void -CudaDataManager::UpdateGPUBuffer() -{ - m_Mutex.lock(); - if (m_IsGPUBufferDirty && m_GPUBuffer) - { - this->Allocate(); // do the allocation - - if (!m_IsCPUBufferDirty && m_CPUBuffer) - { -#ifdef VERBOSE - std::cout << this << "::UpdateGPUBuffer CPU->GPU data copy " << m_CPUBuffer << "->" << m_GPUBuffer->GetPointer() - << " : " << m_BufferSize << std::endl; -#endif - CUDA_CHECK(cuCtxSetCurrent( - *(this->m_ContextManager->GetCurrentContext()))); // This is necessary when running multithread to bind the host - // CPU thread to the right context - CUDA_CHECK(cudaMemcpy(m_GPUBuffer->GetPointer(), m_CPUBuffer, m_BufferSize, cudaMemcpyHostToDevice)); - } - m_IsGPUBufferDirty = false; - } - m_Mutex.unlock(); -} - -void * -CudaDataManager::GetGPUBufferPointer() -{ - SetCPUBufferDirty(); - return m_GPUBuffer->GetPointerPtr(); -} - -void * -CudaDataManager::GetCPUBufferPointer() -{ - SetGPUBufferDirty(); - return m_CPUBuffer; -} - -bool -CudaDataManager::Update() -{ - if (m_IsGPUBufferDirty && m_IsCPUBufferDirty) - { - itkExceptionMacro("Cannot make up-to-date buffer because both CPU and GPU buffers are dirty"); - return false; - } - - this->UpdateGPUBuffer(); - this->UpdateCPUBuffer(); - - m_IsGPUBufferDirty = m_IsCPUBufferDirty = false; - - return true; -} - -void -CudaDataManager::Graft(const CudaDataManager * data) -{ - if (data) - { - m_BufferSize = data->m_BufferSize; - m_ContextManager = data->m_ContextManager; - m_GPUBuffer = data->m_GPUBuffer; - m_CPUBuffer = data->m_CPUBuffer; - m_IsCPUBufferDirty = data->m_IsCPUBufferDirty; - m_IsGPUBufferDirty = data->m_IsGPUBufferDirty; - } -} - -void -CudaDataManager::Initialize() -{ - m_BufferSize = 0; - m_CPUBuffer = nullptr; - m_MemFlags = 0; // default flag - m_IsGPUBufferDirty = false; - m_IsCPUBufferDirty = false; -} - -void -CudaDataManager::PrintSelf(std::ostream & os, Indent indent) const -{ - os << indent << "CudaDataManager (" << this << ")" << std::endl; - os << indent << "m_BufferSize: " << m_BufferSize << std::endl; - os << indent << "m_IsGPUBufferDirty: " << m_IsGPUBufferDirty << std::endl; - os << indent << "m_GPUBuffer: " << m_GPUBuffer << std::endl; - os << indent << "m_IsCPUBufferDirty: " << m_IsCPUBufferDirty << std::endl; - os << indent << "m_CPUBuffer: " << m_CPUBuffer << std::endl; -} - -} // namespace itk diff --git a/utilities/ITKCudaCommon/src/itkCudaMemoryProbe.cxx b/utilities/ITKCudaCommon/src/itkCudaMemoryProbe.cxx deleted file mode 100644 index b6c2f6004..000000000 --- a/utilities/ITKCudaCommon/src/itkCudaMemoryProbe.cxx +++ /dev/null @@ -1,38 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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 "itkCudaMemoryProbe.h" -#include "itkCudaUtil.h" -#include - -namespace itk -{ -CudaMemoryProbe ::CudaMemoryProbe() - : ResourceProbe("Cuda memory", "kB") -{} - -CudaMemoryProbe ::~CudaMemoryProbe() = default; - -CudaMemoryProbe::CudaMemoryLoadType -CudaMemoryProbe ::GetInstantValue() const -{ - size_t free = 0; - size_t total = 0; - CUDA_CHECK(cudaMemGetInfo(&free, &total)); - return static_cast((OffsetValueType(total) - OffsetValueType(free)) / 1024.); -} -} // end namespace itk diff --git a/utilities/ITKCudaCommon/src/itkCudaUtil.cxx b/utilities/ITKCudaCommon/src/itkCudaUtil.cxx deleted file mode 100644 index ebc7ea78c..000000000 --- a/utilities/ITKCudaCommon/src/itkCudaUtil.cxx +++ /dev/null @@ -1,218 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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 "itkCudaUtil.h" -#include -#include -#include - -namespace itk -{ -// -// Get the block size based on the desired image dimension -// -int -CudaGetLocalBlockSize(unsigned int ImageDim) -{ - /** - * Cuda thread block size for 1/2/3D - needs to be tuned based on the Cuda architecture - * 1D : 256 - * 2D : 16x16 = 256 - * 3D : 4x4x4 = 64 - */ - int CUDA_BLOCK_SIZE[3] = { 256, 16, 4 /*8*/ }; - - - if (ImageDim > 3) - { - itkGenericExceptionMacro("Only ImageDimensions up to 3 are supported"); - } - return CUDA_BLOCK_SIZE[ImageDim - 1]; -} - -// -// Get the devices that are available. -// -int -CudaGetAvailableDevices(std::vector & devices) -{ - int numAvailableDevices = 0; - cudaGetDeviceCount(&numAvailableDevices); - - if (numAvailableDevices == 0) - { - return 0; - } - - devices.resize(numAvailableDevices); - - for (int i = 0; i < numAvailableDevices; ++i) - { - cudaGetDeviceProperties(&devices[i], i); - } - - return numAvailableDevices; -} - -// -// Get the device that has the maximum FLOPS -// -int -CudaGetMaxFlopsDev() -{ - std::vector devices; - int numAvailableDevices = CudaGetAvailableDevices(devices); - if (numAvailableDevices == 0) - { - - return -1; - } - int max_flops = 0; - int max_flops_device = 0; - for (int i = 0; i < numAvailableDevices; ++i) - { - int flops = devices[i].multiProcessorCount * devices[i].clockRate; - if (flops > max_flops) - { - max_flops = flops; - max_flops_device = i; - } - } - - return max_flops_device; -} - - -std::pair -GetCudaComputeCapability(int device) -{ - struct cudaDeviceProp properties; - if (cudaGetDeviceProperties(&properties, device) != cudaSuccess) - { - itkGenericExceptionMacro(<< "Unvalid CUDA device"); - } - return std::make_pair(properties.major, properties.minor); -} - -// -// Print device name & info -// -void -CudaPrintDeviceInfo(int device, bool verbose) -{ - cudaDeviceProp prop; - if (cudaGetDeviceProperties(&prop, device) != cudaSuccess) - { - std::cout << "Cuda Error : no device found!" << std::endl; - return; - } - - std::cout << prop.name << std::endl; - std::cout << "Compute capability: " << prop.major << "." << prop.minor << std::endl; - std::cout << "Clockrate: " << prop.clockRate << std::endl; - std::cout << "Global memory: " << prop.totalGlobalMem << std::endl; - std::cout << "Constant memory: " << prop.totalConstMem << std::endl; - std::cout << "Number of Multi Processors: " << prop.multiProcessorCount << std::endl; - std::cout << "Maximum Thread Dim: { " << prop.maxThreadsDim[0] << ", " << prop.maxThreadsDim[1] << ", " - << prop.maxThreadsDim[2] << " }" << std::endl; - std::cout << "Maximum Threads per Block: " << prop.maxThreadsPerBlock << std::endl; - std::cout << "Maximum Grid Size: { " << prop.maxGridSize[0] << ", " << prop.maxGridSize[1] << ", " - << prop.maxGridSize[2] << " }" << std::endl; - - if (verbose) - { - /*cl_uint mem_align; - err = clGetDeviceInfo(device, CL_DEVICE_MEM_BASE_ADDR_ALIGN, sizeof(mem_align), &mem_align, nullptr); - std::cout << "Alignment in bits of the base address : " << mem_align << std::endl; - prop.ext - cl_uint min_align; - err = clGetDeviceInfo(device, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, sizeof(min_align), &min_align, nullptr); - std::cout << "Smallest alignment in bytes for any data type : " << min_align << std::endl; - - char device_extensions[1024]; - err = clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, sizeof(device_extensions), &device_extensions, nullptr); - printf("%s\n", device_extensions);*/ - } -} - -// -// Find the Cuda platform that matches the "name" -// -int -CudaSelectPlatform(const char * name) -{ - int numAvailableDevices = 0; - std::vector devices; - numAvailableDevices = CudaGetAvailableDevices(devices); - if (numAvailableDevices == 0) - { - std::cout << "Cuda Error : no device found!" << std::endl; - return -1; - } - - for (int i = 0; i < numAvailableDevices; ++i) - { - if (!strcmp(devices[i].name, name)) - { - return i; - } - } - - return -1; -} - -void -CudaCheckError(cudaError_t error, const char * filename, int lineno, const char * location) -{ - if (error != cudaSuccess) - { - // print error message - std::ostringstream errorMsg; - errorMsg << "Cuda Error : " << cudaGetErrorString(error) << std::endl; - std::cerr << filename << ":" << lineno << " @ " << location << " : " << errorMsg.str() << std::endl; - ::itk::ExceptionObject e_(filename, lineno, errorMsg.str().c_str(), location); - throw e_; - } -} - - -void -CudaCheckError(CUresult error, const char * filename, int lineno, const char * location) -{ - if (error != CUDA_SUCCESS) - { - // print error message - std::ostringstream errorMsg; - errorMsg << "Cuda Error #" << static_cast(error) << std::endl; - std::cerr << filename << ":" << lineno << " @ " << location << " : " << errorMsg.str() << std::endl; - ::itk::ExceptionObject e_(filename, lineno, errorMsg.str().c_str(), location); - throw e_; - } -} - - -/** Check if OpenCL-enabled Cuda is present. */ -bool -IsCudaAvailable() -{ - int count = 0; - cudaError_t err = cudaGetDeviceCount(&count); - CUDA_CHECK(err) - return count >= 1; -} - -} // end namespace itk diff --git a/wrapping/CMakeLists.txt b/wrapping/CMakeLists.txt index 8f759bff3..a030a3dc0 100644 --- a/wrapping/CMakeLists.txt +++ b/wrapping/CMakeLists.txt @@ -10,7 +10,7 @@ set(WRAPPER_SUBMODULE_ORDER itkVariableLengthVectorRTK itkImageBaseRTK itkImageRTK - itkCudaImage + itkCudaImageRTK itkVectorImageRTK itkImageSourceRTK itkImageToImageFilterRTK diff --git a/wrapping/itkCudaDataManager.wrap b/wrapping/itkCudaDataManager.wrap deleted file mode 100644 index 46dce699a..000000000 --- a/wrapping/itkCudaDataManager.wrap +++ /dev/null @@ -1,5 +0,0 @@ -if(RTK_USE_CUDA) - - itk_wrap_simple_class("itk::CudaDataManager" POINTER) - -endif() diff --git a/wrapping/itkCudaImage.wrap b/wrapping/itkCudaImage.wrap deleted file mode 100644 index ca4e51f24..000000000 --- a/wrapping/itkCudaImage.wrap +++ /dev/null @@ -1,31 +0,0 @@ -if(RTK_USE_CUDA) - - itk_wrap_class("itk::CudaImage" POINTER_WITH_CONST_POINTER) - - foreach(d ${ITK_WRAP_IMAGE_DIMS}) - itk_wrap_template("F${d}" "float, ${d}") - endforeach() - - list(FIND ITK_WRAP_IMAGE_DIMS "4" _index) - if (${_index} EQUAL -1) - itk_wrap_template("F4" "${ITKT_F}, 4") - endif() - - # Force VECTOR_COMPONENTS to "2;3;4;5" - # Force ITK_WRAP_IMAGE_DIMS to "2;3;4" - UNIQUE(imageDimensions "${ITK_WRAP_IMAGE_DIMS};2;3;4") - UNIQUE(vectorComponents "${ITK_WRAP_VECTOR_COMPONENTS};2;3;4;5") - foreach(component ${vectorComponents}) - foreach(d ${imageDimensions}) - foreach(vt ${WRAP_ITK_VECTOR_REAL}) - itk_wrap_template("${ITKM_${vt}${component}}${d}" "${ITKT_${vt}${component}}, ${d}") - endforeach() - foreach(cvt ${WRAP_ITK_COV_VECTOR_REAL}) - itk_wrap_template("${ITKM_${cvt}${component}}${d}" "${ITKT_${cvt}${component}}, ${d}") - endforeach() - endforeach() - endforeach() - - itk_end_wrap_class() - -endif() diff --git a/wrapping/itkCudaImageDataManager.wrap b/wrapping/itkCudaImageDataManager.wrap deleted file mode 100644 index 490349ccb..000000000 --- a/wrapping/itkCudaImageDataManager.wrap +++ /dev/null @@ -1,35 +0,0 @@ -if(RTK_USE_CUDA) - - itk_wrap_include(itkCudaImage.h) - - itk_wrap_class("itk::CudaImageDataManager" POINTER) - - foreach(d ${ITK_WRAP_IMAGE_DIMS}) - itk_wrap_template("CI${ITKM_F}${d}" "itk::CudaImage<${ITKT_F}, ${d}>") - endforeach() - - list(FIND ITK_WRAP_IMAGE_DIMS "4" _index) - if(${_index} EQUAL -1) - itk_wrap_template("CI${ITKM_F}4" "itk::CudaImage<${ITKT_F}, 4>") - endif() - - # Force VECTOR_COMPONENTS to "2;3;4;5" - UNIQUE(vectorComponents "${ITK_WRAP_VECTOR_COMPONENTS};2;3;4;5") - foreach(component ${vectorComponents}) - - foreach(d ${ITK_WRAP_IMAGE_DIMS}) - itk_wrap_template("CI${ITKM_VF${component}}${d}" "itk::CudaImage<${ITKT_VF${component}}, ${d}>") - itk_wrap_template("CI${ITKM_CVF${component}}${d}" "itk::CudaImage<${ITKT_CVF${component}}, ${d}>") - endforeach() - - list(FIND ITK_WRAP_IMAGE_DIMS "4" _index) - if(${_index} EQUAL -1) - itk_wrap_template("CI${ITKM_VF${component}}4" "itk::CudaImage<${ITKT_VF${component}}, 4>") - itk_wrap_template("CI${ITKM_CVF${component}}4" "itk::CudaImage<${ITKT_CVF${component}}, 4>") - endif() - - endforeach() - - itk_end_wrap_class() - -endif() diff --git a/wrapping/itkCudaImageDataManagerRTK.wrap b/wrapping/itkCudaImageDataManagerRTK.wrap new file mode 100644 index 000000000..cd88cf541 --- /dev/null +++ b/wrapping/itkCudaImageDataManagerRTK.wrap @@ -0,0 +1,28 @@ +if(RTK_USE_CUDA) + + itk_wrap_include(itkCudaImage.h) + + itk_wrap_class("itk::CudaImageDataManager" POINTER) + + # Add all missing image with dim == 4 + list(FIND ITK_WRAP_IMAGE_DIMS "4" _index) + if(${_index} EQUAL -1) + itk_wrap_template("CI${ITKM_F}4" "itk::CudaImage<${ITKT_F}, 4>") + foreach(c 2 3 4 5) + itk_wrap_template("CI${ITKM_VF${c}}4" "itk::CudaImage<${ITKT_VF${c}}, 4>") + itk_wrap_template("CI${ITKM_CVF${c}}4" "itk::CudaImage<${ITKT_CVF${c}}, 4>") + endforeach() + endif() + + # Add all missing image with comp == 5 + list(FIND ITK_WRAP_VECTOR_COMPONENTS "5" _index) + if(${_index} EQUAL -1) + foreach(d 2 3) + itk_wrap_template("CI${ITKM_VF5}${d}" "itk::CudaImage<${ITKT_VF5}, ${d}>") + itk_wrap_template("CI${ITKM_CVF5}${d}" "itk::CudaImage<${ITKT_CVF5}, ${d}>") + endforeach() + endif() + + itk_end_wrap_class() + +endif() diff --git a/wrapping/itkCudaImageRTK.wrap b/wrapping/itkCudaImageRTK.wrap new file mode 100644 index 000000000..5cd75e30c --- /dev/null +++ b/wrapping/itkCudaImageRTK.wrap @@ -0,0 +1,26 @@ +if(RTK_USE_CUDA) + + itk_wrap_class("itk::CudaImage" POINTER_WITH_CONST_POINTER) + + # Add all missing image with dim == 4 + list(FIND ITK_WRAP_IMAGE_DIMS "4" _index) + if (${_index} EQUAL -1) + itk_wrap_template("F4" "${ITKT_F}, 4") + foreach(c 2 3 4 5) + itk_wrap_template("${ITKM_VF${c}}4" "${ITKT_VF${c}}, 4") + itk_wrap_template("${ITKM_CVF${c}}4" "${ITKT_CVF${c}}, 4") + endforeach() + endif() + + # Add all missing image with comp == 5 + list(FIND ITK_WRAP_VECTOR_COMPONENTS "5" _index) + if(${_index} EQUAL -1) + foreach(d 2 3) + itk_wrap_template("${ITKM_VF5}${d}" "${ITKT_VF5}, ${d}") + itk_wrap_template("${ITKM_CVF5}${d}" "${ITKT_CVF5}, ${d}") + endforeach() + endif() + + itk_end_wrap_class() + +endif()