LLNL / LEAP

comprehensive library of 3D transmission Computed Tomography (CT) algorithms with Python and C++ APIs, a PyQt GUI, and fully integrated with PyTorch
https://leapct.readthedocs.io
MIT License
104 stars 10 forks source link

Issue with LEAP Library Support on MacOS #71

Closed lc82111 closed 6 days ago

lc82111 commented 2 months ago

I've been trying to use the LEAP library on MacOS, specifically with the leapctype.py bindings, but encountered an issue when attempts to call the functions in the leapct.dylib, e.g., leapct.project(g,f).

The relevant section of the code acknowledges the lack of support for MacOS:


elif _platform == "darwin":  # Darwin is the name for MacOS in Python's platform module
    # there is current no support for LEAP on Mac, but maybe someone can figure this out 
kylechampley commented 2 months ago

Hello. That comment is old and should be removed. The Mac version works, but it does not have GPU support and thus there are a few missing features.

The most likely issue is that LEAP failed to compile. Did you see the comments about compiling for Mac here?

lc82111 commented 2 months ago

Hello. That comment is old and should be removed. The Mac version works, but it does not have GPU support and thus there are a few missing features.

The most likely issue is that LEAP failed to compile. Did you see the comments about compiling for Mac here?

Yes, I have managed to compile leapct.dylib for Mac by the following src/CMakeLists.txt:


cmake_minimum_required(VERSION` 3.5 FATAL_ERROR)

project(leapct CXX)

# Set LLVM's Clang as the compiler
set(CMAKE_C_COMPILER "/opt/homebrew/opt/llvm/bin/clang")
set(CMAKE_CXX_COMPILER "/opt/homebrew/opt/llvm/bin/clang++")

# Set the OpenMP include and library paths based on the Homebrew installation
message(STATUS "apple!!!!!!")
include_directories(/opt/homebrew/opt/libomp/include)
link_directories(/opt/homebrew/opt/libomp/lib)
add_compile_options(-Xpreprocessor -fopenmp)
link_libraries(omp)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Explicitly set OpenMP flags
set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -I/opt/homebrew/opt/libomp/include")
set(OpenMP_CXX_LIB_NAMES "omp")
set(OpenMP_omp_LIBRARY "/opt/homebrew/opt/libomp/lib/libomp.dylib")

find_package(OpenMP REQUIRED COMPONENTS CXX)
add_compile_options(-D__USE_CPU)

if (WIN32)
  set(CMAKE_SHARED_LIBRARY_PREFIX "lib")
  set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
endif()

set(HEADER
  tomographic_models.h
  list_of_tomographic_models.h
  tomographic_models_c_interface.h
  parameters.h
  projectors.h
  filtered_backprojection.h
  projectors_SF_cpu.h
  projectors_Joseph_cpu.h
  projectors_symmetric_cpu.h
  projectors_Siddon_cpu.h
  sensitivity_cpu.h
  ramp_filter_cpu.h
  ray_weighting_cpu.h
  find_center_cpu.h
  sinogram_replacement.h
  resample_cpu.h
  cpu_utils.h
  phantom.h
  analytic_ray_tracing.h
  rebin.h
  file_io.h
  leap_defines.h
  log.h
)

set(SRC_CPP
  tomographic_models.cpp
  list_of_tomographic_models.cpp
  tomographic_models_c_interface.cpp
  parameters.cpp
  projectors.cpp
  filtered_backprojection.cpp
  projectors_SF_cpu.cpp
  projectors_Joseph_cpu.cpp
  projectors_symmetric_cpu.cpp
  projectors_Siddon_cpu.cpp
  sensitivity_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
)

include_directories(
  ./
)

add_library(leapct SHARED
  ${HEADER}
  ${SRC_CPP}
)

# <<<--- Create filters for subfolders for Visual Studio
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

file(GLOB_RECURSE _source_list
  LIST_DIRECTORIES false
  ${HEADER}
  ${SRC_CPP}
)

foreach(_source IN ITEMS ${_source_list})
  get_filename_component(_source_path "${_source}" PATH)
  file(RELATIVE_PATH _source_path_rel "${PROJECT_SOURCE_DIR}" "${_source_path}")
  string(REPLACE "/" "\\" _group_path "${_source_path_rel}")
  source_group("${_group_path}" FILES "${_source}")
endforeach()
# --->>>

target_link_libraries(${PROJECT_NAME}
  OpenMP::OpenMP_CXX
)

install(TARGETS ${PROJECT_NAME}
  PUBLIC_HEADER DESTINATION include
  RUNTIME DESTINATION bin
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
)

Note: llvm was used because CMake complained that the default clang lacked MP support. When functions in leapct.dylib were called by Python bind, it quit without any message. Is there something wrong with it?

kylechampley commented 2 months ago

Hmm, OK. Just to be sure, you do see a libleapct.dylib file, right?

What chip does your Mac have? Intel, M1, M2? I have access to a Mac with an Intel chip and an M2 chip. I tested the Intel chip tonight and it worked. I can try the M2 tomorrow.

Is anything printed to the screen when you do: from leapctype import *

kylechampley commented 2 months ago

Ya, I tested LEAP on a Mac with an M1 chip and it crashed. Seems like it only works on the old Macs with Intel chips. I really don't understand because my other CT library, XrayPhysics, works on the M1 chip and I don't see why LEAP should have issues.

I want to fix this, but I leave for a two-week vacation in a few days, so I won't be able to address this until I get back. Sorry about the troubles.

lc82111 commented 2 months ago

Yes, my Mac is with M1 chip. Thank you for the great work. Waiting for your fix. (≧ω≦)

kylechampley commented 2 weeks ago

So sorry for the absurdly long delay in replying to you. I did find out how to resolve this issue. Basically all you need to do is install gcc and then specify the path to the gcc compiler the CMakeLists.txt file. I recommend using homebrew.

lc82111 commented 5 days ago

thanks. I will try.

lc82111 commented 5 days ago

Hi @kylechampley it works if I set the homebrew gcc as the default compiler in etc/build.sh as

export CC="/opt/homebrew/Cellar/gcc/14.2.0/bin/gcc-14"
export CXX="/opt/homebrew/Cellar/gcc/14.2.0/bin/g++-14"

Note: You can't directly set the compiler path like that within the CMakeLists.txt file. CMake uses environment variables to determine the compiler to use. Instead of hardcoding the path, you should set the environment variables CC and CXX (for C and C++ compilers, respectively) before invoking CMake. So you do not need to set the compiler in cpu_CMakeLists.txt.

lc82111 commented 5 days ago

Reconstructing the d01_standard_geometries.py took a long time, so I had to switch back to my Linux remote server.

kylechampley commented 4 days ago

Thanks for your comments; this will help others.

Ya, the Mac version of LEAP is not very good. Parallelizing code on those ARM chips is very different from parallelizing on a GPU. I'd like to provide better support on Mac, but I am swamped with other things.

Anyway, thanks for your patience.

lc82111 commented 2 days ago

Thanks for the excellent modern approach to CT reconstruction. I notice that most of your solutions, such as BH and scatter, are based on spectrum modeling of the system. However, I'm new to this field. Can you provide some guidance on the modeling?