diff --git a/.gitignore b/.gitignore index dc69e64..ffd7efd 100644 --- a/.gitignore +++ b/.gitignore @@ -182,7 +182,7 @@ cython_debug/ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ +.idea/ @@ -645,4 +645,4 @@ FodyWeavers.xsd *.msp # JetBrains Rider -*.sln.iml \ No newline at end of file +*.sln.iml diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a0f8d4..f32e759 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,61 @@ -#cmake_minimum_required(VERSION 3.23 FATAL_ERROR) -cmake_minimum_required(VERSION 3.18 FATAL_ERROR) +# cmake version 3.23 or higher is needed to support +# the argument CUDA_ARCHITECTURES all-major +cmake_minimum_required(VERSION 3.23 FATAL_ERROR) -project(leapct) +project(leapct LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -ENABLE_TESTING() +# Find a default GPU accelerator language. +set(_default_accelerator_type "None") +include(CheckLanguage) +check_language(HIP) +if(CMAKE_HIP_COMPILER) + set(_default_accelerator_type "AMD") +endif() +check_language(CUDA) +if(CMAKE_CUDA_COMPILER) + set(_default_accelerator_type "NVIDIA") +endif() + +set(LEAP_GPU "$_default_accelerator_type" CACHE STRING "GPU acceleration type") +unset(_default_accelerator_type) + +set_property(CACHE LEAP_GPU PROPERTY STRINGS "NVIDIA" "AMD" "None") +# Extract "STRINGS" property of the parameter +get_property(OPT_STRINGS CACHE LEAP_GPU PROPERTY STRINGS) +# Check that value of the parameter is inside "STRINGS" list. +if (NOT LEAP_GPU IN_LIST OPT_STRINGS) + message(FATAL_ERROR "Wrong value of the parameter 'LEAP_GPU': ${LEAP_GPU}") +endif () +message(STATUS "LEAP_GPU selected accelerator type ${LEAP_GPU}") + +string(TOUPPER "${LEAP_GPU}" LEAP_GPU) +if (LEAP_GPU STREQUAL "NVIDIA") + # To minimize binary size and compile time, users are suggested to + # set the CUDAARCHS environment variable or define the CMake variable CMAKE_CUDA_ARCHITECTURES + # to "native" if building specifically for the GPU visible to the build environment, + # or to an explicit numerical architecture code, such as "70" + if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES) + set(CMAKE_CUDA_ARCHITECTURES all-major) + endif() + enable_language(CUDA) + set(LEAP_CUDA ON) +elseif (LEAP_GPU STREQUAL "AMD") + # Users are advised to set CMAKE_HIP_ARCHITECTURES to a minimal subset. + # See also https://rocm.docs.amd.com/en/latest/conceptual/cmake-packages.html#using-hip-in-cmake + enable_language(HIP) + set(LEAP_HIP ON) +elseif (LEAP_GPU STREQUAL "NONE") + set(LEAP_CPU_ONLY ON) +else () + message(FATAL_ERROR "CMake scripting error: ${LEAP_GPU} didn't match.") +endif () + +if((BUILD_TESTING) OR (NOT DEFINED BUILD_TESTING)) + ENABLE_TESTING() +endif() set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..df8f71d --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,44 @@ +[build-system] +requires = ["scikit-build-core>=0.10"] +build-backend = "scikit_build_core.build" + +[project] +name = "leapct" +dynamic = ["version"] +description = "LivermorE AI Projector for Computed Tomography (LEAPCT)" +authors = [ + { name = "Kyle Champley", email = "champley@gmail.com" }, + { name = "Hyojin Kim", email = "hkim@llnl.gov" } +] +readme = "README.md" +license-files = ["LICENSE"] +keywords = [ + "Machine Learning", "ML", "AI", "Computed Tomography", "CT", + "Differentiable Project", "Forward Project", "Back Project" +] +requires-python = ">=3.6" +dependencies = [ + "imageio", + "matplotlib", + "numpy", + "scipy", +] + +[tool.scikit-build] +minimum-version = "build-system.requires" +cmake.version = ">=3.23" +metadata.version.provider = "scikit_build_core.metadata.setuptools_scm" + +wheel.packages = ["src/leap_filter_sequence", "src/leap_preprocessing_algorithms", "src/leapctype", "src/leaptorch"] +wheel.py-api = "py3" +# If we have to issue revised packages for the same software version, +# we can increment a build number: +wheel.build-tag = 0 + +[tool.scikit-build.cmake.define] +BUILD_TESTING = false +LEAP_GPU = "NVIDIA" + +[tool.setuptools_scm] +# There are several packages. Is there an appropriate place to put a package version? +#write_to = "src/leap/_version.py" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index a71d070..0000000 --- a/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[metadata] -description_file=README.md -license_files=LICENSE.rst - diff --git a/setup.py b/setup.py deleted file mode 100644 index 840c4ec..0000000 --- a/setup.py +++ /dev/null @@ -1,141 +0,0 @@ -################################################################################ -# Copyright 2022-2023 Lawrence Livermore National Security, LLC and other -# LEAP project developers. See the LICENSE file for details. -# SPDX-License-Identifier: MIT -# -# LivermorE AI Projector for Computed Tomography (LEAP) -# setup.py for pytorch module -################################################################################ - -from setuptools import setup, find_packages -from setuptools.command.install import install -from torch.utils.cpp_extension import CUDAExtension -from torch.utils.cpp_extension import CppExtension -from torch.utils.cpp_extension import BuildExtension -import os -import pybind11 -import torch -from sys import platform as _platform - - -## todo -# compiler options (optimization flags, cufft options) -# leapctype : libleap.so - -cpp_files=[ - 'analytic_ray_tracing.cpp', - 'cpu_utils.cpp', - 'file_io.cpp', - 'filtered_backprojection.cpp', - 'find_center_cpu.cpp', - 'list_of_tomographic_models.cpp', - 'parameters.cpp', - 'phantom.cpp', - 'projectors.cpp', - 'projectors_Joseph_cpu.cpp', - 'projectors_SF_cpu.cpp', - 'projectors_Siddon_cpu.cpp', - 'projectors_symmetric_cpu.cpp', - 'ramp_filter_cpu.cpp', - 'ray_weighting_cpu.cpp', - 'rebin.cpp', - 'sensitivity_cpu.cpp', - 'resample_cpu.cpp', - 'sinogram_replacement.cpp', - 'tomographic_models_c_interface.cpp', - 'tomographic_models.cpp', -] - -cuda_files=[ - 'bilateral_filter.cu', - 'guided_filter.cu', - 'cuda_utils.cu', - 'matching_pursuit.cu', - 'noise_filters.cu', - 'projectors_attenuated.cu', - 'projectors_extendedSF.cu', - 'projectors_Joseph.cu', - 'projectors_SF.cu', - 'projectors_Siddon.cu', - 'projectors_symmetric.cu', - 'ramp_filter.cu', - 'ray_weighting.cu', - 'scatter_models.cu', - 'sensitivity.cu', - 'resample.cu', - 'total_variation.cu', - 'geometric_calibration.cu', - 'analytic_ray_tracing_gpu.cu', - 'backprojectors_VD.cu', -] - -cuda = torch.cuda.is_available() -if cuda: - source_files = [] - for cpp_file in cpp_files: - source_files.append(os.path.join('src', cpp_file)) - for cuda_file in cuda_files: - source_files.append(os.path.join('src', cuda_file)) - - # optionally we could add '-O3' - # or extra_link_args=["-std=c++11"] - rocm = "AMD" in torch.cuda.get_device_name(0) - if rocm: # AMD ROCM GPU - #print("########## AMD ROCM architecture found! ##########") - extra_compile_args={'cxx': ['-D__USE_GPU', '-D__USE_NOTEX', '-O3', '-lhipfft', '-D__INCLUDE_CUFFT'], - 'nvcc': ['-D__USE_GPU', '-D__USE_NOTEX', '-O3', '-lhipfft', '-D__INCLUDE_CUFFT']} - libraries = ['hipfft'] - else: # CUDA GPU - #print("########## NVIDIA CUDA architecture found! ##########") - # for debug - #extra_compile_args={'cxx': ['-D__USE_GPU', '-D__USE_NOTEX', '-O3'], - # 'nvcc': ['-D__USE_GPU', '-D__USE_NOTEX', '-O3']} #, '-arch=compute_61' - #libraries = [] - - # for debug - extra_compile_args={'cxx': ['-D__USE_GPU', '-D__USE_NOTEX', '-O3', '-lcufft', '-D__INCLUDE_CUFFT'], - 'nvcc': ['-D__USE_GPU', '-D__USE_NOTEX', '-O3', '-lcufft', '-D__INCLUDE_CUFFT']} #, '-arch=compute_61' - libraries = ['cufft'] - - # for release - #extra_compile_args={'cxx': ['-D__USE_GPU', '-O3', '-lcufft', '-D__INCLUDE_CUFFT'], - # 'nvcc': ['-D__USE_GPU', '-O3', '-lcufft', '-D__INCLUDE_CUFFT']} - #libraries = ['cufft'] - ext_mod = CUDAExtension( - name='leapct', - sources=source_files, - extra_compile_args=extra_compile_args, - libraries = libraries, - #extra_link_args=["-lcufft"], - extra_cflags=['-O3']) -else: - source_files = [] - for cpp_file in cpp_files: - source_files.append(os.path.join('src', cpp_file)) - - ext_mod = CppExtension( - name='leapct', - sources=source_files, - extra_cflags=['-O3'], - #extra_link_args=["-lcufft"], - extra_compile_args={'cxx': ['-D__USE_CPU']} - #extra_compile_args=['-g', '-D__USE_CPU'], - ) - -setup( - name='leapct', - version='1.27', - author='Kyle Champley, Hyojin Kim', - author_email='champley@gmail.com, hkim@llnl.gov', - description='LivermorE AI Projector for Computed Tomography (LEAPCT)', - keywords='Machine Learning, ML, AI, Computed Tomography, CT, Differentiable Project, Forward Project, Back Project', - python_requires='>=3.6', - packages=find_packages("src"), - package_dir={'': 'src'}, - #install_requires=['numpy', 'torch'], - py_modules=['leaptorch','leapctype', 'leap_filter_sequence', 'leap_preprocessing_algorithms'], - ext_modules=[ext_mod], - cmdclass={'build_ext': BuildExtension}, - #package_data={'': [lib_fname]}, -) - diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2e2a41e..2c38822 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,21 +1,7 @@ -# cmake version 3.23 or higher is needed to support -# the argument CUDA_ARCHITECTURES all-major -# You could use cmake as old as version 3.18 if you replaced -# the line below that specifies all-major with the line below -# it which specifies the list of CUDA architectures -#cmake_minimum_required(VERSION 3.23 FATAL_ERROR) -cmake_minimum_required(VERSION 3.18 FATAL_ERROR) - -project(leapct CXX CUDA) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -find_package(CUDA 11.7 REQUIRED) -find_package(OpenMP REQUIRED) -#set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS}; -O3) -set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS}; -D__INCLUDE_CUFFT) -add_compile_options(-D__INCLUDE_CUFFT) +find_package(OpenMP REQUIRED COMPONENTS CXX) +if(LEAP_CUDA) + find_package(CUDAToolkit 11.7 REQUIRED) +endif() if (WIN32) set(CMAKE_SHARED_LIBRARY_PREFIX "lib") @@ -27,96 +13,96 @@ endif() #set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/..) set(HEADER - tomographic_models.h + analytic_ray_tracing.h + analytic_ray_tracing_gpu.cuh + backprojectors_VD.cuh + bilateral_filter.cuh + cpu_utils.h + cuda_utils.h + file_io.h + filtered_backprojection.h + find_center_cpu.h + geometric_calibration.cuh + guided_filter.cuh + leap_defines.h list_of_tomographic_models.h - tomographic_models_c_interface.h + log.h + matching_pursuit.cuh + noise_filters.cuh parameters.h + phantom.h projectors.h - filtered_backprojection.h + projectors_Joseph.cuh + projectors_Joseph_cpu.h projectors_SF.cuh projectors_SF_cpu.h + projectors_Siddon.cuh + projectors_Siddon_cpu.h + projectors_attenuated.cuh projectors_extendedSF.cuh - projectors_Joseph.cuh - projectors_Joseph_cpu.h projectors_symmetric.cuh projectors_symmetric_cpu.h - projectors_attenuated.cuh - projectors_Siddon.cuh - projectors_Siddon_cpu.h - backprojectors_VD.cuh - sensitivity_cpu.h - sensitivity.cuh ramp_filter.cuh ramp_filter_cpu.h ray_weighting.cuh ray_weighting_cpu.h + rebin.h + resample.cuh + resample_cpu.h scatter_models.cuh - noise_filters.cuh - total_variation.cuh - matching_pursuit.cuh - bilateral_filter.cuh - guided_filter.cuh - geometric_calibration.cuh - find_center_cpu.h + sensitivity.cuh + sensitivity_cpu.h sinogram_replacement.h - resample_cpu.h - resample.cuh - cuda_utils.h - cpu_utils.h - phantom.h - analytic_ray_tracing.h - analytic_ray_tracing_gpu.cuh - rebin.h - file_io.h - leap_defines.h - log.h + tomographic_models.h + tomographic_models_c_interface.h + total_variation.cuh ) set(SRC_CPP - tomographic_models.cpp + analytic_ray_tracing.cpp + cpu_utils.cpp + file_io.cpp + filtered_backprojection.cpp + find_center_cpu.cpp list_of_tomographic_models.cpp - tomographic_models_c_interface.cpp parameters.cpp + phantom.cpp projectors.cpp - filtered_backprojection.cpp - projectors_SF_cpu.cpp projectors_Joseph_cpu.cpp - projectors_symmetric_cpu.cpp + projectors_SF_cpu.cpp projectors_Siddon_cpu.cpp - sensitivity_cpu.cpp + projectors_symmetric_cpu.cpp ramp_filter_cpu.cpp ray_weighting_cpu.cpp - find_center_cpu.cpp - sinogram_replacement.cpp - resample_cpu.cpp - cpu_utils.cpp - phantom.cpp - analytic_ray_tracing.cpp rebin.cpp - file_io.cpp + resample_cpu.cpp + sensitivity_cpu.cpp + sinogram_replacement.cpp + tomographic_models.cpp + tomographic_models_c_interface.cpp ) set(SRC_CU + analytic_ray_tracing_gpu.cu + backprojectors_VD.cu + bilateral_filter.cu + cuda_utils.cu + geometric_calibration.cu + guided_filter.cu + matching_pursuit.cu + noise_filters.cu + projectors_Joseph.cu projectors_SF.cu + projectors_Siddon.cu + projectors_attenuated.cu projectors_extendedSF.cu - projectors_Joseph.cu projectors_symmetric.cu - projectors_attenuated.cu - projectors_Siddon.cu - backprojectors_VD.cu - sensitivity.cu ramp_filter.cu - resample.cu - noise_filters.cu - total_variation.cu - matching_pursuit.cu - bilateral_filter.cu - guided_filter.cu - geometric_calibration.cu ray_weighting.cu + resample.cu scatter_models.cu - analytic_ray_tracing_gpu.cu - cuda_utils.cu + sensitivity.cu + total_variation.cu ) include_directories( @@ -129,9 +115,12 @@ include_directories( add_library(leapct SHARED ${HEADER} ${SRC_CPP} - ${SRC_CU} ) +if(LEAP_CUDA) + target_sources(leapct PRIVATE ${SRC_CU}) +endif() + # <<<--- Create filters for subfolders for Visual Studio set_property(GLOBAL PROPERTY USE_FOLDERS ON) @@ -150,31 +139,52 @@ foreach(_source IN ITEMS ${_source_list}) endforeach() # --->>> -target_link_libraries(${PROJECT_NAME} - OpenMP::OpenMP_CXX - ${CUDA_LIBRARIES} - ${CUDA_cublas_LIBRARY} - ${CUDA_cufft_LIBRARY} -) +if (LEAP_CUDA) + target_compile_definitions( + leapct PRIVATE + __USE_GPU + __INCLUDE_CUFFT + ) + target_link_libraries(${PROJECT_NAME} + OpenMP::OpenMP_CXX + CUDA::cudart + CUDA::cublas + CUDA::cufft + ) +elseif (LEAP_HIP) + target_compile_definitions( + leapct PRIVATE + __USE_GPU + __USE_NOTEX + __INCLUDE_CUFFT + ) + target_link_libraries(${PROJECT_NAME} + OpenMP::OpenMP_CXX + hip::hipfft + ) +else () + target_compile_definitions( + leapct PRIVATE + __USE_CPU + ) + target_link_libraries(${PROJECT_NAME} + OpenMP::OpenMP_CXX + ) +endif() target_compile_options(leapct PRIVATE $<$: --use_fast_math >) -#set_property(TARGET leapct PROPERTY CXX_STANDARD 14) -#set_property(TARGET leapct PROPERTY CUDA_ARCHITECTURES native) -if(CMAKE_VERSION VERSION_GREATER "3.23") - message("Building for all major cuda architectures") - set_property(TARGET leapct PROPERTY CUDA_ARCHITECTURES all-major) +if(SKBUILD) + install(TARGETS ${PROJECT_NAME} + DESTINATION ${SKBUILD_PLATLIB_DIR}/leapctype/ + ) +else() + install(TARGETS ${PROJECT_NAME} + PUBLIC_HEADER DESTINATION include + RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + ) endif() -#set_property(TARGET leapct PROPERTY CUDA_ARCHITECTURES all-major) -#set_property(TARGET ${PROJECT_NAME} PROPERTY CUDA_ARCHITECTURES 60 61 62 70 72 75 80 86 87 89) -#set_property(TARGET ${PROJECT_NAME} PROPERTY CUDA_ARCHITECTURES 75 86 87 89) -#set_property(TARGET leapct PROPERTY CUDA_ARCHITECTURES OFF) - -install(TARGETS ${PROJECT_NAME} - PUBLIC_HEADER DESTINATION include - RUNTIME DESTINATION bin - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib -) diff --git a/src/leap_filter_sequence.py b/src/leap_filter_sequence/__init__.py similarity index 100% rename from src/leap_filter_sequence.py rename to src/leap_filter_sequence/__init__.py diff --git a/src/leap_preprocessing_algorithms.py b/src/leap_preprocessing_algorithms/__init__.py similarity index 100% rename from src/leap_preprocessing_algorithms.py rename to src/leap_preprocessing_algorithms/__init__.py diff --git a/src/leapctype.py b/src/leapctype/__init__.py similarity index 100% rename from src/leapctype.py rename to src/leapctype/__init__.py diff --git a/src/leaptorch.py b/src/leaptorch/__init__.py similarity index 100% rename from src/leaptorch.py rename to src/leaptorch/__init__.py