Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 19 additions & 88 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,91 +1,24 @@
# CMake version, project name, language
cmake_minimum_required(VERSION 3.20)
project(neural-fortran Fortran)

# Set output paths for modules, archives, and executables
set(CMAKE_Fortran_MODULE_DIRECTORY ${PROJECT_BINARY_DIR}/include)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

# If build type not specified, default to release
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "release")
endif()

if(SERIAL)
message(STATUS "Configuring build for serial execution")
else()
message(STATUS "Configuring build for parallel execution")
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Default build Release")
endif()

find_package(HDF5 COMPONENTS Fortran HL)
include_directories(${HDF5_INCLUDE_DIRS})

include(FetchContent)

FetchContent_Declare(
h5fortran
GIT_REPOSITORY https://github.com/geospace-code/h5fortran
GIT_TAG v4.6.3
project(neural-fortran
LANGUAGES C Fortran
)

FetchContent_Declare(
jsonfortran
GIT_REPOSITORY https://github.com/jacobwilliams/json-fortran
GIT_TAG 8.3.0
)

FetchContent_MakeAvailable(h5fortran jsonfortran)

file(MAKE_DIRECTORY ${h5fortran_BINARY_DIR}/include)
include_directories(${h5fortran_BINARY_DIR}/include)

file(MAKE_DIRECTORY ${jsonfortran_BINARY_DIR}/include)
include_directories(${jsonfortran_BINARY_DIR})

# compiler flags for gfortran
if(CMAKE_Fortran_COMPILER_ID MATCHES GNU)

if(SERIAL)
message(STATUS "Configuring to build with -fcoarray=single")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fcoarray=single")
endif()

if(BLAS)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fexternal-blas ${BLAS}")
set(LIBS "${LIBS} blas")
message(STATUS "Configuring build to use BLAS from ${BLAS}")
endif()

set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -g -fcheck=bounds -fbacktrace")
set(CMAKE_Fortran_FLAGS_RELEASE "-Ofast -fno-frontend-optimize")
endif()

# compiler flags for ifort
if(CMAKE_Fortran_COMPILER_ID MATCHES Intel)

if(SERIAL)
message(STATUS "Configuring to build with -coarray=single")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -coarray=single")
endif()
enable_testing()

set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -assume byterecl")
set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -g -C -traceback")
set(CMAKE_Fortran_FLAGS_RELEASE "-O3")
include(FetchContent)

if(NOT SERIAL)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -coarray=shared")
endif()
include(cmake/options.cmake)
include(cmake/compilers.cmake)

endif()

# compiler flags for Cray ftn
if(CMAKE_Fortran_COMPILER_ID MATCHES Cray)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -h noomp")
set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -g")
set(CMAKE_Fortran_FLAGS_RELEASE "-O3")
endif()
include(cmake/h5fortran.cmake)
include(cmake/json.cmake)

# library to archive (libneural.a)
add_library(neural
Expand Down Expand Up @@ -129,19 +62,17 @@ add_library(neural
src/nf/io/nf_io_hdf5.f90
src/nf/io/nf_io_hdf5_submodule.f90
)
target_link_libraries(neural PRIVATE h5fortran::h5fortran HDF5::HDF5 jsonfortran::jsonfortran)

install(TARGETS neural)

# Remove leading or trailing whitespace
string(REGEX REPLACE "^ | $" "" LIBS "${LIBS}")

# tests
enable_testing()
foreach(execid input1d_layer input3d_layer dense_layer conv2d_layer maxpool2d_layer flatten_layer dense_network dense_network_from_keras conv2d_network io_hdf5 keras_read_model)
add_executable(test_${execid} test/test_${execid}.f90)
target_link_libraries(test_${execid} PRIVATE neural h5fortran::h5fortran jsonfortran ${LIBS})
add_test(test_${execid} bin/test_${execid})
endforeach()

foreach(execid cnn mnist mnist_from_keras simple sine)
add_executable(${execid} example/${execid}.f90)
target_link_libraries(${execid} PRIVATE neural h5fortran::h5fortran jsonfortran ${LIBS})
endforeach()
if(${PROJECT_NAME}_BUILD_TESTING)
add_subdirectory(test)
endif()

if(${PROJECT_NAME}_BUILD_EXAMPLES)
add_subdirectory(example)
endif()
51 changes: 51 additions & 0 deletions cmake/compilers.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# compiler flags for gfortran
if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")

if(SERIAL)
message(STATUS "Configuring to build with -fcoarray=single")
add_compile_options("$<$<COMPILE_LANGUAGE:Fortran>:-fcoarray=single>")
else()
add_compile_options("$<$<COMPILE_LANGUAGE:Fortran>:-fcoarray=lib>")
endif()

if(BLAS)
add_compile_options("$<$<COMPILE_LANGUAGE:Fortran>:-fexternal-blas;${BLAS}>")
list(APPEND LIBS "blas")
message(STATUS "Configuring build to use BLAS from ${BLAS}")
endif()

add_compile_options("$<$<AND:$<COMPILE_LANGUAGE:Fortran>,$<CONFIG:Debug>>:-fcheck=bounds;-fbacktrace>")
add_compile_options("$<$<AND:$<COMPILE_LANGUAGE:Fortran>,$<CONFIG:Release>>:-Ofast;-fno-frontend-optimize;-fno-backtrace>")

elseif(CMAKE_Fortran_COMPILER_ID MATCHES "^Intel")
# compiler flags for ifort

if(SERIAL)
message(STATUS "Configuring to build with -coarray=single")
if(WIN32)
add_compile_options("$<$<COMPILE_LANGUAGE:Fortran>:/Qcoarray:single>")
else()
add_compile_options("$<$<COMPILE_LANGUAGE:Fortran>:-coarray=single>")
endif()
else()
if(WIN32)
add_compile_options("$<$<COMPILE_LANGUAGE:Fortran>:/Qcoarray:shared>")
else()
add_compile_options("$<$<COMPILE_LANGUAGE:Fortran>:-coarray=shared>")
endif()
endif()

if(WIN32)
string(APPEND CMAKE_Fortran_FLAGS " /assume:byterecl")
else()
string(APPEND CMAKE_Fortran_FLAGS " -assume byterecl")
endif()
add_compile_options("$<$<AND:$<COMPILE_LANGUAGE:Fortran>,$<CONFIG:Debug>>:-check;-traceback>")
# add_compile_options("$<$<AND:$<COMPILE_LANGUAGE:Fortran>,$<CONFIG:Release>>:-O3>")

elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "Cray")
# compiler flags for Cray ftn
string(APPEND CMAKE_Fortran_FLAGS " -h noomp")
add_compile_options("$<$<AND:$<COMPILE_LANGUAGE:Fortran>,$<CONFIG:Debug>>:-O0;-g>")
add_compile_options("$<$<AND:$<COMPILE_LANGUAGE:Fortran>,$<CONFIG:Release>>:-O3>")
endif()
15 changes: 15 additions & 0 deletions cmake/h5fortran.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
set(h5fortran_BUILD_TESTING false)

FetchContent_Declare(h5fortran
GIT_REPOSITORY https://github.com/geospace-code/h5fortran
GIT_TAG v4.6.3
GIT_SHALLOW true
)

FetchContent_MakeAvailable(h5fortran)

file(MAKE_DIRECTORY ${h5fortran_BINARY_DIR}/include)


list(APPEND CMAKE_MODULE_PATH ${h5fortran_SOURCE_DIR}/cmake/Modules)
find_package(HDF5 COMPONENTS Fortran REQUIRED)
35 changes: 35 additions & 0 deletions cmake/json.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# use our own CMake script to build jsonfortran instead of jsonfortran/CMakelists.txt

FetchContent_Declare(jsonfortran
GIT_REPOSITORY https://github.com/jacobwilliams/json-fortran
GIT_TAG 8.3.0
GIT_SHALLOW true
)

FetchContent_Populate(jsonfortran)

SET(JSON_REAL_KIND "REAL64")
SET(JSON_INT_KIND "INT32")

set(_src ${jsonfortran_SOURCE_DIR}/src)

set (JF_LIB_SRCS
${_src}/json_kinds.F90
${_src}/json_parameters.F90
${_src}/json_string_utilities.F90
${_src}/json_value_module.F90
${_src}/json_file_module.F90
${_src}/json_module.F90
)

add_library(jsonfortran ${JF_LIB_SRCS})
target_compile_definitions(jsonfortran PRIVATE ${JSON_REAL_KIND} ${JSON_INT_KIND})
target_include_directories(jsonfortran PUBLIC
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>
)

add_library(jsonfortran::jsonfortran INTERFACE IMPORTED GLOBAL)
target_link_libraries(jsonfortran::jsonfortran INTERFACE jsonfortran)

install(TARGETS jsonfortran)
30 changes: 30 additions & 0 deletions cmake/options.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
option(SERIAL "Serial execution")
option(${PROJECT_NAME}_BUILD_TESTING "build ${PROJECT_NAME} tests" true)
option(${PROJECT_NAME}_BUILD_EXAMPLES "build ${PROJECT_NAME} examples" true)

# Set output paths for modules, archives, and executables
set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/include)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

if(SERIAL)
message(STATUS "Configuring build for serial execution")
else()
message(STATUS "Configuring build for parallel execution")
endif()

# --- Generally useful CMake project options

# Rpath options necessary for shared library install to work correctly in user projects
set(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_PREFIX}/lib)
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH true)

# Necessary for shared library with Visual Studio / Windows oneAPI
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS true)

# --- auto-ignore build directory
if(NOT EXISTS ${PROJECT_BINARY_DIR}/.gitignore)
file(WRITE ${PROJECT_BINARY_DIR}/.gitignore "*")
endif()
4 changes: 4 additions & 0 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
foreach(execid cnn mnist mnist_from_keras simple sine)
add_executable(${execid} ${execid}.f90)
target_link_libraries(${execid} PRIVATE neural h5fortran::h5fortran jsonfortran::jsonfortran ${LIBS})
endforeach()
10 changes: 10 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
foreach(execid input1d_layer input3d_layer dense_layer conv2d_layer maxpool2d_layer flatten_layer dense_network dense_network_from_keras conv2d_network io_hdf5 keras_read_model)
add_executable(test_${execid} test_${execid}.f90)
target_link_libraries(test_${execid} PRIVATE neural h5fortran::h5fortran jsonfortran::jsonfortran ${LIBS})

add_test(NAME test_${execid} COMMAND test_${execid})
endforeach()

set_tests_properties(test_dense_network_from_keras test_io_hdf5 test_keras_read_model PROPERTIES
RESOURCE_LOCK download
)