option(
    GINKGO_BUILD_EXTLIB_EXAMPLE
    "Build the external-lib-interfacing with deal.II, you need to link the deal.II library."
    OFF
)

set(EXAMPLES_EXEC_LIST
    adaptiveprecision-blockjacobi
    batched-solver
    cb-gmres
    custom-logger
    ginkgo-ranges
    ilu-preconditioned-solver
    ir-ilu-preconditioned-solver
    inverse-iteration
    iterative-refinement
    mixed-precision-ir
    nine-pt-stencil-solver
    poisson-solver
    preconditioned-solver
    simple-solver
    three-pt-stencil-solver
)

set(EXAMPLES_LIST
    ${EXAMPLES_EXEC_LIST}
    custom-stopping-criterion
    file-config-solver
    ginkgo-overhead
    minimal-cuda-solver
    mixed-spmv
    mixed-multigrid-solver
    mixed-multigrid-preconditioned-solver
    multigrid-preconditioned-solver
    multigrid-preconditioned-solver-customized
    par-ilu-convergence
    performance-debugging
    preconditioner-export
    reordered-preconditioned-solver
    simple-solver-logging
)

if(GINKGO_BUILD_CUDA AND GINKGO_BUILD_OMP)
    list(APPEND EXAMPLES_LIST custom-matrix-format)
endif()

if(GINKGO_BUILD_EXTLIB_EXAMPLE)
    list(APPEND EXAMPLES_LIST external-lib-interfacing)
endif()

find_package(OpenCV QUIET)
if(OpenCV_FOUND)
    list(APPEND EXAMPLES_LIST heat-equation schroedinger-splitting)
else()
    message(STATUS "No OpenCV found, disabling examples with video output")
endif()

if(GINKGO_HAVE_PAPI_SDE)
    list(APPEND EXAMPLES_LIST papi-logging)
endif()

if(GINKGO_BUILD_MPI)
    list(
        APPEND
        EXAMPLES_LIST
        distributed-solver
        distributed-multigrid-preconditioned-solver
    )
endif()

find_package(Kokkos 4.1.00 QUIET)
if(Kokkos_FOUND)
    list(APPEND EXAMPLES_LIST kokkos-assembly)
else()
    message(STATUS "No Kokkos found, disabling examples with Kokkos assembly.")
endif()

foreach(example ${EXAMPLES_LIST})
    add_subdirectory(${example})
endforeach()

if(GINKGO_BUILD_TESTS)
    find_package(Python3 COMPONENTS Interpreter REQUIRED)
    set(executors)
    if(GINKGO_BUILD_REFERENCE)
        list(APPEND executors reference)
    endif()
    # OpenMP support is needed for some host kernels
    if(GINKGO_BUILD_CUDA AND GINKGO_BUILD_OMP)
        list(APPEND executors cuda)
    endif()
    if(GINKGO_BUILD_HIP AND GINKGO_BUILD_OMP)
        list(APPEND executors hip)
    endif()
    # DPC++ support is incomplete
    #if(GINKGO_BUILD_SYCL)
    #    list(APPEND executors dpcpp)
    #endif()
    if(GINKGO_BUILD_OMP)
        list(APPEND executors omp)
    endif()
    foreach(example IN LISTS EXAMPLES_EXEC_LIST)
        foreach(executor IN LISTS executors)
            add_test(
                NAME example_${example}_${executor}
                COMMAND
                    ${Python3_EXECUTABLE}
                    "${CMAKE_CURRENT_SOURCE_DIR}/compare-output.py"
                    "${CMAKE_CURRENT_BINARY_DIR}/${example}"
                    "$<TARGET_FILE_DIR:ginkgo>"
                    "${CMAKE_CURRENT_SOURCE_DIR}/${example}/doc/results.dox"
                    "$<TARGET_FILE:${example}>" "${executor}"
                WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${example}"
            )
            # Prevent performance issues with high core counts
            set_property(
                TEST example_${example}_${executor}
                PROPERTY ENVIRONMENT OMP_NUM_THREADS=4
            )
        endforeach()
    endforeach()

    file(
        GLOB config_list
        RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
        file-config-solver/config/*.json
    )
    foreach(config IN LISTS config_list)
        get_filename_component(config_name "${config}" NAME_WE)
        foreach(executor IN LISTS executors)
            add_test(
                NAME example_file-config-solver_${config_name}_${executor}
                COMMAND
                    "$<TARGET_FILE:file-config-solver>" "${executor}"
                    "${CMAKE_CURRENT_SOURCE_DIR}/file-config-solver/config/${config_name}.json"
                    "${CMAKE_CURRENT_SOURCE_DIR}/file-config-solver/data/A.mtx"
                WORKING_DIRECTORY "$<TARGET_FILE_DIR:ginkgo>"
            )
            # Prevent performance issues with high core counts
            set_property(
                TEST example_file-config-solver_${config_name}_${executor}
                PROPERTY ENVIRONMENT OMP_NUM_THREADS=4
            )
        endforeach()
    endforeach()
endif()
