###
#
#  @file CMakeLists.txt
# 
#  @project MORSE
#  MORSE is a software package provided by:
#     Inria Bordeaux - Sud-Ouest,
#     Univ. of Tennessee,
#     Univ. of California Berkeley,
#     Univ. of Colorado Denver.
# 
#  @version 0.1.0
#  @author Cedric Castagnede
#  @date 13-07-2012
#   
###

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
INCLUDE(RulesPrecisions)

# Generate the morse auxiliary headers for all possible precisions
# ----------------------------------------------------------------
SET(MORSE_AUX_HDRS_GENERATED "")
SET(ZHDR
    zauxiliary.h
   )
precisions_rules_py(MORSE_AUX_HDRS_GENERATED "${ZHDR}"
                    PRECISIONS "${MAGMA_MORSE_PRECISION}"
                    DICTIONARY "MORSE")
SET(MORSE_AUX_HDRS
    auxiliary.h
    timing.h
    timing.c
    ${MORSE_AUX_HDRS_GENERATED}
   )

# Force generation of headers
# ---------------------------
ADD_CUSTOM_TARGET(timing_include ALL SOURCES ${MORSE_AUX_HDRS})

# Generate the morse auxiliary sources for all possible precisions
# ----------------------------------------------------------------
SET(MORSE_AUX_SRCS_GENERATED "")
SET(ZSRC
    zauxiliary.c
   )
precisions_rules_py(MORSE_AUX_SRCS_GENERATED "${ZSRC}"
                    PRECISIONS "${MAGMA_MORSE_PRECISION}"
                    DICTIONARY "MORSE")
SET(MORSE_SRCS
    auxiliary.c
    ${MORSE_AUX_SRCS_GENERATED}
   )

# Force generation of headers
# ---------------------------
ADD_CUSTOM_TARGET(timing_source ALL SOURCES ${MORSE_SRCS})

# Create libauxilary.a
# --------------------
ADD_LIBRARY(morse_timing STATIC ${MORSE_SRCS})
SET_PROPERTY(TARGET morse_timing PROPERTY LINKER_LANGUAGE Fortran)
ADD_DEPENDENCIES(morse_timing timing_include)
ADD_DEPENDENCIES(morse_timing timing_source)

FOREACH(_external_package "blas" "cblas" "lapack" "lapacke" "quark" "starpu")
    STRING(TOUPPER "${_external_package}" _NAMEVAR)
    IF(${_NAMEVAR}_EP)
        ADD_DEPENDENCIES(morse_timing ${_external_package}_build)
    ENDIF()
ENDFOREACH()

# Generate the morse testing sources for all possible precisions
# --------------------------------------------------------------
SET(MORSE_TESTS_GENERATED "")
SET(ZTEST
    ##################
    # BLAS 3
    ##################
    time_zgemm.c
    time_zgemm_tile.c
    time_ztrsm.c
    ##################
    # LAPACK
    ##################
    time_zgels.c
    time_zgels_tile.c
    time_zgeqrf.c
    time_zgeqrf_tile.c
    time_zgetrf_incpiv.c
    time_zgetrf_incpiv_tile.c
    #time_zgetrf.c
    #time_zgetrf_tile.c
    time_zposv.c
    time_zposv_tile.c
    time_zpotrf.c
    time_zpotrf_tile.c
    time_zpotri_tile.c
    ##################
    # MIXED PRECISION
    ##################
    #time_zcgesv.c
    #time_zcgesv_tile.c
    #time_zcposv.c
    #time_zcposv_tile.c
    ##################
    # OTHERS
    ##################
    #time_zgebrd_tile.c
    #time_zgecfi.c
    #time_zgesvd_tile.c
    #time_zgetrf_reclap.c
    #time_zgetrf_rectil.c
    #time_zheevd_tile.c
    #time_zheev_tile.c
    #time_zhegv_tile.c
    #time_zlapack2tile.c
    #time_zgetri_tile.c
    #time_zgesv.c
    #time_zgesv_tile.c
    #time_zgesv_incpiv.c
    #time_zgesv_incpiv_tile.c
   )

#IF(MORSE_SCHED_QUARK)
#    SET(ZTEST
#        ${ZTEST}
#        time_zgels.c
#        time_zgels_tile.c
#        time_zgeqrf.c
#        time_zgeqrf_tile.c
#        time_zgetrf_incpiv.c
#        time_zgetrf_incpiv_tile.c
#       )
#ENDIF(MORSE_SCHED_QUARK)

precisions_rules_py(MORSE_TESTS_GENERATED "${ZTEST}"
                    PRECISIONS "${MAGMA_MORSE_PRECISION}"
                    DICTIONARY "MORSE")

SET(MORSE_TESTS ${MORSE_TESTS_GENERATED})
ADD_CUSTOM_TARGET(time_source ALL SOURCES ${MORSE_TESTS})

# Add include and link directories
# --------------------------------
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})

# Add tests (C/CPP)
# -----------------
UNSET(libs_for_tests)
LIST(APPEND libs_for_tests morse_timing)
LIST(APPEND libs_for_tests magma_morse)

IF(MORSE_SCHED_STARPU)
    LIST(APPEND libs_for_tests morse_starpu)
    LIST(APPEND libs_for_tests ${STARPU_LIBRARIES})
    LIST(APPEND libs_for_tests coreblas)
ELSEIF(MORSE_SCHED_QUARK)
    LIST(APPEND libs_for_tests morse_quark)
    LIST(APPEND libs_for_tests ${QUARK_LIBRARIES})
    LIST(APPEND libs_for_tests coreblas)
ENDIF()

IF(MAGMA)
    LIST(APPEND libs_for_tests magma)
    LIST(APPEND libs_for_tests magmablas)
    LIST(APPEND libs_for_tests magma)
    LIST(APPEND libs_for_tests "${CUDA_LDFLAGS}")
ENDIF()

FOREACH(_dep LAPACKE LAPACK CBLAS BLAS)
    IF(HAVE_${_dep})
        LIST(APPEND libs_for_tests ${${_dep}_LIBRARY})
    ENDIF()
ENDFOREACH()
FOREACH(_dep QUARK HWLOC MPI DL)
    IF(HAVE_${_dep})
        LIST(APPEND libs_for_tests ${${_dep}_LIBRARIES})
    ENDIF()
ENDFOREACH()

LIST(APPEND libs_for_tests ${CMAKE_Fortran_FLAGS})
LIST(APPEND libs_for_tests ${CMAKE_Fortran_LDFLAGS})
LIST(APPEND libs_for_tests ${MORSE_EXTRA_LIBS})

FOREACH(_test_src ${MORSE_TESTS_GENERATED})
    GET_FILENAME_COMPONENT(_name_exe ${_test_src} NAME_WE)
    ADD_EXECUTABLE(${_name_exe} ${_test_src})
    SET_PROPERTY(TARGET ${_name_exe} PROPERTY LINKER_LANGUAGE Fortran)
    TARGET_LINK_LIBRARIES(${_name_exe} ${libs_for_tests})

    IF(HAVE_MPI)
        ADD_TEST(NAME ${_name_exe} 
                 COMMAND ${MPIEXEC} -np 2 ${_name_exe} --n_range=1000:2000:1000 --check)
    ELSE(HAVE_MPI)
        ADD_TEST(NAME ${_name_exe} 
                 COMMAND ${_name_exe} --n_range=1000:2000:1000 --check)
    ENDIF(HAVE_MPI)
ENDFOREACH()

