diff --git a/CMakeLists.txt b/CMakeLists.txt index e859c1001cf7d0ad1aa8a261510c3eb8614dc5f9..967e1141cec81b64d4b9e31014d8d2c88e87f20f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,27 +26,37 @@ endif (NOT CMAKE_BUILD_TYPE) # funroll-all-loops a bez prepinace set(standard "-std=f2008") +get_filename_component (Fortran_COMPILER_NAME ${CMAKE_Fortran_COMPILER} NAME) + +if (WITH_TIME_PROFILING) + add_definitions(-DTIME_PROFILING) +endif() + +message ("Fortran compiler name: " ${Fortran_COMPILER_NAME}) +message ("CMAKE_Fortran_COMPILER full path: " ${CMAKE_Fortran_COMPILER}) +message ("Fortran compiler: " ${Fortran_COMPILER_NAME}) +message ("Build type:" ${CMAKE_BUILD_TYPE}) if (Fortran_COMPILER_NAME MATCHES "gfortran.*") # gfortran - set (CMAKE_Fortran_FLAGS_RELEASE "-funroll-loops -fno-f2c -O3 ${standard}") - set (CMAKE_Fortran_FLAGS_DEBUG "-fno-f2c -O0 -g ${standard}") + set (CMAKE_Fortran_FLAGS_RELEASE "-funroll-loops -fno-f2c -O3 ${standard} -cpp") + set (CMAKE_Fortran_FLAGS_DEBUG "-fno-f2c -O0 -g ${standard} -cpp") elseif (Fortran_COMPILER_NAME MATCHES "ifort.*") # ifort (untested) - set (CMAKE_Fortran_FLAGS_RELEASE "-f77rtl -O3 ${standard}") - set (CMAKE_Fortran_FLAGS_DEBUG "-f77rtl -O0 -g ${standard}") + set (CMAKE_Fortran_FLAGS_RELEASE "-f77rtl -O3 ${standard} -cpp") + set (CMAKE_Fortran_FLAGS_DEBUG "-f77rtl -O0 -g ${standard} -cpp") elseif (Fortran_COMPILER_NAME MATCHES "g77") # g77 - set (CMAKE_Fortran_FLAGS_RELEASE "-funroll-loops -fno-f2c -O3 -m32 ${standard}") - set (CMAKE_Fortran_FLAGS_DEBUG "-fno-f2c -O0 -g -m32 ${standard}") + set (CMAKE_Fortran_FLAGS_RELEASE "-funroll-loops -fno-f2c -O3 -m32 ${standard} -cpp") + set (CMAKE_Fortran_FLAGS_DEBUG "-fno-f2c -O0 -g -m32 ${standard} -cpp") else (Fortran_COMPILER_NAME MATCHES "gfortran.*") - message ("CMAKE_Fortran_COMPILER full path: " ${CMAKE_Fortran_COMPILER}) - message ("Fortran compiler: " ${Fortran_COMPILER_NAME}) message ("No optimized Fortran compiler flags are known, we just try -O2...") - set (CMAKE_Fortran_FLAGS_RELEASE "-O2 ${standard}") - set (CMAKE_Fortran_FLAGS_DEBUG "-O0 -g ${standard}") + set (CMAKE_Fortran_FLAGS_RELEASE "-O2 ${standard} -cpp") + set (CMAKE_Fortran_FLAGS_DEBUG "-O0 -g ${standard} -cpp") endif (Fortran_COMPILER_NAME MATCHES "gfortran.*") +#(Fortran_COMPILER_NAME MATCHES "gfortran.*") + #----------------# # User variables # #----------------# diff --git a/build.sh b/build.sh index 6231cf85f3f42641d1b9bac498bad1ad1c0a88ac..bb911a42da730ad95cfdcc7f6e003b00aa374f06 100755 --- a/build.sh +++ b/build.sh @@ -1,11 +1,23 @@ #!/bin/bash +#------------#------------------------------------------------------------ +# Parameters # +#------------# + +# Build type (Release/Debug) +BUILD_TYPE=Debug + +# Turn of/off time profiling (1/0) +WITH_TIME_PROFILING=0 + +#------------------------------------------------------------------------- + echo "Creating folder 'build'..."; mkdir -p build/lib; echo "Folder 'build' was created'"; cd build; -cmake ..; -make && echo "Installation complete." || exit -1; +cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DWITH_TIME_PROFILING:BOOLEAN=${WITH_TIME_PROFILING} .. +make VERBOSE=1 && echo "Build complete." || exit -1; #make install; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5a2e0ac728d8eea07500642edfcbda4f41017a83..426f3b91933effd6951ae27d790e74b1b29d9052 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,9 +1,6 @@ project(Modules) enable_language(Fortran) -set(standard "-std=f2008") -set(CMAKE_Fortran_FLAGS "${standard}") - add_library(neuron_dummy_m SHARED neuron_dummy_m.f90) set_target_properties(neuron_dummy_m PROPERTIES LINKER_LANGUAGE Fortran) diff --git a/src/connection_m.f90 b/src/connection_m.f90 index 6358244430cd9bf7c946dcf4bb74b1854c9fdddd..9ca14c245f7d90f7b6135c442c712c9dac7f14dc 100644 --- a/src/connection_m.f90 +++ b/src/connection_m.f90 @@ -1,15 +1,13 @@ !> Module containing classes representing connections (synapses) !! in neural networks. !! -!! It uses `neural_t` class. +!! It uses `neuron_t` class. !! !! @author Martin Beseda !! @author Martin Mrovec !! @date 2017 -!! @todo Implement destructor -!! @todo Comment constructor +!! @todo Change generating random connection weights from uniform to Gaussian distribution module connection_m - ! TODO Implement destructor use neuron_dummy_m implicit none @@ -21,7 +19,7 @@ module connection_m !------------------! !> Represents a connection between two neurons. - type, abstract :: connection_t + type :: connection_t private class(neuron_t), pointer :: input_neuron !< Pointer to an input neuron @@ -33,11 +31,15 @@ module connection_m !> Initializes the common connection_t class components !! 'input_neuron', 'output_neuron' and 'weight'. !! I.e. serves similarly to an abstract constructor. + !! @param input_neuron Pointer to the input neuron (instance of neuron_t) + !! @param output_neuron Pointer to the output neuron (instance of neuron_t) + !! @param weight Weight of the connection (real number) procedure, private :: init_components => init_components_impl - !procedure :: destroy_instance => destroy_instance_impl - - !final, deferred :: destructor + !> Nullifies pointers to input and output neurons, so they + !! don't get destroyed when the connection_t instance is + !! deallocated. + procedure, private :: nullify_pointers => nullify_pointers_impl !> Adds a given value to the current weight of the !! connection. @@ -56,6 +58,9 @@ module connection_m !! @return Weight of the connection (type real) procedure :: get_weight => get_weight_impl + !> Desctructor for instances of the class connection_t + final :: destroy_connection + end type connection_t !> Represents a connection between two neurons. @@ -68,14 +73,36 @@ module connection_m !! input neuron state * weight) !! to an output neuron. procedure :: pass_signal => pass_signal_impl + end type interval_connection_t !------------!------------------------------------------------------------------------------ ! Interfaces ! !------------! + interface connection_t + !> Constructor of connection_t class + !! @param input_neuron Pointer to the input neuron (instance of neuron_t) + !! @param output_neuron Pointer to the output neuron (instance of neuron_t) + module procedure :: new_connection_2 + + !> Constructor of connection_t class + !! @param input_neuron Pointer to the input neuron (instance of neuron_t) + !! @param output_neuron Pointer to the output neuron (instance of neuron_t) + !! @param weight Weight of the connection (real number) + module procedure :: new_connection_3 + end interface connection_t + interface interval_connection_t !> Constructor of interval_connection_t class - module procedure :: new_interval_connection + !! @param input_neuron Pointer to the input neuron (instance of neuron_t) + !! @param output_neuron Pointer to the output neuron (instance of neuron_t) + module procedure :: new_interval_connection_2 + + !> Constructor of interval_connection_t class + !! @param input_neuron Pointer to the input neuron (instance of neuron_t) + !! @param output_neuron Pointer to the output neuron (instance of neuron_t) + !! @param weight Weight of the connection (real number) + module procedure :: new_interval_connection_3 end interface interval_connection_t contains @@ -83,38 +110,66 @@ module connection_m ! Method implementations ! ! -----------------------! - !subroutine destroy_instance_impl(this) - ! class(connection_t), pointer, intent(out) :: this - - ! deallocate(this) - !end subroutine destroy_instance_impl - !--------------------! ! class connection_t ! !--------------------! + function new_connection_2(input_neuron, output_neuron) result(new_obj) + type(neuron_t), pointer, intent(in) :: input_neuron + type(neuron_t), pointer, intent(in) :: output_neuron + real :: weight + type(connection_t), pointer :: new_obj + + allocate(new_obj) + + ! todo change to random numbers from Gaussian distribution + call random_seed() + call random_number(weight) + + call new_obj%init_components(input_neuron, output_neuron, weight) + end function new_connection_2 + + + function new_connection_3(input_neuron, output_neuron, weight) result(new_obj) + type(neuron_t), pointer, intent(in) :: input_neuron + type(neuron_t), pointer, intent(in) :: output_neuron + real, intent(in) :: weight + type(connection_t), pointer :: new_obj + + allocate(new_obj) + + call new_obj%init_components(input_neuron, output_neuron, weight) + end function new_connection_3 + subroutine init_components_impl(this, input_neuron, output_neuron, weight) class(connection_t), intent(inout) :: this type(neuron_t), pointer :: input_neuron type(neuron_t), pointer :: output_neuron real, intent(in) :: weight - !DEC$ IF DEFINED TIME_PROFILING +#ifdef TIME_PROFILING real :: t1, t2 !< Variables used for time measurement call cpu_time(t1) - !DEC$ ENDIF +#endif this%input_neuron => input_neuron this%output_neuron => output_neuron this%weight = weight - !DEC$ IF DEFINED TIME_PROFILING +#ifdef TIME_PROFILING call cpu_time(t2) write(*, "(A)") '+----------------+' write(*, "(A, E15.7, A)") '| TIME PROFILING | Function init_components() was running for ', t2-t1, 's.' write(*, "(A)") '+----------------+' - !DEC$ ENDIF +#endif end subroutine init_components_impl + + subroutine nullify_pointers_impl(this) + class(connection_t), intent(inout) :: this + + nullify(this%input_neuron) + nullify(this%output_neuron) + end subroutine nullify_pointers_impl subroutine adjust_weight_impl(this, added_value) class(connection_t), intent(inout) :: this @@ -123,6 +178,12 @@ module connection_m this%weight = this%weight + added_value end subroutine adjust_weight_impl + subroutine destroy_connection(this) + type(connection_t), intent(inout) :: this + + call this%nullify_pointers() + end subroutine destroy_connection + !-----------------------------! ! class interval_connection_t ! !-----------------------------! @@ -135,16 +196,31 @@ module connection_m !--------------!------------------------------------------------------------------------ ! Constructors ! !--------------! - function new_interval_connection(input_neuron, output_neuron, weight) result(ret_obj) + function new_interval_connection_2(input_neuron, output_neuron) result(new_obj) + type(neuron_t), pointer :: input_neuron + type(neuron_t), pointer :: output_neuron + real :: weight + type(interval_connection_t), pointer :: new_obj + + allocate(new_obj) + + ! todo change to random numbers from Gaussian distribution + call random_seed() + call random_number(weight) + + call new_obj%init_components(input_neuron, output_neuron, weight) + end function new_interval_connection_2 + + function new_interval_connection_3(input_neuron, output_neuron, weight) result(new_obj) type(neuron_t), pointer :: input_neuron type(neuron_t), pointer :: output_neuron real, intent(in) :: weight - type(interval_connection_t), pointer :: ret_obj + type(interval_connection_t), pointer :: new_obj - allocate(ret_obj) + allocate(new_obj) - call ret_obj%init_components(input_neuron, output_neuron, weight) - end function new_interval_connection + call new_obj%init_components(input_neuron, output_neuron, weight) + end function new_interval_connection_3 !-------------------!------------------------------------------------------------------- ! Getters & Setters ! diff --git a/src/connection_test.f90 b/src/connection_test.f90 index 16883f5fa8bb655c4fc2f85f717edcec2da31325..8dbb24a1db1ad057da1e04dce025ba8a0674d5ce 100644 --- a/src/connection_test.f90 +++ b/src/connection_test.f90 @@ -26,6 +26,9 @@ program connection_test print *, 'Assignment was successful.' print *, 'Creating an instance of the class interval_connection_t...' + !con => interval_connection_t(input_neuron=n1_p, & + ! output_neuron=n2_p,& + ! weight=5.25) con => interval_connection_t(n1_p, n2_p, 5.25) print *, 'The instance of the class interval_connection_t was created successfully.' @@ -80,6 +83,8 @@ program connection_test stop -1 end if + deallocate(con) + print *, '+-------------------------------------------------------------+' print *, '| ALL TESTS OF THE MODULE CONNECTION_M WERE RUN SUCCESSFULLY. |' print *, '+-------------------------------------------------------------+'