if (MGARD_ENABLE_SERIAL)
  list(APPEND DEVICE_TYPE_LIST SERIAL)
endif()
if (MGARD_ENABLE_CUDA)
  list(APPEND DEVICE_TYPE_LIST CUDA)
endif()
if (MGARD_ENABLE_HIP)
  list(APPEND DEVICE_TYPE_LIST HIP)
endif()
if (MGARD_ENABLE_SYCL)
  list(APPEND DEVICE_TYPE_LIST SYCL)
endif()

set(DATA_TYPE_LIST double float)
set(NUM_DIM_LIST 1 2 3 4 5)
  
function(MgardXGenerateSourceAllCombinations src_file_prefix)
  foreach(DEVICE_TYPE IN LISTS DEVICE_TYPE_LIST)
    foreach(DATA_TYPE IN LISTS DATA_TYPE_LIST)
      foreach(NUM_DIM IN LISTS NUM_DIM_LIST)
        set(SRC_FILE "${CMAKE_CURRENT_SOURCE_DIR}/${src_file_prefix}.cpp.in")
        set(GEN_FILE "${CMAKE_CURRENT_BINARY_DIR}/${src_file_prefix}_${NUM_DIM}D_${DATA_TYPE}_${DEVICE_TYPE}.cpp")
        configure_file(${SRC_FILE} ${GEN_FILE})
        if (${DEVICE_TYPE} STREQUAL "SERIAL")
          set_source_files_properties(${GEN_FILE} PROPERTIES LANGUAGE CXX)
          list(APPEND MGARD_X_SERIAL_SRC ${GEN_FILE})
        endif()
        if (${DEVICE_TYPE} STREQUAL "CUDA")
          set_source_files_properties(${GEN_FILE} PROPERTIES LANGUAGE CUDA)
          list(APPEND MGARD_X_CUDA_SRC ${GEN_FILE})
        endif()
        if (${DEVICE_TYPE} STREQUAL "HIP")
          set_source_files_properties(${GEN_FILE} PROPERTIES LANGUAGE HIP)
          list(APPEND MGARD_X_HIP_SRC ${GEN_FILE})
        endif()
        if (${DEVICE_TYPE} STREQUAL "SYCL")
          set_source_files_properties(${GEN_FILE} PROPERTIES LANGUAGE CXX)
          list(APPEND MGARD_X_SYCL_SRC ${GEN_FILE})
        endif()
        
      endforeach()
    endforeach()
  endforeach()
  set(MGARD_X_SERIAL_SRC ${MGARD_X_SERIAL_SRC} PARENT_SCOPE)
  set(MGARD_X_CUDA_SRC ${MGARD_X_CUDA_SRC} PARENT_SCOPE)
  set(MGARD_X_HIP_SRC ${MGARD_X_HIP_SRC} PARENT_SCOPE)
  set(MGARD_X_SYCL_SRC ${MGARD_X_SYCL_SRC} PARENT_SCOPE)
endfunction()

function(MgardXGenerateSourceAllDevices src_file_prefix)
  foreach(DEVICE_TYPE IN LISTS DEVICE_TYPE_LIST)
    set(SRC_FILE "${CMAKE_CURRENT_SOURCE_DIR}/${src_file_prefix}.cpp.in")
    set(GEN_FILE "${CMAKE_CURRENT_BINARY_DIR}/${src_file_prefix}_${DEVICE_TYPE}.cpp")
    configure_file(${SRC_FILE} ${GEN_FILE})
    if (${DEVICE_TYPE} STREQUAL "SERIAL")
      set_source_files_properties(${GEN_FILE} PROPERTIES LANGUAGE CXX)
      list(APPEND MGARD_X_SERIAL_SRC ${GEN_FILE})
    endif()
    if (${DEVICE_TYPE} STREQUAL "CUDA")
      set_source_files_properties(${GEN_FILE} PROPERTIES LANGUAGE CUDA)
      list(APPEND MGARD_X_CUDA_SRC ${GEN_FILE})
    endif()
    if (${DEVICE_TYPE} STREQUAL "HIP")
      set_source_files_properties(${GEN_FILE} PROPERTIES LANGUAGE HIP)
      list(APPEND MGARD_X_HIP_SRC ${GEN_FILE})
    endif()
    if (${DEVICE_TYPE} STREQUAL "SYCL")
      set_source_files_properties(${GEN_FILE} PROPERTIES LANGUAGE CXX)
      list(APPEND MGARD_X_SYCL_SRC ${GEN_FILE})
    endif()
  endforeach()
  set(MGARD_X_SERIAL_SRC ${MGARD_X_SERIAL_SRC} PARENT_SCOPE)
  set(MGARD_X_CUDA_SRC ${MGARD_X_CUDA_SRC} PARENT_SCOPE)
  set(MGARD_X_HIP_SRC ${MGARD_X_HIP_SRC} PARENT_SCOPE)
  set(MGARD_X_SYCL_SRC ${MGARD_X_SYCL_SRC} PARENT_SCOPE)
endfunction()