Skip to content

Refactor: move procedure definitions submodules #51

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Apr 18, 2022
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
18 changes: 17 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,23 @@ if(CMAKE_Fortran_COMPILER_ID MATCHES Cray)
endif()

# library to archive (libneural.a)
add_library(neural src/mod_activation.f90 src/mod_io.f90 src/mod_kinds.f90 src/mod_layer.f90 src/mod_mnist.f90 src/mod_network.f90 src/mod_parallel.f90 src/mod_random.f90)
add_library(neural
src/mod_activation.f90
src/mod_activation_submodule.f90
src/mod_io.f90
src/mod_io_submodule.f90
src/mod_kinds.f90
src/mod_layer.f90
src/mod_layer_submodule.f90
src/mod_mnist.f90
src/mod_mnist_submodule.f90
src/mod_network.f90
src/mod_network_submodule.f90
src/mod_parallel.f90
src/mod_parallel_submodule.f90
src/mod_random.f90
src/mod_random_submodule.f90
)

# Remove leading or trailing whitespace
string(REGEX REPLACE "^ | $" "" LIBS "${LIBS}")
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ Dependencies:
* OpenCoarrays (optional, for parallel execution, GFortran only)
* BLAS, MKL (optional)

Compilers tested include:

* gfortran-10.3.0
* ifort-2021.4
* ifx-2021.4

### Building with fpm

#### Building in serial mode
Expand Down
4 changes: 2 additions & 2 deletions fpm.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "neural-fortran"
version = "0.1.0"
version = "0.2.0"
license = "MIT"
author = "Milan Curcic"
maintainer = "[email protected]"
copyright = "Copyright 2018-2021, neural-fortran contributors"
copyright = "Copyright 2018-2022, neural-fortran contributors"
158 changes: 75 additions & 83 deletions src/mod_activation.f90
Original file line number Diff line number Diff line change
Expand Up @@ -16,94 +16,86 @@ module mod_activation
public :: tanhf, tanh_prime

interface

pure function activation_function(x)
import :: rk
real(rk), intent(in) :: x(:)
real(rk) :: activation_function(size(x))
end function activation_function
end interface

contains

pure function gaussian(x) result(res)
!! Gaussian activation function.
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
res = exp(-x**2)
end function gaussian

pure function gaussian_prime(x) result(res)
!! First derivative of the Gaussian activation function.
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
res = -2 * x * gaussian(x)
end function gaussian_prime

pure function relu(x) result(res)
!! REctified Linear Unit (RELU) activation function.
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
res = max(0., x)
end function relu

pure function relu_prime(x) result(res)
!! First derivative of the REctified Linear Unit (RELU) activation function.
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
where (x > 0)
res = 1
elsewhere
res = 0
end where
end function relu_prime

pure function sigmoid(x) result(res)
!! Sigmoid activation function.
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
res = 1 / (1 + exp(-x))
endfunction sigmoid

pure function sigmoid_prime(x) result(res)
!! First derivative of the sigmoid activation function.
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
res = sigmoid(x) * (1 - sigmoid(x))
end function sigmoid_prime

pure function step(x) result(res)
!! Step activation function.
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
where (x > 0)
res = 1
elsewhere
res = 0
end where
end function step

pure function step_prime(x) result(res)
!! First derivative of the step activation function.
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
res = 0
end function step_prime

pure function tanhf(x) result(res)
!! Tangent hyperbolic activation function.
!! Same as the intrinsic tanh, but must be
!! defined here so that we can use procedure
!! pointer with it.
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
res = tanh(x)
end function tanhf

pure function tanh_prime(x) result(res)
!! First derivative of the tanh activation function.
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
res = 1 - tanh(x)**2
end function tanh_prime
pure module function gaussian(x) result(res)
!! Gaussian activation function.
implicit none
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
end function gaussian

pure module function gaussian_prime(x) result(res)
!! First derivative of the Gaussian activation function.
implicit none
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
end function gaussian_prime

pure module function relu(x) result(res)
!! REctified Linear Unit (RELU) activation function.
implicit none
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
end function relu

pure module function relu_prime(x) result(res)
!! First derivative of the REctified Linear Unit (RELU) activation function.
implicit none
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
end function relu_prime

pure module function sigmoid(x) result(res)
!! Sigmoid activation function.
implicit none
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
end function sigmoid

pure module function sigmoid_prime(x) result(res)
!! First derivative of the sigmoid activation function.
implicit none
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
end function sigmoid_prime

pure module function step(x) result(res)
!! Step activation function.
implicit none
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
end function step

pure module function step_prime(x) result(res)
!! First derivative of the step activation function.
implicit none
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
end function step_prime

pure module function tanhf(x) result(res)
!! Tangent hyperbolic activation function.
!! Same as the intrinsic tanh, but must be
!! defined here so that we can use procedure
!! pointer with it.
implicit none
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
end function tanhf

pure module function tanh_prime(x) result(res)
!! First derivative of the tanh activation function.
implicit none
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
end function tanh_prime

end interface

end module mod_activation
77 changes: 77 additions & 0 deletions src/mod_activation_submodule.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
submodule(mod_activation) mod_activation_submodule

!! A collection of activation functions and their derivatives.

implicit none

contains

pure module function gaussian(x) result(res)
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
res = exp(-x**2)
end function gaussian

pure module function gaussian_prime(x) result(res)
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
res = -2 * x * gaussian(x)
end function gaussian_prime

pure module function relu(x) result(res)
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
res = max(0., x)
end function relu

pure module function relu_prime(x) result(res)
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
where (x > 0)
res = 1
elsewhere
res = 0
end where
end function relu_prime

pure module function sigmoid(x) result(res)
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
res = 1 / (1 + exp(-x))
endfunction sigmoid

pure module function sigmoid_prime(x) result(res)
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
res = sigmoid(x) * (1 - sigmoid(x))
end function sigmoid_prime

pure module function step(x) result(res)
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
where (x > 0)
res = 1
elsewhere
res = 0
end where
end function step

pure module function step_prime(x) result(res)
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
res = 0
end function step_prime

pure module function tanhf(x) result(res)
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
res = tanh(x)
end function tanhf

pure module function tanh_prime(x) result(res)
real(rk), intent(in) :: x(:)
real(rk) :: res(size(x))
res = 1 - tanh(x)**2
end function tanh_prime

end submodule mod_activation_submodule
44 changes: 15 additions & 29 deletions src/mod_io.f90
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,21 @@ module mod_io
public :: read_binary_file

interface read_binary_file
module procedure :: read_binary_file_1d, read_binary_file_2d
end interface read_binary_file

contains

subroutine read_binary_file_1d(filename, dtype, nrec, array)
character(len=*), intent(in) :: filename
integer(ik), intent(in) :: dtype, nrec
real(rk), allocatable, intent(in out) :: array(:)
integer(ik) :: fileunit
allocate(array(nrec))
open(newunit=fileunit, file=filename, access='direct',&
action='read', recl=dtype * nrec, status='old')
read(fileunit, rec=1) array
close(fileunit)
end subroutine read_binary_file_1d

subroutine read_binary_file_2d(filename, dtype, dsize, nrec, array)
character(len=*), intent(in) :: filename
integer(ik), intent(in) :: dtype, dsize, nrec
real(rk), allocatable, intent(in out) :: array(:,:)
integer(ik) :: fileunit, i
allocate(array(dsize, nrec))
open(newunit=fileunit, file=filename, access='direct',&
action='read', recl=dtype * dsize, status='old')
do i = 1, nrec
read(fileunit, rec=i) array(:,i)
end do
close(fileunit)
end subroutine read_binary_file_2d
module subroutine read_binary_file_1d(filename, dtype, nrec, array)
implicit none
character(len=*), intent(in) :: filename
integer(ik), intent(in) :: dtype, nrec
real(rk), allocatable, intent(in out) :: array(:)
end subroutine read_binary_file_1d

module subroutine read_binary_file_2d(filename, dtype, dsize, nrec, array)
implicit none
character(len=*), intent(in) :: filename
integer(ik), intent(in) :: dtype, dsize, nrec
real(rk), allocatable, intent(in out) :: array(:,:)
end subroutine read_binary_file_2d

end interface read_binary_file

end module mod_io
33 changes: 33 additions & 0 deletions src/mod_io_submodule.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
submodule(mod_io) mod_io_submodule

implicit none

contains

module subroutine read_binary_file_1d(filename, dtype, nrec, array)
character(len=*), intent(in) :: filename
integer(ik), intent(in) :: dtype, nrec
real(rk), allocatable, intent(in out) :: array(:)
integer(ik) :: fileunit
allocate(array(nrec))
open(newunit=fileunit, file=filename, access='direct',&
action='read', recl=dtype * nrec, status='old')
read(fileunit, rec=1) array
close(fileunit)
end subroutine read_binary_file_1d

module subroutine read_binary_file_2d(filename, dtype, dsize, nrec, array)
character(len=*), intent(in) :: filename
integer(ik), intent(in) :: dtype, dsize, nrec
real(rk), allocatable, intent(in out) :: array(:,:)
integer(ik) :: fileunit, i
allocate(array(dsize, nrec))
open(newunit=fileunit, file=filename, access='direct',&
action='read', recl=dtype * dsize, status='old')
do i = 1, nrec
read(fileunit, rec=i) array(:,i)
end do
close(fileunit)
end subroutine read_binary_file_2d

end submodule mod_io_submodule
Loading