Skip to content

Commit

Permalink
cmake
Browse files Browse the repository at this point in the history
  • Loading branch information
rae-ra committed Feb 11, 2024
1 parent 5070748 commit 6303a5e
Show file tree
Hide file tree
Showing 10 changed files with 325 additions and 18 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,11 @@
*.exe
*.out
*.app


*.DS_Store
build/*
*.prefs
.classpath
.cproject
.project
60 changes: 60 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
cmake_minimum_required(VERSION 3.14.0)

project(nerofort
LANGUAGES Fortran
)


include(${PROJECT_SOURCE_DIR}/cmake/nerofort.cmake)


# Config
#add_subdirectory(config)


# Set compiler options
if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU)
add_compile_options(-fimplicit-none)
add_compile_options(-ffree-line-length-132)
add_compile_options(-Wall)
add_compile_options(-Wextra)
add_compile_options(-Wimplicit-procedure)
add_compile_options(-Wconversion-extra)
# -pedantic-errors triggers a false positive for optional arguments of elemental functions,
# see test_optval and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95446
add_compile_options(-pedantic-errors)
if(CMAKE_Fortran_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0)
add_compile_options(-std=f2018)
else()
add_compile_options(-std=f2008ts)
endif()
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL Intel)
add_compile_options(-warn declarations,general,usage,interfaces,unused)
if(NOT CMAKE_Fortran_COMPILER_VERSION VERSION_EQUAL 20.2.1.20200827)
add_compile_options(-standard-semantics)
endif()
if(CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 18.0)
add_compile_options(-stand f15)
else()
add_compile_options(-stand f18)
endif()
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL PGI)
add_compile_options(-Mdclchk)
endif()

# Add src
add_subdirectory(src
)
# Set include directories
target_include_directories(nerofort PRIVATE src)

# Set the output binary directory
set_target_properties(nerofort PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)

find_program(FYPP fypp)
if(NOT FYPP)
message(FATAL_ERROR "Preprocessor fypp not found!")
endif()

42 changes: 42 additions & 0 deletions cmake/nerofort.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Preprocesses a list of files with given preprocessor and preprocessor options
#
# Args:
# preproc [in]: Preprocessor program
# preprocopts [in]: Preprocessor options
# srcext [in]: File extension of the source files
# trgext [in]: File extension of the target files
# srcfiles [in]: List of the source files
# trgfiles [out]: Contains the list of the preprocessed files on exit
#
function(preprocess preproc preprocopts srcext trgext srcfiles trgfiles)

set(_trgfiles)
foreach(srcfile IN LISTS srcfiles)
string(REGEX REPLACE "\\.${srcext}$" ".${trgext}" trgfile ${srcfile})
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${trgfile}
COMMAND ${preproc} ${preprocopts} ${CMAKE_CURRENT_SOURCE_DIR}/${srcfile} ${CMAKE_CURRENT_BINARY_DIR}/${trgfile}
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/${srcfile})
list(APPEND _trgfiles ${CMAKE_CURRENT_BINARY_DIR}/${trgfile})
endforeach()
set(${trgfiles} ${_trgfiles} PARENT_SCOPE)

endfunction()



# Preprocesses fortran files with fypp.
#
# It assumes that source files have the ".fypp" extension. Target files will be
# created with the extension ".f90". The FYPP variable must contain the path to
# the fypp-preprocessor.
#
# Args:
# fyppopts [in]: Options to pass to fypp.
# fyppfiles [in]: Files to be processed by fypp
# f90files [out]: List of created f90 files on exit
#
function (fypp_f90 fyppopts fyppfiles f90files)
preprocess("${FYPP}" "${fyppopts}" "fypp" "f90" "${fyppfiles}" _f90files)
set(${f90files} ${_f90files} PARENT_SCOPE)
endfunction()
40 changes: 40 additions & 0 deletions config/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# SPDX-Identifier: MIT

# Export a pkg-config file
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/template.pc"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
@ONLY
)
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
)

# Export CMake package file
include(CMakePackageConfigHelpers)
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/template.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
if(BUILD_SHARED_LIBS)
# Due to the uncertain ABI compatibility of Fortran shared libraries
# limit compatibility for dynamic linking to same minor version.
set(COMPATIBILITY SameMinorVersion)
else()
# Require API compatibility via semantic versioning for static linking,
set(COMPATIBILITY SameMajorVersion)
endif()
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
VERSION "${PROJECT_VERSION}"
COMPATIBILITY ${COMPATIBILITY}
)
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
5 changes: 5 additions & 0 deletions config/template.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@PACKAGE_INIT@

if(NOT TARGET "@PROJECT_NAME@::@PROJECT_NAME@")
include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")
endif()
9 changes: 9 additions & 0 deletions config/template.pc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
prefix=@CMAKE_INSTALL_PREFIX@
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@

Name: @PROJECT_NAME@
Description: @PROJECT_DESCRIPTION@
Version: @PROJECT_VERSION@
Libs: -L${libdir} -l@PROJECT_NAME@
Cflags: -I${includedir}
17 changes: 14 additions & 3 deletions nerofort.prj
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,17 @@
"Name":"+src",
"Files":[{
"filename":"src/Activation_mod.f90",
"enabled":"1"
"enabled":"1",
"panel":1,
"open":"1"
},{
"filename":"src/Batch_norm_mod.f90",
"enabled":"1"
},{
"filename":"src/Conv2D_mod.f90",
"enabled":"1"
"enabled":"1",
"panel":1,
"open":"1"
},{
"filename":"src/Cost_mod.f90",
"enabled":"1"
Expand All @@ -89,7 +93,14 @@
"enabled":"1"
},{
"filename":"src/Padding2D_mod.f90",
"enabled":"1"
"enabled":"1",
"panel":1,
"open":"1"
},{
"filename":"src/Pooling2D_mod.f90",
"enabled":"1",
"panel":1,
"open":"1"
},{
"filename":"src/Util.f90",
"enabled":"1"
Expand Down
15 changes: 0 additions & 15 deletions src/Activation_mod.f90
Original file line number Diff line number Diff line change
Expand Up @@ -159,21 +159,6 @@ function gen_back_4(this, dz) result(dx)
dx = internal_backpropagation(this,dz, cache_x_4)
end function gen_back_4
















function internal_forward(this, X) result(z)
class(Activation), intent(in) :: this
real(dp), intent(in) :: X (:,:,:,:)
Expand Down
34 changes: 34 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Set the source files
set(SRC
data/dict_mod.f90
data/str_mod.f90
math/clip_mod.f90
math/data_types.f90
math/einsum_mod.f90
math/Math_util.f90
math/utility_mod.f90
math/activations/d_prelu_mod.f90
math/activations/d_relu_mod.f90
math/activations/d_sigmoid_mod.f90
math/activations/d_softmax_mod.f90
math/activations/d_tanh_mod.f90
math/activations/prelu_mod.f90
math/activations/relu_mod.f90
math/activations/sigmoid_mod.f90
math/activations/softmax_mod.f90
Activation_mod.f90
Batch_norm_mod.f90
Conv2D_mod.f90
Cost_mod.f90
Dense_mod.f90
Learning_rate_decay_mod.f90
Main.f90
Optimizer_mod.f90
Padding2D_mod.f90
Pooling2D_mod.f90
Util.f90
W_reg_mod.f90
Weights_mod.f90
)
# Add an executable
add_executable(nerofort ${SRC})
113 changes: 113 additions & 0 deletions src/Pooling2D_mod.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
module Pooling2D_mod
use Padding2D_mod
use Conv2D_MOD, only: prepare_submatrix
use Math_UTIL, only: dp
implicit none

type :: Pooling2D
type(Padding2D) :: padding
integer :: pool_size(2)
integer :: s(2)
integer :: Kh, Kw
integer :: sh, sw
character(len=6) :: pool_type
end type Pooling2D

contains

subroutine init_Pooling2D(this, pool_size, s, p, pool_type)
class(Pooling2D), intent(inout) :: this
integer, intent(in) :: pool_size(2), s(2)
character(len=*), intent(in) :: p, pool_type

call Padding_init(this%padding, p=p)
this%pool_size = pool_size
this%s = s
this%Kh = pool_size(1)
this%Kw = pool_size(2)
this%sh = s(1)
this%sw = s(2)
this%pool_type = pool_type
end subroutine init_Pooling2D

subroutine get_dimensions(this, input_shape, output_shape)
class(Pooling2D), intent(inout) :: this
integer, intent(in) :: input_shape(4)
integer, intent(out) :: output_shape(4)

integer :: m, Nc, Nh, Nw, Oh, Ow

if (size(input_shape) == 4) then
m = input_shape(1)
Nc = input_shape(2)
Nh = input_shape(3)
Nw = input_shape(4)
elseif (size(input_shape) == 3) then
Nc = input_shape(1)
Nh = input_shape(2)
Nw = input_shape(3)
endif

Oh = (Nh - this%Kh) / this%sh + 1
Ow = (Nw - this%Kw) / this%sw + 1

if (size(input_shape) == 4) then
output_shape = (/m, Nc, Oh, Ow/)
elseif (size(input_shape) == 3) then
output_shape = (/Nc, Oh, Ow, 1/)
endif
end subroutine get_dimensions

subroutine max_pool_prep_subMatrix(X, pool_size, s, subM)
real(dp), intent(in) :: X(:,:,:,:)
integer, intent(in) :: pool_size(2), s(2)
real(dp), allocatable, intent(out) :: subM(:,:,:,:,:,:)

call prepare_submatrix(X, pool_size(1), pool_size(2), s, subM)


end subroutine max_pool_prep_subMatrix

subroutine pooling(X, pool_size, s, pool_type, Z)
real(dp), intent(in) :: X(:,:,:,:)
integer, intent(in) :: pool_size(2), s(2)
character(len=3), intent(in) :: pool_type
real(dp), allocatable, intent(out) :: Z(:,:,:,:)

real(dp), allocatable :: subM(:,:,:,:,:,:)
integer :: Oh, Ow

call max_pool_prep_subMatrix(X, pool_size, s, subM)
Oh = size(subM, 3)
Ow = size(subM, 4)

if (pool_type == 'max') then
Z = maxval(maxval(subM, dim=5), dim=5)
elseif (pool_type == 'mean') then
Z = sum(sum(subM, dim=5), dim=5) / &
(size(subM, 5) * size(subM, 6))
else
stop "Allowed pool types are only 'max' or 'mean'."
endif

deallocate(subM)

end subroutine pooling


subroutine forward(this, X, Z)
class(Pooling2D), intent(inout) :: this
real(dp), intent(in) :: X(:,:,:,:)
real(dp), allocatable, intent(out) :: Z(:,:,:,:)

real(dp), allocatable :: Xp(:,:,:,:)

call pad_forward(this%padding, X, this%pool_size, this%s, Xp)

call pooling(Xp, this%pool_size, this%s, this%pool_type, Z)

deallocate(Xp)

end subroutine forward

end module Pooling2D_mod

0 comments on commit 6303a5e

Please sign in to comment.