configure_file(config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/config.h)

# phi auto cmake utils
include(phi)

set(common_srcs CACHE INTERNAL "" FORCE)
set(api_srcs CACHE INTERNAL "" FORCE)
set(capi_srcs CACHE INTERNAL "" FORCE)
set(core_srcs CACHE INTERNAL "" FORCE)
set(backends_srcs CACHE INTERNAL "" FORCE)
set(kernels_srcs CACHE INTERNAL "" FORCE)
set(infermeta_srcs CACHE INTERNAL "" FORCE)
#set(excluded_srcs CACHE INTERNAL "" FORCE)

# paddle experimental common components
add_subdirectory(common)

# phi (low level) api headers: include
# phi (high level) api
add_subdirectory(api)
# phi core components
add_subdirectory(core)
# phi components of specific backends
add_subdirectory(backends)
# phi kernels for diff device
add_subdirectory(kernels)
# phi infermeta
add_subdirectory(infermeta)
# phi tools
add_subdirectory(tools)
# phi capi
if(WITH_CUSTOM_DEVICE)
  add_subdirectory(capi)
endif()

set(PHI_DEPS
    phi_profiler_proto
    auto_parallel_proto
    gflags
    glog
    warpctc
    warprnnt
    eigen3
    xxhash
    cblas
    utf8proc)

set(INFERENCE_DEPS phi_profiler_proto auto_parallel_proto)

if(WITH_GPU)
  list(APPEND PHI_DEPS external_error_proto)
endif()

if(WITH_ASCEND_CL)
  list(APPEND PHI_DEPS npu_hccl)
endif()

if(WITH_FLASHATTN)
  list(APPEND PHI_DEPS flashattn)
endif()

if(WITH_XBYAK)
  list(APPEND PHI_DEPS xbyak)
endif()

if(WITH_MKLDNN)
  list(APPEND PHI_DEPS mkldnn)
endif()

if(WITH_GLOO)
  list(APPEND PHI_DEPS gloo)
endif()

if(WITH_CUDNN_FRONTEND)
  list(APPEND PHI_DEPS cudnn-frontend)
endif()

if(WITH_POCKETFFT)
  list(APPEND PHI_DEPS pocketfft)
endif()

if(WITH_MKLML)
  list(APPEND PHI_DEPS pocketfft dynload_mklml)
  list(APPEND INFERENCE_DEPS dynload_mklml)
endif()

if(WITH_XPU)
  list(APPEND PHI_DEPS xpulib)
  if(WITH_XPU_PLUGIN)
    add_subdirectory(kernels/xpu/plugin)
    list(APPEND PHI_DEPS xpuplugin)
  endif()
endif()

set(PHI_SRCS
    ${common_srcs}
    ${api_srcs}
    ${core_srcs}
    ${backends_srcs}
    ${kernels_srcs}
    ${infermeta_srcs}
    ${capi_srcs})

if(WITH_SHARED_PHI)
  set(PHI_BUILD_TYPE
      SHARED
      CACHE INTERNAL "" FORCE)
else()
  set(PHI_BUILD_TYPE
      STATIC
      CACHE INTERNAL "" FORCE)
endif()

if(WITH_GPU)
  set_source_files_properties(
    backends/gpu/gpu_resources.cc
    PROPERTIES COMPILE_FLAGS
               "-DCUDA_REAL_ARCHS=\"${NVCC_FLAGS_EXTRA_real_archs}\"")
  nv_library(
    phi ${PHI_BUILD_TYPE}
    SRCS ${PHI_SRCS}
    DEPS ${PHI_DEPS})
elseif(WITH_ROCM)
  hip_add_library(phi ${PHI_BUILD_TYPE} ${PHI_SRCS})
  target_link_libraries(phi ${PHI_DEPS})
elseif(WITH_XPU_KP)
  xpu_library(
    phi ${PHI_BUILD_TYPE}
    SRCS ${PHI_SRCS}
    DEPS ${PHI_DEPS})
else()
  cc_library(
    phi ${PHI_BUILD_TYPE}
    SRCS ${PHI_SRCS}
    DEPS ${PHI_DEPS})
endif()

if(WIN32)
  target_link_libraries(phi shlwapi.lib)
endif()

if(WIN32)
  if(WITH_SHARED_PHI)
    set_property(TARGET phi PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS ON)
    set(PHI_NAME
        phi.dll
        CACHE INTERNAL "" FORCE)
  else()
    set(PHI_NAME
        phi.lib
        CACHE INTERNAL "" FORCE)
  endif()
elseif(APPLE)
  if(WITH_SHARED_PHI)
    set(PHI_NAME
        libphi.dylib
        CACHE INTERNAL "" FORCE)
  else()
    set(PHI_NAME
        libphi.a
        CACHE INTERNAL "" FORCE)
  endif()
else()
  if(WITH_SHARED_PHI)
    set(PHI_NAME
        libphi.so
        CACHE INTERNAL "" FORCE)
  else()
    set(PHI_NAME
        libphi.a
        CACHE INTERNAL "" FORCE)
  endif()
endif()

set(PHI_LIB
    "${CMAKE_CURRENT_BINARY_DIR}/${PHI_NAME}"
    CACHE FILEPATH "PHI Library" FORCE)

if(MKL_FOUND AND WITH_ONEMKL)
  target_include_directories(phi PRIVATE ${MKL_INCLUDE})
endif()

add_dependencies(phi extern_lapack)
if(WITH_CUTLASS)
  add_dependencies(phi cutlass_codegen)
  add_definitions("-DPADDLE_WITH_MEMORY_EFFICIENT_ATTENTION"
  )# for memory_efficient_attention.h
endif()
if(WITH_FLASHATTN)
  add_dependencies(phi flashattn)
endif()

# for inference static library
if(NOT WITH_SHARED_PHI)
  get_property(phi_modules GLOBAL PROPERTY PHI_MODULES)
  set(phi_modules ${phi_modules} ${INFERENCE_DEPS} phi)
  set_property(GLOBAL PROPERTY PHI_MODULES "${phi_modules}")
endif()

set(phi_extension_header_file
    ${CMAKE_CURRENT_SOURCE_DIR}/extension.h
    CACHE INTERNAL "phi/extension.h file")
file(
  WRITE ${phi_extension_header_file}
  "// Header file generated by paddle/phi/CMakeLists.txt for external users,\n// DO NOT edit or include it within paddle.\n\n#pragma once\n\n"
)

file(APPEND ${phi_extension_header_file} "#include \"paddle/phi/config.h\"\n\n")
# generate inner headers include dir for users
generate_unify_header(backends EXCLUDES context_pool_utils.h)
generate_unify_header(core EXCLUDES cuda_stream.h)
generate_unify_header(infermeta)
generate_unify_header(kernels SKIP_SUFFIX grad_kernel)
