cmake_minimum_required (VERSION 2.8)
project (PASTIX C CXX Fortran)

include(CMakeDependentOption)
include(CheckFunctionExists)

set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)

# The current version number
set (PASTIX_VERSION_MAJOR 5)
set (PASTIX_VERSION_MINOR 2)
set (PASTIX_VERSION_MICRO 3)
set (PASTIX_VERSION_BUGFIX 0)

set( PASTIX_VERSION "${PASTIX_VERSION_MAJOR}.${PASTIX_VERSION_MINOR}.${PASTIX_VERSION_MICRO}" )
add_definitions("-DVERSION=\"\\\"${PASTIX_VERSION}\\\"\"")

set( MORSE_DISTRIB_DIR "" CACHE PATH "Directory of MORSE distribution")

if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_SOURCE_DIR}/cmake_modules/")

  # Add extra cmake module path and initialize morse cmake modules
  # --------------------------------------------------------------
  if(MORSE_DISTRIB_DIR)
    list(APPEND CMAKE_MODULE_PATH ${MORSE_DISTRIB_DIR}/cmake_modules)
    list(APPEND CMAKE_MODULE_PATH "${MORSE_DISTRIB_DIR}/cmake_modules/morse")
    set(MORSE_CMAKE_MODULE_PATH ${MORSE_DISTRIB_DIR}/cmake_modules/morse )
  elseif(EXISTS "${CMAKE_SOURCE_DIR}/cmake_modules/")
    list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake_modules)
    list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules/morse")
    set(MORSE_CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake_modules/morse )
  endif()
  include(MorseInit)
  include(array2d)

  ###############################################################################
  # Set the RPATH config #
  ########################

  # use, i.e. don't skip the full RPATH for the build tree
  set(CMAKE_SKIP_BUILD_RPATH  FALSE)

  # when building, don't use the install RPATH already
  # (but later on when installing)
  set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)

  # the RPATH to be used when installing
  set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")

  ### Misc general options
  option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
  #option(BUILD_64bits "Build 64 bits mode" ON)
  if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
      "Choose the type of build, options are None, Debug, Release, RelWithDebInfo and MinSizeRel." FORCE)
  endif(NOT CMAKE_BUILD_TYPE)

  ###############################################################################
  # Options #
  ###########

  ### Distributed engine parameters
  option(PASTIX_WITH_MPI
    "Build PaStiX for distributed memory with MPI" ON)

  ### Distributed engine parameters
  option(PASTIX_WITH_MULTITHREAD
    "Build PaStiX with multithreading enabled" ON)

  ### GPU engine parameters
  option(PASTIX_WITH_STARPU_CUDA
    "Enable GPU support using CUDA kernels" OFF)

  ### Runtime engines
  option(PASTIX_WITH_STARPU
    "Build PaStiX with StarPU runtime support" OFF)
  option(PASTIX_WITH_STARPU_PROFILING
    "Build PaStiX with StarPU runtime support profiling" OFF)
  #option(PASTIX_WITH_PARSEC
  #  "Build PaStiX with PaRSEC runtime support" OFF)

  option(PASTIX_BLAS_MT
    "Build PaStiX with Blas multithreaded if available (MKL, ESSL, OpenBLAS)" OFF)

  ### Build examples
  option(PASTIX_BUILD_EXAMPLES
    "Build PaStiX example drivers" ON)

  # Some architecture are not detected by cmake (ex: power) so that the user must give the targeted arch
  set( PASTIX_ARCH "" CACHE STRING "To give the architecture, one of: i686_pc_linux, i586_pc_linux2, i686_mac, i686_pc_windows, alpha_compaq_osf1, power_ibm_aix, sun")

  # Fortran mangling
  option(PASTIX_FM_NOCHANGE
    "To add _ or not in FORTRAN_CALL (PASTIX_FM_NOCHANGE=OFF i.e. add _)" OFF)

  ### Internal options

  option(PASTIX_INT64
    "Choose between int32 and int64 for integer representation" OFF)

  option(PASTIX_WITH_MEMORY_USAGE
    "Trace memory allocations" OFF)

  option(PASTIX_DUMP_CBLK
    "Dump all cblk on disk after modifications" OFF)

  cmake_dependent_option(PASTIX_DISTRIBUTED
    "Enable the distributed interface (requires PASTIX_WITH_MPI and PT-Scotch)" OFF "PASTIX_WITH_MPI" OFF)

  cmake_dependent_option(PASTIX_THREAD_COMM
    "Enable the specific communication thread (requires PASTIX_WITH_MPI)" ON "PASTIX_WITH_MPI" OFF)

  cmake_dependent_option(PASTIX_FUNNELED
    "Enable the funneled (requires PASTIX_THREAD_COMM), toggle using IPARM_THREAD_COMM_MODE" ON "PASTIX_WITH_MPI" OFF)

  cmake_dependent_option(PASTIX_DYNSCHED
    "Enable dynamic thread scheduling support (requires PASTIX_WITH_MULTITHREAD)" OFF "PASTIX_WITH_MULTITHREAD" OFF)

  # check consistency of options
  if(PASTIX_FUNNELED)
    set(PASTIX_THREAD_COMM ON CACHE BOOL "Enable the specific communication thread" FORCE)
  endif()
  if(NOT PASTIX_WITH_MULTITHREAD)
    set(PASTIX_THREAD_COMM OFF CACHE BOOL "Enable the specific communication thread" FORCE)
    set(PASTIX_FUNNELED OFF CACHE BOOL "Enable the funneled (requires PASTIX_THREAD_COMM), toggle using IPARM_THREAD_COMM_MODE" FORCE)
  endif()

  if(NOT PASTIX_FLOAT_TYPE)
    set(PASTIX_FLOAT_TYPE "D" CACHE STRING "Default float type: S, D, C, or Z" FORCE)
  else()
    set(PASTIX_FLOAT_TYPE "${PASTIX_FLOAT_TYPE}" CACHE STRING "Default float type: S, D, C, or Z" FORCE)
  endif()

  ### Define precision supported by PASTIX
  set( RP_PASTIX_DICTIONNARY ${MORSE_CMAKE_MODULE_PATH}/precision_generator/subs.py )
  set( RP_PASTIX_PRECISIONS  "s;d;c;z" )
  include(RulesPrecisions)
  # Precisions generated
  if(NOT PASTIX_PRECISIONS)
    set(PASTIX_PRECISIONS "s;d;c;z" CACHE STRING "The precisions to compile in PaSTiX (accepts a colon separated list of s;d;c;z)" FORCE)
  else()
    set(PASTIX_PRECISIONS "${PASTIX_PRECISIONS}" CACHE STRING "The precisions to compile in PaSTiX (accepts a colon separated list of s;d;c;z)" FORCE)
  endif()

  # Ordering step options
  option(PASTIX_ORDERING_SCOTCH
    "Enable Scotch Ordering" ON)
  option(PASTIX_ORDERING_METIS
    "Enable Metis ordering"  OFF)
  cmake_dependent_option(PASTIX_ORDERING_PTSCOTCH
    "Activate the PT-scotch ordering (requires PASTIX_DISTRIBUTED and PASTIX_ORDERING_SCOTCH)" ON
    "PASTIX_DISTRIBUTED;PASTIX_ORDERING_SCOTCH" OFF)

  if (PASTIX_ORDERING_PTSCOTCH)
    # turn distributed mode on if PTSCOTCH is ON MPI found
    set(PASTIX_WITH_MPI ON)
    set(PASTIX_DISTRIBUTED ON)
    message(STATUS "PASTIX_ORDERING_PTSCOTCH is ON so that we turn PASTIX_WITH_MPI and PASTIX_DISTRIBUTED ON")
  endif()

  # Symbolic factorization options
  option(PASTIX_SYMBOL_DUMP_SYMBMTX
    "Dump the generated symbol matrix in a postscript file" OFF)
  option(PASTIX_SYMBOL_FORCELOAD
    "Force the symbol matrix to be loaded from file" OFF)

  # Symbolic factorization options
  option(PASTIX_BLEND_GENTRACE
    "Allow trace generation in Blend simulation" OFF)

  # Options to check
  option(FORGET_PARTITION
    "Force to forget the partition generated by Scotch" OFF)
  option(COMPACT_SMX
    "Optimization for solve computations (TODO: check if not obsolete because results don't converge)" OFF)

  ###############################################################################
  # Look for dependencies #
  #########################

  include(PastixFindDependencies)

  ###############################################################################
  # Define pastix library sources #
  #################################

  include(PastixLibSrc)

  ###############################################################################
  # Set definitions #
  ###################

  include(PastixDefinitions)

  ###############################################################################
  # Generate some headers which depends on the config #
  #####################################################

  include(PastixGenHeaders)

  ###############################################################################
  # Define the matrix_drivers library #
  #####################################
  add_subdirectory(matrix_drivers/src)

  ###############################################################################
  # Define the pastix library #
  #############################

  include(PastixLib)

  ###############################################################################
  # Misc #
  ########

  ### warning message if install prefix not modified by user
  if (CMAKE_INSTALL_PREFIX STREQUAL "/usr/local" OR CMAKE_INSTALL_PREFIX STREQUAL "C:/Program Files")
    message(STATUS "Your CMAKE_INSTALL_PREFIX is ${CMAKE_INSTALL_PREFIX} which is a default system path."
      "You may want to change it: set the CMAKE_INSTALL_PREFIX variable to do so")
  else()
    message(STATUS "Your CMAKE_INSTALL_PREFIX is ${CMAKE_INSTALL_PREFIX}")
  endif()

  ### Generate pastix-conf
  include(GenPastixConf)
  generate_pastixconf("${CMAKE_SOURCE_DIR}/utils/src/pastix-conf.in")

  #### Build examples
  if (PASTIX_BUILD_EXAMPLES)
    add_subdirectory(example/src)
    install( DIRECTORY ${CMAKE_SOURCE_DIR}/matrix DESTINATION .)
  endif()

else(MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_SOURCE_DIR}/cmake_modules/")

  message(STATUS "MORSE_DISTRIB_DIR is not set")
  message(STATUS "Please indicate where is located your MORSE distribution directory."
    " This is necessary to find cmake_modules.")
  message(STATUS "If you are a MORSE developer, you normally have access to the svn repository of the MORSE_DISTRIB_DIR: "
    "svn checkout svn+ssh://yourlogin@scm.gforge.inria.fr/svnroot/morse/trunk/morse_distrib")

endif(MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_SOURCE_DIR}/cmake_modules/")
