CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
CMAKE_POLICY(VERSION 2.8)

SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})

IF(NOT Torch_FOUND)
  FIND_PACKAGE(Torch)
ENDIF()
IF(NOT CUDA_FOUND)
  FIND_PACKAGE(CUDA 5.5 REQUIRED)
ENDIF()
IF(NOT MAGMA_FOUND)
  FIND_PACKAGE(MAGMA)
ENDIF()

IF(NOT TH_LIBRARIES)
  SET(TH_LIBRARIES "TH")
ENDIF(NOT TH_LIBRARIES)
MESSAGE(STATUS "TH_LIBRARIES: ${TH_LIBRARIES}")
IF(NOT THC_LIBRARIES)
  SET(THC_LIBRARIES "THC")
ENDIF(NOT THC_LIBRARIES)
MESSAGE(STATUS "THC_LIBRARIES: ${THC_LIBRARIES}")
IF(NOT THS_LIBRARIES)
  SET(THS_LIBRARIES "THS")
ENDIF(NOT THS_LIBRARIES)
MESSAGE(STATUS "THS_LIBRARIES: ${THS_LIBRARIES}")

if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "4.9.3")
    if(CUDA_VERSION VERSION_LESS "8.0")
      MESSAGE(STATUS "Found gcc >=5 and CUDA <= 7.5, adding workaround C++ flags")
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORCE_INLINES")
    endif(CUDA_VERSION VERSION_LESS "8.0")
  endif(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "4.9.3")
endif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")

if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  SET(CMAKE_CXX_STANDARD 11)
endif()

INCLUDE_DIRECTORIES(${CUDA_INCLUDE_DIRS})
INCLUDE_DIRECTORIES("${CUDA_SDK_ROOT_DIR}/common/inc")

IF ($ENV{TH_BINARY_BUILD})
  MESSAGE(STATUS "TH_BINARY_BUILD detected. Statically linking libstdc++")
  SET(CMAKE_CXX_FLAGS "-static-libstdc++ ${CMAKE_CXX_FLAGS}")
ENDIF()

IF(APPLE)
  IF(${CUDA_VERSION} LESS 6.0)
    # work around for mac os x bug:
    # http://stackoverflow.com/questions/16286588/cuda-5-0-cmake-and-make-failing-on-osx-10-8-3
    if (NOT DEFINED CUDA_HOST_COMPILER AND CMAKE_C_COMPILER_ID STREQUAL "Clang" AND EXISTS /usr/bin/gcc)
      set(CUDA_HOST_COMPILER /usr/bin/gcc CACHE FILEPATH "Host side compiler used by NVCC")
      message(STATUS "Setting CMAKE_HOST_COMPILER to /usr/bin/gcc instead of ${CMAKE_C_COMPILER}.")
    endif()

    # bug on Apple
    LINK_DIRECTORIES("/usr/local/cuda/lib/")
  ELSEIF(${CUDA_VERSION} LESS 7.0)
    SET(CUDA_HOST_COMPILER clang)
    LIST(APPEND CUDA_NVCC_FLAGS "-Xcompiler -stdlib=libstdc++ -Xlinker -stdlib=libstdc++")
    IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libstdc++")
    ENDIF()
  ENDIF()
  # CUDA 7 supports clang and libc++ so no need to change anything
ENDIF(APPLE)

# Detect CUDA architecture and get best NVCC flags
IF(NOT COMMAND CUDA_SELECT_NVCC_ARCH_FLAGS)
  INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/cmake/select_compute_arch.cmake)
ENDIF()
LIST(APPEND CUDA_NVCC_FLAGS $ENV{TORCH_NVCC_FLAGS})
CUDA_SELECT_NVCC_ARCH_FLAGS(NVCC_FLAGS_EXTRA $ENV{TORCH_CUDA_ARCH_LIST})
LIST(APPEND CUDA_NVCC_FLAGS ${NVCC_FLAGS_EXTRA})

IF(NOT THCS_INSTALL_BIN_SUBDIR
    OR NOT THCS_INSTALL_LIB_SUBDIR
    OR NOT THCS_INSTALL_INCLUDE_SUBDIR
    OR NOT THCS_INSTALL_CMAKE_SUBDIR)

  INCLUDE_DIRECTORIES(${TH_INCLUDE_PATH} ${TH_INCLUDE_PATH}/TH)
  LINK_DIRECTORIES(${TH_LIB_PATH})

  SET(THCS_INSTALL_BIN_SUBDIR "bin" CACHE PATH "THCS install binary subdirectory")
  SET(THCS_INSTALL_LIB_SUBDIR "lib" CACHE PATH "THCS install library subdirectory")
  SET(THCS_INSTALL_INCLUDE_SUBDIR "include" CACHE PATH "THCS install include subdirectory")
  SET(THCS_INSTALL_CMAKE_SUBDIR "share/cmake/THCS" CACHE PATH "THCS install cmake subdirectory")
ELSE()
  SET(THCS_INSTALL_BIN_SUBDIR ${Torch_INSTALL_BIN_SUBDIR})
  SET(THCS_INSTALL_LIB_SUBDIR ${Torch_INSTALL_LIB_SUBDIR})
  SET(THCS_INSTALL_INCLUDE_SUBDIR ${Torch_INSTALL_INCLUDE_SUBDIR})
  SET(THCS_INSTALL_CMAKE_SUBDIR ${Torch_INSTALL_CMAKE_SUBDIR})
ENDIF()

INCLUDE_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}")
# CONFIGURE_FILE(THCSGeneral.h.in "${CMAKE_CURRENT_BINARY_DIR}/THCSGeneral.h")

SET(CMAKE_C_FLAGS "-std=c99 ${CMAKE_C_FLAGS}")

SET(src
  THCSTensor.c
  )

SET(src-cuda
  THCSTensor.cu
  )

MESSAGE(STATUS "got cuda version " ${CUDA_VERSION})

IF(CUDA_HAS_FP16 OR NOT ${CUDA_VERSION} LESS 7.5)
  MESSAGE(STATUS "Found CUDA with FP16 support, compiling with torch.CudaHalfTensor")
  LIST(APPEND CUDA_NVCC_FLAGS "-DCUDA_HAS_FP16=1")
ELSE(CUDA_HAS_FP16 OR NOT ${CUDA_VERSION} LESS 7.5)
  MESSAGE(STATUS "Could not find CUDA with FP16 support, compiling without torch.CudaHalfTensor")
ENDIF(CUDA_HAS_FP16 OR NOT ${CUDA_VERSION} LESS 7.5)

MESSAGE(STATUS "CUDA_NVCC_FLAGS: ${CUDA_NVCC_FLAGS}")

CUDA_ADD_LIBRARY(THCS SHARED ${src} ${src-cuda})
CUDA_ADD_CUBLAS_TO_TARGET(THCS)
TARGET_LINK_LIBRARIES(THCS ${TH_LIBRARIES} ${THC_LIBRARIES} ${THS_LIBRARIES} ${CUDA_cusparse_LIBRARY})

IF(NOT THCS_SO_VERSION)
  SET(THCS_SO_VERSION 1)
ENDIF(NOT THCS_SO_VERSION)
MESSAGE(STATUS "THCS_SO_VERSION: ${THCS_SO_VERSION}")
SET_TARGET_PROPERTIES(THCS PROPERTIES
  VERSION   ${THCS_SO_VERSION}
  SOVERSION ${THCS_SO_VERSION})

INSTALL(TARGETS THCS
          RUNTIME DESTINATION "${THCS_INSTALL_BIN_SUBDIR}"
          LIBRARY DESTINATION "${THCS_INSTALL_LIB_SUBDIR}"
          ARCHIVE DESTINATION "${THCS_INSTALL_LIB_SUBDIR}")

INSTALL(FILES
          THCS.h
          THCSTensor.h
          THCSGenerateAllTypes.h
          THCSGenerateByteType.h
          THCSGenerateCharType.h
          THCSGenerateShortType.h
          THCSGenerateIntType.h
          THCSGenerateLongType.h
          THCSGenerateHalfType.h
          THCSGenerateFloatType.h
          THCSGenerateFloatTypes.h
          THCSGenerateDoubleType.h
          DESTINATION "${THCS_INSTALL_INCLUDE_SUBDIR}/THCS")

INSTALL(FILES
          generic/THCSTensor.c
          generic/THCSTensor.cu
          generic/THCSTensor.h
          generic/THCSTensorMath.h
          generic/THCSTensorMath.cu
          DESTINATION "${THCS_INSTALL_INCLUDE_SUBDIR}/THCS/generic")
