cmake_minimum_required(VERSION 3.18)
project(cudakima LANGUAGES CXX CUDA)

# Set C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CUDA_STANDARD 17)
set(CMAKE_CUDA_STANDARD_REQUIRED ON)

# Find Python and pybind11
find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
find_package(pybind11 CONFIG REQUIRED)

# Find CUDA
find_package(CUDAToolkit REQUIRED)

# Set CUDA architecture (adjust for your GPU)
# Common architectures: 60 (Pascal), 70 (Volta), 75 (Turing), 80 (Ampere), 86 (Ampere), 89 (Ada), 90 (Hopper)
if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
    set(CMAKE_CUDA_ARCHITECTURES "60;70;75;80;86")
endif()

# Enable OpenMP for CPU fallback
find_package(OpenMP)

# Source files
set(CUDA_SOURCES
    ${CMAKE_CURRENT_SOURCE_DIR}/akima.cu
)

set(BINDING_SOURCES
    ${CMAKE_CURRENT_SOURCE_DIR}/cutils/bindings.cxx
)

# Create the shared library
pybind11_add_module(_cudakima_core MODULE
    ${CUDA_SOURCES}
    ${BINDING_SOURCES}
)

# Include directories
target_include_directories(_cudakima_core PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/cutils
    ${Python3_INCLUDE_DIRS}
)

# Link libraries
target_link_libraries(_cudakima_core PRIVATE
    CUDA::cudart
)

# Add OpenMP if available
if(OpenMP_CXX_FOUND)
    target_link_libraries(_cudakima_core PRIVATE OpenMP::OpenMP_CXX)
    target_compile_definitions(_cudakima_core PRIVATE USE_OPENMP)
endif()

# CUDA-specific compiler flags
target_compile_options(_cudakima_core PRIVATE
    $<$<COMPILE_LANGUAGE:CUDA>:
        --expt-relaxed-constexpr
        -O3
        --use_fast_math
    >
    $<$<COMPILE_LANGUAGE:CXX>:
        -O3
    >
)

# Set output directory
set_target_properties(_cudakima_core PROPERTIES
    LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    CUDA_SEPARABLE_COMPILATION ON
)

# Installation
install(TARGETS _cudakima_core
    LIBRARY DESTINATION ${Python3_SITELIB}/cudakima
)

# Print configuration summary
message(STATUS "======================================")
message(STATUS "CudAkima Build Configuration:")
message(STATUS "  Python: ${Python3_EXECUTABLE}")
message(STATUS "  Python version: ${Python3_VERSION}")
message(STATUS "  CUDA Toolkit: ${CUDAToolkit_VERSION}")
message(STATUS "  CUDA Architectures: ${CMAKE_CUDA_ARCHITECTURES}")
message(STATUS "  OpenMP: ${OpenMP_CXX_FOUND}")
message(STATUS "======================================")
