cmake_minimum_required(VERSION 3.15)
project(aenet Fortran)



find_package(MPI    REQUIRED)


add_definitions(-DPARALLEL)

add_library(lbfgsb STATIC )

set(URL "https://github.com/atomisticnet/aenet-PyTorch/archive/refs/heads/main.zip")
message(STATUS "URL=${URL}")

if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
  # using GCC
  #message(STATUS "GCC.")
  #add_definitions("-fdefault-integer-8")
else()
message(STATUS ${CMAKE_Fortran_COMPILER_ID})
  #add_definitions("-i4")
endif()




set(FILE_NAME "main.zip")
set(aenet_PATH "${CMAKE_CURRENT_BINARY_DIR}/aenetlib")
set(FILE_PATH "${aenet_PATH}/${FILE_NAME}")

if(NOT EXISTS ${FILE_PATH})
    # ダウンロード
    file(MAKE_DIRECTORY "${aenet_PATH}")
    file(DOWNLOAD "${URL}" "${FILE_PATH}" SHOW_PROGRESS)

    message(STATUS "extracting...")
    execute_process(
        COMMAND ${CMAKE_COMMAND} -E tar xvf "${FILE_PATH}"
        WORKING_DIRECTORY "${aenet_PATH}"
    )
    execute_process(
      COMMAND ${CMAKE_COMMAND} -E tar xvf "${aenet_PATH}/aenet-PyTorch-main/aenet_modified/lib/Lbfgsb.3.0.tar.gz"
      WORKING_DIRECTORY "${aenet_PATH}/aenet-PyTorch-main/aenet_modified//lib/"
    )
    message(STATUS "extracted.")
else()
    message(STATUS "${FILE_NAME} already downloaded.")
endif()

if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/src_modified)
message(STATUS "apply patch.")
execute_process(
        COMMAND cp -r  "${aenet_PATH}/aenet-PyTorch-main/aenet_modified/lib" ./
        COMMAND cp -r  "${aenet_PATH}/aenet-PyTorch-main/aenet_modified/src" ./
        COMMAND cp  "${CMAKE_CURRENT_SOURCE_DIR}/src.patch" "${CMAKE_CURRENT_BINARY_DIR}/"
        COMMAND cp  "${CMAKE_CURRENT_SOURCE_DIR}/apply_patch.sh" "${CMAKE_CURRENT_BINARY_DIR}/"
        COMMAND sh apply_patch.sh
        #COMMAND cp -r  "${aenet_PATH}/aenet-PyTorch-main/src" "${CMAKE_BINARY_DIR}/"
        #COMMAND cp -r  "${CMAKE_CURRENT_SOURCE_DIR}/aenet_pytorch_pimd.py" "${CMAKE_BINARY_DIR}/"
        
        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
    )
message(STATUS "done.")
endif()

message(STATUS "python script is copied.")
execute_process(
        COMMAND cp -r  "${aenet_PATH}/aenet-PyTorch-main/src" "${CMAKE_BINARY_DIR}/src_pytorch"
        COMMAND cp -r  "${CMAKE_CURRENT_SOURCE_DIR}/aenet_pytorch_pimd.py" "${CMAKE_BINARY_DIR}/src_pytorch/"
        
        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
    )
message(STATUS "done.")


add_custom_command(
  TARGET lbfgsb
  POST_BUILD
  COMMAND cp  $<TARGET_FILE:lbfgsb>  ${CMAKE_SOURCE_DIR}
)

set(LBFGSB ${CMAKE_CURRENT_BINARY_DIR}/lib/Lbfgsb.3.0)

target_sources(lbfgsb
PRIVATE
${LBFGSB}/blas.f
${LBFGSB}/lbfgsb.f
${LBFGSB}/linpack.f
${LBFGSB}/timer.f
)


add_executable(trainbin2ASCII.x ${aenet_PATH}/aenet-PyTorch-main/tools/trainbin2ASCII.f90)
add_executable(nnASCII2bin.x ${aenet_PATH}/aenet-PyTorch-main/tools/nnASCII2bin.f90)

if (NOT CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
  add_custom_command(
    TARGET nnASCII2bin.x
    POST_BUILD
    COMMAND cp  $<TARGET_FILE:nnASCII2bin.x>  ${CMAKE_BINARY_DIR}
  )
  add_custom_command(
    TARGET trainbin2ASCII.x
    POST_BUILD
    COMMAND cp  $<TARGET_FILE:trainbin2ASCII.x>  ${CMAKE_BINARY_DIR})
endif ()




add_library(aenet STATIC)
target_link_libraries(aenet PRIVATE  lbfgsb)

set(aenet_dir ${CMAKE_CURRENT_BINARY_DIR}/src_modified)

set(SOURCES
  ${aenet_dir}/ext/chebyshev.f90 
  ${aenet_dir}/ext/feedforward.f90  
  ${aenet_dir}/ext/io.f90  
  ${aenet_dir}/ext/lclist.f90  
  ${aenet_dir}/ext/sfbasis.f90  
  ${aenet_dir}/ext/sortlib.f90  
  ${aenet_dir}/ext/symmfunc.f90  
  ${aenet_dir}/ext/timing.f90
    ${aenet_dir}/ext/unittest.f90  
    ${aenet_dir}/ext/xsflib.f90
    ${aenet_dir}/aenet.f90 
  ${aenet_dir}/aeio.f90
  ${aenet_dir}/constants.f90
  ${aenet_dir}/geometry.f90
  ${aenet_dir}/input.f90
  ${aenet_dir}/optimize.f90
  ${aenet_dir}/parallel.F90
  ${aenet_dir}/potential.f90
  ${aenet_dir}/random.f90
  ${aenet_dir}/sfsetup.f90
  ${aenet_dir}/trainset.f90
  ${aenet_dir}/pytorchoutput.f90
  ${aenet_dir}/pytorchoutput_MPI.f90
  ${aenet_dir}/sub_generate.f90
  ${aenet_dir}/sub_trainbin2ASCII.f90
  ${aenet_dir}/sub_nnASCII2bin.f90
  ${aenet_dir}/trainset_MPI.f90
  ${aenet_dir}/sub_generate_MPI.f90
)

set(MKL_INTERFACE lp64)
if (CMAKE_Fortran_COMPILER_ID STREQUAL "Fujitsu")
else()
  if(MKLUSE)
    find_package(MKL REQUIRED)
  else()
    find_package(LAPACK REQUIRED)
  endif()
endif()
add_executable(aenet_generate.x ${aenet_dir}/generate.f90 ${SOURCES})
add_executable(aenet_generate_MPI.x ${aenet_dir}/generate_MPI.F90 ${SOURCES})


if(NOT MATHLIBDONE)
  if (CMAKE_Fortran_COMPILER_ID STREQUAL "Fujitsu")
    target_link_libraries(aenet_generate.x PRIVATE lbfgsb ${LAPACK_LIBRARIES} )
    target_link_libraries(aenet_generate_MPI.x PRIVATE lbfgsb ${LAPACK_LIBRARIES} )

  else()
    if(MKLUSE)
        target_link_libraries(aenet_generate.x PRIVATE  lbfgsb MKL::MKL )
        target_link_libraries(aenet_generate_MPI.x PRIVATE  lbfgsb MKL::MKL )
    else()
    	target_link_libraries(aenet_generate.x PRIVATE lbfgsb ${LAPACK_LIBRARIES} )
      target_link_libraries(aenet_generate_MPI.x PRIVATE lbfgsb ${LAPACK_LIBRARIES} )
    endif()
      
  endif()
else()
  target_link_libraries(aenet_generate.x PRIVATE lbfgsb )
  target_link_libraries(aenet_generate_MPI.x PRIVATE lbfgsb )
endif() 

target_sources(aenet
PRIVATE
${SOURCES}
)


add_custom_command(
  TARGET aenet
  PRE_BUILD
  COMMAND cd "${aenet_PATH}/aenet-PyTorch-main/aenet_modified"
)

set(aenet_dir aenetlib/aenet-PyTorch-main/aenet_modified)



if(MPI_COMPILE_FLAGS)
  set_target_properties(aenet  PROPERTIES
    COMPILE_FLAGS "${MPI_COMPILE_FLAGS}")

endif()


include_directories(SYSTEM ${MPI_C_INCLUDE_PATH} ${MPI_CXX_INCLUDE_PATH})

target_link_libraries(aenet PRIVATE ${MPI_LIBRARIES})
target_include_directories(aenet PRIVATE ${MPI_INCLUDE_PATH})

target_link_libraries(aenet PRIVATE MPI::MPI_Fortran)

target_compile_definitions(aenet PUBLIC PARALLEL )

if (NOT CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
add_custom_command(
  TARGET aenet
  POST_BUILD
  COMMAND cp  $<TARGET_FILE:aenet>  ${CMAKE_BINARY_DIR}
)
  
add_custom_command(
  TARGET aenet_generate.x
  POST_BUILD
  COMMAND cp  $<TARGET_FILE:aenet_generate.x>  ${CMAKE_BINARY_DIR}
  )

add_custom_command(
  TARGET aenet_generate_MPI.x
  POST_BUILD
  COMMAND cp  $<TARGET_FILE:aenet_generate_MPI.x>  ${CMAKE_BINARY_DIR}
)
endif()



set(SRC_DIR src)

