GCC Code Coverage Report


Directory: src/athena/
File: src/athena/athena_full_layer.f90
Date: 2026-04-15 16:08:59
Exec Total Coverage
Lines: 235 262 89.7%
Functions: 0 0 -%
Branches: 699 1466 47.7%

Line Branch Exec Source
1 module athena__full_layer
2 !! Module containing implementation of a fully connected layer
3 !!
4 !! This module implements a fully connected (dense) layer, the fundamental
5 !! building block of neural networks that connects every input to every output.
6 !!
7 !! Mathematical operation:
8 !! \[ \mathbf{y} = \sigma(\mathbf{W}\mathbf{x} + \mathbf{b}) \]
9 !!
10 !! where:
11 !! - \(\mathbf{x} \in \mathbb{R}^{n_{in}}\) is the input vector
12 !! - \(\mathbf{W} \in \mathbb{R}^{n_{out} \times n_{in}}\) is the weight matrix
13 !! - \(\mathbf{b} \in \mathbb{R}^{n_{out}}\) is the bias vector
14 !! - \(\sigma\) is the activation function
15 !! - \(\mathbf{y} \in \mathbb{R}^{n_{out}}\) is the output vector
16 !!
17 !! Number of parameters: \(n_{out} \times n_{in} + n_{out}\) (if bias used)
18 !!
19 !! Properties: Universal function approximator (with sufficient width/depth)
20 !! Learns arbitrary non-linear mappings between input and output spaces
21 !!
22 !! Attribution statement:
23 !! The get_num_params procedure is based on code from the
24 !! neural-fortran library
25 !! https://github.com/modern-fortran/neural-fortran
26 use coreutils, only: real32, stop_program
27 use athena__base_layer, only: learnable_layer_type, base_layer_type
28 use athena__misc_types, only: base_actv_type, base_init_type, &
29 onnx_node_type, onnx_initialiser_type, onnx_tensor_type
30 use diffstruc, only: array_type, matmul, operator(+)
31 use athena__initialiser_data, only: data_init_type
32 implicit none
33
34
35 private
36
37 public :: full_layer_type
38 public :: read_full_layer, create_from_onnx_full_layer
39
40
41 type, extends(learnable_layer_type) :: full_layer_type
42 !! Type for fully connected (aka dense) layer with overloaded procedures
43 integer :: num_inputs
44 !! Number of inputs
45 integer :: num_outputs
46 !! Number of outputs
47 type(array_type), dimension(1) :: z
48 !! Temporary arrays for forward propagation
49 contains
50 procedure, pass(this) :: get_num_params => get_num_params_full
51 !! Get the number of parameters for fully connected layer
52 procedure, pass(this) :: set_hyperparams => set_hyperparams_full
53 !! Set the hyperparameters for fully connected layer
54 procedure, pass(this) :: init => init_full
55 !! Initialise fully connected layer
56 procedure, pass(this) :: print_to_unit => print_to_unit_full
57 !! Print the layer to a file
58 procedure, pass(this) :: read => read_full
59 !! Read the layer from a file
60 procedure, pass(this) :: build_from_onnx => build_from_onnx_full
61 !! Build fully connected layer from ONNX node and initialiser
62
63 procedure, pass(this) :: forward => forward_full
64 !! Forward propagation derived type handler
65
66 final :: finalise_full
67 !! Finalise fully connected layer
68 end type full_layer_type
69
70 interface full_layer_type
71 !! Interface for setting up the fully connected layer
72 module function layer_setup( &
73 num_outputs, num_inputs, use_bias, &
74 activation, &
75 kernel_initialiser, bias_initialiser, verbose &
76 ) result(layer)
77 !! Setup a fully connected layer
78 integer, intent(in) :: num_outputs
79 !! Number of outputs
80 integer, optional, intent(in) :: num_inputs
81 !! Number of inputs
82 logical, optional, intent(in) :: use_bias
83 !! Whether to use bias
84 class(*), optional, intent(in) :: activation
85 !! Activation function
86 class(*), optional, intent(in) :: kernel_initialiser, bias_initialiser
87 !! Kernel and bias initialisers
88 integer, optional, intent(in) :: verbose
89 !! Verbosity level
90 type(full_layer_type) :: layer
91 !! Instance of the fully connected layer
92 end function layer_setup
93 end interface full_layer_type
94
95
96
97 contains
98
99 !###############################################################################
100 99 subroutine finalise_full(this)
101 !! Finalise fully connected layer
102 implicit none
103
104 ! Arguments
105 type(full_layer_type), intent(inout) :: this
106 !! Instance of the fully connected layer
107
108
3/4
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 76 times.
99 if(allocated(this%input_shape)) deallocate(this%input_shape)
109
4/6
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 76 times.
✓ Branch 5 taken 76 times.
✗ Branch 6 not taken.
99 if(allocated(this%output)) deallocate(this%output)
110
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 83 times.
99 if(this%z(1)%allocated) call this%z(1)%deallocate()
111
112 99 end subroutine finalise_full
113 !###############################################################################
114
115
116 !##############################################################################!
117 ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !
118 !##############################################################################!
119
120
121 !###############################################################################
122 63 pure function get_num_params_full(this) result(num_params)
123 !! Get the number of parameters for fully connected layer
124 !!
125 !! This function calculates the number of parameters for a fully connected
126 !! layer.
127 !! This procedure is based on code from the neural-fortran library
128 implicit none
129
130 ! Arguments
131 class(full_layer_type), intent(in) :: this
132 !! Instance of the fully connected layer
133 integer :: num_params
134 !! Number of parameters
135
136 63 num_params = ( this%num_inputs + 1 )* this%num_outputs
137
138 63 end function get_num_params_full
139 !###############################################################################
140
141
142 !##############################################################################!
143 ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !
144 !##############################################################################!
145
146
147 !###############################################################################
148 63 module function layer_setup( &
149 num_outputs, num_inputs, &
150 use_bias, &
151 activation, &
152 kernel_initialiser, bias_initialiser, verbose &
153
9/16
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 63 times.
✓ Branch 2 taken 63 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 63 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 63 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 63 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 63 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 63 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 63 times.
126 ) result(layer)
154 !! Setup a fully connected layer
155 use athena__activation, only: activation_setup
156 use athena__initialiser, only: initialiser_setup
157 implicit none
158
159 ! Arguments
160 integer, intent(in) :: num_outputs
161 !! Number of outputs
162 integer, optional, intent(in) :: num_inputs
163 !! Number of inputs
164 logical, optional, intent(in) :: use_bias
165 !! Whether to use bias
166 class(*), optional, intent(in) :: activation
167 !! Activation function
168 class(*), optional, intent(in) :: kernel_initialiser, bias_initialiser
169 !! Activation function, kernel initialiser, and bias initialiser
170 integer, optional, intent(in) :: verbose
171 !! Verbosity level
172
173 type(full_layer_type) :: layer
174 !! Instance of the fully connected layer
175
176 ! Local variables
177 integer :: verbose_ = 0
178 !! Verbosity level
179 logical :: use_bias_ = .true.
180 !! Whether to use bias
181 189 class(base_actv_type), allocatable :: activation_
182 !! Activation function
183 63 class(base_init_type), allocatable :: kernel_initialiser_, bias_initialiser_
184 !! Kernel and bias initialisers
185
186
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 52 times.
63 if(present(verbose)) verbose_ = verbose
187
188
189 !---------------------------------------------------------------------------
190 ! Set use_bias
191 !---------------------------------------------------------------------------
192
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 48 times.
63 if(present(use_bias)) use_bias_ = use_bias
193
194
195 !---------------------------------------------------------------------------
196 ! Set activation functions based on input name
197 !---------------------------------------------------------------------------
198
3/4
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
63 if(present(activation))then
199
5/14
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 6 taken 39 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 39 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 39 times.
✓ Branch 17 taken 39 times.
✗ Branch 18 not taken.
39 activation_ = activation_setup(activation)
200 else
201
5/14
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 24 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 24 times.
✓ Branch 17 taken 24 times.
✗ Branch 18 not taken.
24 activation_ = activation_setup("none")
202 end if
203
204
205 !---------------------------------------------------------------------------
206 ! Define weights (kernels) and biases initialisers
207 !---------------------------------------------------------------------------
208
3/4
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
63 if(present(kernel_initialiser))then
209
5/14
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 6 taken 37 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 37 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 37 times.
✓ Branch 17 taken 37 times.
✗ Branch 18 not taken.
37 kernel_initialiser_ = initialiser_setup(kernel_initialiser)
210 end if
211
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
63 if(present(bias_initialiser))then
212
5/14
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 10 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 10 times.
✓ Branch 17 taken 10 times.
✗ Branch 18 not taken.
10 bias_initialiser_ = initialiser_setup(bias_initialiser)
213 end if
214
215
216 !---------------------------------------------------------------------------
217 ! Set hyperparameters
218 !---------------------------------------------------------------------------
219 call layer%set_hyperparams( &
220 num_outputs = num_outputs, &
221 use_bias = use_bias_, &
222 activation = activation_, &
223 kernel_initialiser = kernel_initialiser_, &
224 bias_initialiser = bias_initialiser_, &
225 verbose = verbose_ &
226 63 )
227
228
229 !---------------------------------------------------------------------------
230 ! Initialise layer shape
231 !---------------------------------------------------------------------------
232
4/4
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 44 times.
107 if(present(num_inputs)) call layer%init(input_shape=[num_inputs])
233
234
17/28
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 63 times.
✓ Branch 2 taken 63 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 63 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 63 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 63 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 63 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 63 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 63 times.
✓ Branch 16 taken 37 times.
✓ Branch 17 taken 26 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 37 times.
✓ Branch 21 taken 10 times.
✓ Branch 22 taken 53 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 10 times.
✓ Branch 26 taken 63 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 63 times.
189 end function layer_setup
235 !###############################################################################
236
237
238 !###############################################################################
239 68 subroutine set_hyperparams_full( &
240 this, num_outputs, &
241 use_bias, &
242 activation, &
243 kernel_initialiser, bias_initialiser, &
244 verbose &
245 )
246 !! Set the hyperparameters for fully connected layer
247 use athena__activation, only: activation_setup
248 use athena__initialiser, only: get_default_initialiser, initialiser_setup
249 use athena__initialiser_data, only: data_init_type
250 implicit none
251
252 ! Arguments
253 class(full_layer_type), intent(inout) :: this
254 !! Instance of the fully connected layer
255 integer, intent(in) :: num_outputs
256 !! Number of outputs
257 logical, intent(in) :: use_bias
258 !! Whether to use bias
259 class(base_actv_type), allocatable, intent(in) :: activation
260 !! Activation function
261 class(base_init_type), allocatable, intent(in) :: &
262 kernel_initialiser, bias_initialiser
263 !! Kernel and bias initialisers
264 integer, optional, intent(in) :: verbose
265 !! Verbosity level
266
267 ! Local variables
268 character(len=256) :: buffer
269
270
271
5/8
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 68 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 68 times.
68 this%name = "full"
272 68 this%type = "full"
273 68 this%input_rank = 1
274 68 this%output_rank = 1
275 68 this%use_bias = use_bias
276 68 this%num_outputs = num_outputs
277
4/6
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
68 if(allocated(this%activation)) deallocate(this%activation)
278
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 68 times.
68 if(.not.allocated(activation))then
279 this%activation = activation_setup("none")
280 else
281
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 68 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 68 times.
68 allocate(this%activation, source=activation)
282 end if
283
4/6
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
68 if(allocated(this%kernel_init)) deallocate(this%kernel_init)
284
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 42 times.
68 if(.not.allocated(kernel_initialiser))then
285
1/2
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
26 buffer = get_default_initialiser(this%activation%name)
286
5/14
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 6 taken 26 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 26 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 26 times.
✓ Branch 17 taken 26 times.
✗ Branch 18 not taken.
26 this%kernel_init = initialiser_setup(buffer)
287 else
288 select type(kernel_init_in => kernel_initialiser)
289 class is(data_init_type)
290
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 allocate(data_init_type :: this%kernel_init)
291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 select type(kernel_init_out => this%kernel_init)
292 type is(data_init_type)
293 2 kernel_init_out%name = kernel_init_in%name
294
6/12
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
2 allocate(kernel_init_out%data(size(kernel_init_in%data)))
295
12/26
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 2 times.
✓ Branch 16 taken 234 times.
✓ Branch 17 taken 2 times.
✓ Branch 18 taken 2 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 2 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✓ Branch 28 taken 234 times.
✓ Branch 29 taken 2 times.
472 kernel_init_out%data = kernel_init_in%data
296 end select
297 class default
298
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40 times.
40 allocate(this%kernel_init, source=kernel_initialiser)
299 end select
300 end if
301
4/6
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
68 if(allocated(this%bias_init)) deallocate(this%bias_init)
302
2/2
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 15 times.
68 if(.not.allocated(bias_initialiser))then
303 buffer = get_default_initialiser( &
304 this%activation%name, &
305 is_bias=.true. &
306
1/2
✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
53 )
307
5/14
✗ Branch 0 not taken.
✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 6 taken 53 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 53 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 53 times.
✓ Branch 17 taken 53 times.
✗ Branch 18 not taken.
53 this%bias_init = initialiser_setup(buffer)
308 else
309
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
15 if(allocated(this%bias_init)) deallocate(this%bias_init)
310 select type(bias_init_in => bias_initialiser)
311 class is(data_init_type)
312
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 allocate(data_init_type :: this%bias_init)
313
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 select type(bias_init_out => this%bias_init)
314 type is(data_init_type)
315 2 bias_init_out%name = bias_init_in%name
316
6/12
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
2 allocate(bias_init_out%data(size(bias_init_in%data)))
317
12/26
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 2 times.
✓ Branch 16 taken 9 times.
✓ Branch 17 taken 2 times.
✓ Branch 18 taken 2 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 2 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✓ Branch 28 taken 9 times.
✓ Branch 29 taken 2 times.
22 bias_init_out%data = bias_init_in%data
318 end select
319 class default
320
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
13 allocate(this%bias_init, source=bias_initialiser)
321 end select
322 end if
323
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 if(present(verbose))then
324
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 57 times.
68 if(abs(verbose).gt.0)then
325 write(*,'("FULL activation function: ",A)') &
326
1/2
✓ Branch 3 taken 11 times.
✗ Branch 4 not taken.
11 trim(this%activation%name)
327 write(*,'("FULL kernel initialiser: ",A)') &
328
1/2
✓ Branch 3 taken 11 times.
✗ Branch 4 not taken.
11 trim(this%kernel_init%name)
329 write(*,'("FULL bias initialiser: ",A)') &
330
1/2
✓ Branch 3 taken 11 times.
✗ Branch 4 not taken.
11 trim(this%bias_init%name)
331 end if
332 end if
333
334 68 end subroutine set_hyperparams_full
335 !###############################################################################
336
337
338 !###############################################################################
339
1/2
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
63 subroutine init_full(this, input_shape, verbose)
340 !! Initialise fully connected layer
341 implicit none
342
343 ! Arguments
344 class(full_layer_type), intent(inout) :: this
345 !! Instance of the fully connected layer
346 integer, dimension(:), intent(in) :: input_shape
347 !! Input shape
348 integer, optional, intent(in) :: verbose
349 !! Verbosity level
350
351 ! Local variables
352 integer :: num_inputs
353 !! Temporary variable
354 integer :: verbose_ = 0
355
356
357 !---------------------------------------------------------------------------
358 ! Initialise optional arguments
359 !---------------------------------------------------------------------------
360
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 48 times.
63 if(present(verbose)) verbose_ = verbose
361
362
363 !---------------------------------------------------------------------------
364 ! Initialise number of inputs
365 !---------------------------------------------------------------------------
366
4/8
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 63 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 63 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 63 times.
63 if(.not.allocated(this%input_shape)) call this%set_shape(input_shape)
367
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 63 times.
63 this%num_inputs = this%input_shape(1)
368
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 63 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 63 times.
✓ Branch 7 taken 63 times.
126 this%output_shape = [this%num_outputs]
369 63 this%num_params = this%get_num_params()
370
371
372 !---------------------------------------------------------------------------
373 ! Allocate weight, weight steps (velocities), output, and activation
374 !---------------------------------------------------------------------------
375
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 63 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 63 times.
63 allocate(this%weight_shape(2,1))
376
9/16
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 63 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 63 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 63 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 63 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 63 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 63 times.
✓ Branch 21 taken 126 times.
✓ Branch 22 taken 63 times.
189 this%weight_shape(:,1) = [ this%num_outputs, this%num_inputs ]
377
378
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 15 times.
63 if(this%use_bias)then
379
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 48 times.
✓ Branch 7 taken 48 times.
96 this%bias_shape = [ this%num_outputs ]
380
16/30
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 48 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 48 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 48 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 48 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 48 times.
✓ Branch 21 taken 96 times.
✓ Branch 22 taken 48 times.
✓ Branch 23 taken 96 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 96 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 96 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 96 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 96 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 96 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 96 times.
144 allocate(this%params(2))
381 else
382
16/30
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 15 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 15 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 15 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 15 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 15 times.
✓ Branch 21 taken 15 times.
✓ Branch 22 taken 15 times.
✓ Branch 23 taken 15 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 15 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 15 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 15 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 15 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 15 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 15 times.
30 allocate(this%params(1))
383 end if
384
14/24
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 63 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 63 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 63 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 63 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 63 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 63 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 63 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 63 times.
✓ Branch 27 taken 126 times.
✓ Branch 28 taken 63 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 63 times.
✓ Branch 31 taken 189 times.
✓ Branch 32 taken 63 times.
378 call this%params(1)%allocate([this%weight_shape(:,1), 1])
385
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 63 times.
63 call this%params(1)%set_requires_grad(.true.)
386
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 63 times.
63 this%params(1)%fix_pointer = .true.
387
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 63 times.
63 this%params(1)%is_sample_dependent = .false.
388
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 63 times.
63 this%params(1)%is_temporary = .false.
389 63 num_inputs = this%num_inputs
390
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 15 times.
63 if(this%use_bias)then
391 48 num_inputs = this%num_inputs + 1
392
12/20
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 48 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 48 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 48 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 48 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 48 times.
✓ Branch 21 taken 48 times.
✓ Branch 22 taken 48 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 48 times.
✓ Branch 25 taken 96 times.
✓ Branch 26 taken 48 times.
192 call this%params(2)%allocate([this%bias_shape, 1])
393
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
48 call this%params(2)%set_requires_grad(.true.)
394
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
48 this%params(2)%fix_pointer = .true.
395
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
48 this%params(2)%is_sample_dependent = .false.
396
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
48 this%params(2)%is_temporary = .false.
397 end if
398
399
400 !---------------------------------------------------------------------------
401 ! Initialise weights (kernels)
402 !---------------------------------------------------------------------------
403 call this%kernel_init%initialise( &
404 630 this%params(1)%val(:,1), &
405 fan_in = num_inputs, fan_out = this%num_outputs, &
406 spacing = [ this%num_outputs ] &
407
12/22
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 63 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 63 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 63 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 63 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 63 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 63 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 63 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 63 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 63 times.
✓ Branch 30 taken 63 times.
✓ Branch 31 taken 63 times.
126 )
408
409 ! Initialise biases
410 !---------------------------------------------------------------------------
411
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 15 times.
63 if(this%use_bias)then
412 call this%bias_init%initialise( &
413 480 this%params(2)%val(:,1), &
414 fan_in = num_inputs, fan_out = this%num_outputs &
415
10/20
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 48 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 48 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 48 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 48 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 48 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 48 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 48 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 48 times.
48 )
416 end if
417
418
419 !---------------------------------------------------------------------------
420 ! Allocate arrays
421 !---------------------------------------------------------------------------
422
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
63 if(allocated(this%output)) deallocate(this%output)
423
15/26
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 63 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 63 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 63 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 63 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 63 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 63 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 63 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 63 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 63 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 63 times.
✓ Branch 33 taken 63 times.
✓ Branch 34 taken 63 times.
✓ Branch 35 taken 63 times.
✓ Branch 36 taken 63 times.
189 allocate(this%output(1,1))
424
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
63 if(this%z(1)%allocated) call this%z(1)%deallocate()
425
426 63 end subroutine init_full
427 !###############################################################################
428
429
430 !##############################################################################!
431 ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !
432 !##############################################################################!
433
434
435 !###############################################################################
436 3 subroutine print_to_unit_full(this, unit)
437 !! Print fully connected layer to unit
438 use coreutils, only: to_upper
439 implicit none
440
441 ! Arguments
442 class(full_layer_type), intent(in) :: this
443 !! Instance of the fully connected layer
444 integer, intent(in) :: unit
445 !! File unit
446
447
448 ! Write initial parameters
449 !---------------------------------------------------------------------------
450 3 write(unit,'(3X,"NUM_INPUTS = ",I0)') this%num_inputs
451 3 write(unit,'(3X,"NUM_OUTPUTS = ",I0)') this%num_outputs
452
453 3 write(unit,'(3X,"USE_BIAS = ",L1)') this%use_bias
454
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(this%activation%name .ne. 'none')then
455 3 call this%activation%print_to_unit(unit)
456 end if
457
458
459 ! Write fully connected weights and biases
460 !---------------------------------------------------------------------------
461 3 write(unit,'("WEIGHTS")')
462
10/18
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 3 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 3 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 3 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 3 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 3 times.
✓ Branch 25 taken 66 times.
✓ Branch 26 taken 3 times.
69 write(unit,'(5(E16.8E2))') this%params(1)%val(:,1)
463
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(this%use_bias)then
464
10/18
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 3 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 3 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 3 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 3 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 3 times.
✓ Branch 25 taken 22 times.
✓ Branch 26 taken 3 times.
25 write(unit,'(5(E16.8E2))') this%params(2)%val(:,1)
465 end if
466 3 write(unit,'("END WEIGHTS")')
467
468 3 end subroutine print_to_unit_full
469 !###############################################################################
470
471
472 !###############################################################################
473 3 subroutine read_full(this, unit, verbose)
474 !! Read fully connected layer from file
475 use athena__tools_infile, only: assign_val, assign_vec, move
476 use coreutils, only: to_lower, to_upper, icount
477 use athena__activation, only: read_activation
478 use athena__initialiser, only: initialiser_setup
479 implicit none
480
481 ! Arguments
482 class(full_layer_type), intent(inout) :: this
483 !! Instance of the fully connected layer
484 integer, intent(in) :: unit
485 !! Unit number
486 integer, optional, intent(in) :: verbose
487 !! Verbosity level
488
489 ! Local variables
490 integer :: stat
491 !! Status of read
492 integer :: verbose_ = 0
493 !! Verbosity level
494 integer :: i, j, k, c, itmp1, iline, num_params
495 !! Loop variables and temporary integer
496 integer :: num_inputs, num_outputs
497 !! Number of inputs and outputs
498 logical :: use_bias = .true.
499 !! Whether to use bias
500 character(14) :: kernel_initialiser_name='', bias_initialiser_name=''
501 !! Initialisers
502 character(20) :: activation_name=''
503 !! Activation function
504 9 class(base_actv_type), allocatable :: activation
505 !! Activation function
506 15 class(base_init_type), allocatable :: kernel_initialiser, bias_initialiser
507 !! Initialisers
508 character(256) :: buffer, tag, err_msg
509 !! Buffer, tag, and error message
510 integer, dimension(2) :: input_shape
511 !! Input shape
512 3 real(real32), allocatable, dimension(:) :: data_list
513 !! Data list
514 integer :: param_line, final_line
515 !! Parameter line number
516
517
518 ! Initialise optional arguments
519 !---------------------------------------------------------------------------
520
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(present(verbose)) verbose_ = verbose
521
522
523 ! Loop over tags in layer card
524 !---------------------------------------------------------------------------
525 3 iline = 0
526 3 param_line = 0
527 3 final_line = 0
528 37 tag_loop: do
529
530 ! Check for end of file
531 !------------------------------------------------------------------------
532 40 read(unit,'(A)',iostat=stat) buffer
533
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 if(stat.ne.0)then
534 write(err_msg,'("file encountered error (EoF?) before END ",A)') &
535 to_upper(this%name)
536 call stop_program(err_msg)
537 return
538 end if
539
2/4
✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 40 times.
40 if(trim(adjustl(buffer)).eq."") cycle tag_loop
540
541 ! Check for end of layer card
542 !------------------------------------------------------------------------
543
4/6
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 40 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✓ Branch 9 taken 37 times.
80 if(trim(adjustl(buffer)).eq."END "//to_upper(trim(this%name)))then
544 3 final_line = iline
545 3 backspace(unit)
546 40 exit tag_loop
547 end if
548 37 iline = iline + 1
549
550
2/4
✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
37 tag=trim(adjustl(buffer))
551
6/10
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 9 times.
✓ Branch 8 taken 9 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 9 times.
✗ Branch 11 not taken.
37 if(scan(buffer,"=").ne.0) tag=trim(tag(:scan(tag,"=")-1))
552
553 ! Read parameters from file
554 !------------------------------------------------------------------------
555 74 select case(trim(tag))
556 case("NUM_INPUTS")
557 6 call assign_val(buffer, num_inputs, itmp1)
558 case("NUM_OUTPUTS")
559 6 call assign_val(buffer, num_outputs, itmp1)
560 case("USE_BIAS")
561 6 call assign_val(buffer, use_bias, itmp1)
562 case("ACTIVATION")
563 3 iline = iline - 1
564 3 backspace(unit)
565
5/14
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 3 times.
✓ Branch 17 taken 3 times.
✗ Branch 18 not taken.
3 activation = read_activation(unit, iline)
566 case("KERNEL_INITIALISER", "KERNEL_INIT", "KERNEL_INITIALIZER")
567 call assign_val(buffer, kernel_initialiser_name, itmp1)
568 case("BIAS_INITIALISER", "BIAS_INIT", "BIAS_INITIALIZER")
569 call assign_val(buffer, bias_initialiser_name, itmp1)
570 case("WEIGHTS")
571 3 kernel_initialiser_name = 'zeros'
572 3 bias_initialiser_name = 'zeros'
573 3 param_line = iline
574 case default
575 ! Don't look for "e" due to scientific notation of numbers
576 ! ... i.e. exponent (E+00)
577
3/4
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19 times.
✓ Branch 5 taken 3 times.
44 if(scan(to_lower(trim(adjustl(buffer))),&
578 'abcdfghijklmnopqrstuvwxyz').eq.0)then
579 22 cycle tag_loop
580
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 elseif(tag(:3).eq.'END')then
581 22 cycle tag_loop
582 end if
583 write(err_msg,'("Unrecognised line in input file: ",A)') &
584 trim(adjustl(buffer))
585 call stop_program(err_msg)
586
7/10
✓ Branch 0 taken 37 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✓ Branch 9 taken 22 times.
74 return
587 end select
588 end do tag_loop
589
5/14
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 3 times.
✓ Branch 17 taken 3 times.
✗ Branch 18 not taken.
3 kernel_initialiser = initialiser_setup(kernel_initialiser_name)
590
5/14
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 3 times.
✓ Branch 17 taken 3 times.
✗ Branch 18 not taken.
3 bias_initialiser = initialiser_setup(bias_initialiser_name)
591
592
593 ! Set hyperparameters and initialise layer
594 !---------------------------------------------------------------------------
595 call this%set_hyperparams( &
596 num_outputs = num_outputs, &
597 use_bias = use_bias, &
598 activation = activation, &
599 kernel_initialiser = kernel_initialiser, &
600 bias_initialiser = bias_initialiser, &
601 verbose = verbose_ &
602 3 )
603
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 call this%init(input_shape=[num_inputs])
604
605
606 ! Check if WEIGHTS card was found
607 !---------------------------------------------------------------------------
608
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(param_line.eq.0)then
609 write(0,*) "WARNING: WEIGHTS card in "//to_upper(trim(this%name))//" not found"
610 else
611 3 call move(unit, param_line - iline, iostat=stat)
612 3 num_params = this%num_inputs * this%num_outputs
613
7/14
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 3 times.
3 allocate(data_list(num_params), source=0._real32)
614 3 c = 1
615 3 k = 1
616
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 14 times.
17 data_concat_loop: do while(c.le.num_params)
617 14 read(unit,'(A)',iostat=stat) buffer
618
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if(stat.ne.0) exit data_concat_loop
619 14 k = icount(buffer)
620
5/8
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✓ Branch 3 taken 66 times.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 66 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 66 times.
80 read(buffer,*,iostat=stat) (data_list(j),j=c,c+k-1)
621 14 c = c + k
622 end do data_concat_loop
623
15/28
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 3 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 3 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 3 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 3 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 3 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 3 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 3 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 3 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 3 times.
✓ Branch 39 taken 66 times.
✓ Branch 40 taken 3 times.
69 this%params(1)%val(:,1) = data_list
624
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 deallocate(data_list)
625
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(use_bias)then
626
7/14
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 3 times.
3 allocate(data_list(num_outputs), source=0._real32)
627 3 c = 1
628 3 k = 1
629
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5 times.
8 data_concat_loop2: do while(c.le.num_outputs)
630 5 read(unit,'(A)',iostat=stat) buffer
631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if(stat.ne.0) exit data_concat_loop2
632 5 k = icount(buffer)
633
5/8
✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
✓ Branch 3 taken 22 times.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 22 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 22 times.
27 read(buffer,*,iostat=stat) (data_list(j),j=c,c+k-1)
634 5 c = c + k
635 end do data_concat_loop2
636
15/28
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 3 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 3 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 3 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 3 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 3 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 3 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 3 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 3 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 3 times.
✓ Branch 39 taken 22 times.
✓ Branch 40 taken 3 times.
25 this%params(2)%val(:,1) = data_list(1:num_outputs)
637
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 deallocate(data_list)
638 end if
639
640 ! Check for end of weights card
641 !------------------------------------------------------------------------
642 3 read(unit,'(A)') buffer
643
2/4
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
3 if(trim(adjustl(buffer)).ne."END WEIGHTS")then
644 write(0,*) trim(adjustl(buffer))
645 call stop_program("END WEIGHTS not where expected")
646 return
647 end if
648 end if
649
650
651 !---------------------------------------------------------------------------
652 ! Check for end of layer card
653 !---------------------------------------------------------------------------
654 3 call move(unit, final_line - iline, iostat=stat)
655 3 read(unit,'(A)') buffer
656
3/6
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
6 if(trim(adjustl(buffer)).ne."END "//to_upper(trim(this%name)))then
657 write(0,*) trim(adjustl(buffer))
658 write(err_msg,'("END ",A," not where expected")') to_upper(this%name)
659 call stop_program(err_msg)
660 3 return
661 end if
662
663
7/14
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✓ Branch 12 taken 3 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 3 times.
3 end subroutine read_full
664 !###############################################################################
665
666
667 !###############################################################################
668 3 function read_full_layer(unit, verbose) result(layer)
669 !! Read fully connected layer from file and return layer
670 implicit none
671
672 ! Arguments
673 integer, intent(in) :: unit
674 !! Unit number
675 integer, optional, intent(in) :: verbose
676 !! Verbosity level
677 class(base_layer_type), allocatable :: layer
678 !! Instance of the fully connected layer
679
680 ! Local variables
681 integer :: verbose_ = 0
682 !! Verbosity level
683
684
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(present(verbose)) verbose_ = verbose
685
21/78
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✓ Branch 48 taken 3 times.
✗ Branch 50 not taken.
✓ Branch 51 taken 3 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 3 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 3 times.
✗ Branch 56 not taken.
✓ Branch 57 taken 3 times.
✗ Branch 58 not taken.
✓ Branch 59 taken 3 times.
✗ Branch 60 not taken.
✓ Branch 61 taken 3 times.
✗ Branch 63 not taken.
✓ Branch 64 taken 3 times.
✓ Branch 65 taken 3 times.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✓ Branch 68 taken 3 times.
✓ Branch 70 taken 3 times.
✗ Branch 71 not taken.
✓ Branch 72 taken 3 times.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✓ Branch 75 taken 3 times.
✓ Branch 77 taken 3 times.
✗ Branch 78 not taken.
✓ Branch 79 taken 3 times.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✓ Branch 82 taken 3 times.
✓ Branch 84 taken 3 times.
✗ Branch 85 not taken.
6 allocate(layer, source=full_layer_type(num_outputs=0))
686 3 call layer%read(unit, verbose=verbose_)
687
688 6 end function read_full_layer
689 !###############################################################################
690
691
692 !###############################################################################
693
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 subroutine build_from_onnx_full(this, node, initialisers, value_info, verbose )
694 !! Read ONNX attributes for fully connected layer
695 use athena__activation, only: activation_setup
696 use athena__initialiser_data, only: data_init_type
697 implicit none
698
699 ! Arguments
700 class(full_layer_type), intent(inout) :: this
701 !! Instance of the fully connected layer
702 type(onnx_node_type), intent(in) :: node
703 !! Instance of ONNX node information
704 type(onnx_initialiser_type), dimension(:), intent(in) :: initialisers
705 !! Instance of ONNX initialiser information
706 type(onnx_tensor_type), dimension(:), intent(in) :: value_info
707 !! Instance of ONNX value info information
708 integer, intent(in) :: verbose
709 !! Verbosity level
710
711 ! Local variables
712 integer :: i
713 !! Loop index
714 logical :: use_bias = .true.
715 !! Whether to use bias
716 2 integer, dimension(:), allocatable :: dim_products, init_indices
717 !! Initialiser flattened sizes and their source indices
718 integer :: num_init_products
719 !! Number of initialisers with dimension metadata
720 integer :: weight_idx, bias_idx
721 !! Indices for weight and bias initialisers
722 integer :: num_outputs
723 !! Number of outputs
724 6 class(base_actv_type), allocatable :: activation
725 !! Activation function
726 10 class(base_init_type), allocatable :: kernel_initialiser, bias_initialiser
727
728
729 2 weight_idx = -1
730 2 bias_idx = -1
731
10/20
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 2 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 2 times.
2 allocate(dim_products(size(initialisers)))
732
10/20
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 2 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 2 times.
2 allocate(init_indices(size(initialisers)))
733 2 num_init_products = 0
734
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
2 if(size(initialisers).lt.1)then
735 call stop_program("ONNX FULL layer requires at least 1 initialiser")
736 return
737 else
738 ! check which initialiser has weights and which has biases,
739 ! look for dimensions
740
5/8
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 2 times.
6 do i = 1, size(initialisers)
741
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
6 if(allocated(initialisers(i)%dims))then
742 4 num_init_products = num_init_products + 1
743
10/18
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 4 times.
✓ Branch 18 taken 6 times.
✓ Branch 19 taken 4 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 4 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 4 times.
10 dim_products(num_init_products) = product(initialisers(i)%dims)
744
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
4 init_indices(num_init_products) = i
745 end if
746 end do
747 end if
748 ! if both weight and bias have dimension 1, check which is larger and that
749 ! the division of it by the kernel size is equal to the length of the other
750 select case(num_init_products)
751 case(1)
752 weight_idx = init_indices(1)
753 use_bias = .false.
754 case(2)
755 ! check which is weight and which is bias
756
5/10
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
4 if(mod(dim_products(1), dim_products(2)).eq.0)then
757
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
2 weight_idx = init_indices(1)
758
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
2 bias_idx = init_indices(2)
759 elseif(mod(dim_products(2), dim_products(1)).eq.0)then
760 weight_idx = init_indices(2)
761 bias_idx = init_indices(1)
762 else
763 call stop_program("ONNX FULL layer initialiser dimensions not compatible")
764 return
765 end if
766 case default
767 call stop_program("ONNX FULL layer number of initialisers not supported")
768
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 return
769 end select
770
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
2 num_outputs = value_info(1)%dims(2)
771
772
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
2 allocate(data_init_type :: kernel_initialiser)
773 select type(kernel_init_data => kernel_initialiser)
774 type is(data_init_type)
775 2 kernel_init_data%name = 'data'
776
8/16
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 2 times.
2 allocate(kernel_init_data%data(size(initialisers(weight_idx)%data)))
777
14/30
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 2 times.
✓ Branch 22 taken 234 times.
✓ Branch 23 taken 2 times.
✓ Branch 24 taken 2 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 2 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✓ Branch 34 taken 234 times.
✓ Branch 35 taken 2 times.
472 kernel_init_data%data = initialisers(weight_idx)%data
778 end select
779
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if(use_bias)then
780
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
2 allocate(data_init_type :: bias_initialiser)
781 select type(bias_init_data => bias_initialiser)
782 type is(data_init_type)
783 2 bias_init_data%name = 'data'
784
8/16
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 2 times.
2 allocate(bias_init_data%data(size(initialisers(bias_idx)%data)))
785
14/30
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 2 times.
✓ Branch 22 taken 9 times.
✓ Branch 23 taken 2 times.
✓ Branch 24 taken 2 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 2 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✓ Branch 34 taken 9 times.
✓ Branch 35 taken 2 times.
22 bias_init_data%data = initialisers(bias_idx)%data
786 end select
787 end if
788
789
5/14
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 2 times.
✓ Branch 17 taken 2 times.
✗ Branch 18 not taken.
2 activation = activation_setup("none")
790 call this%set_hyperparams( &
791 num_outputs = num_outputs, &
792 use_bias = use_bias, &
793 activation = activation, &
794 verbose = verbose, &
795 kernel_initialiser = kernel_initialiser, &
796 bias_initialiser = bias_initialiser &
797 2 )
798
799
8/16
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 2 times.
6 end subroutine build_from_onnx_full
800 !###############################################################################
801
802
803 !###############################################################################
804
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 function create_from_onnx_full_layer(node, initialisers, value_info, verbose) &
805 2 result(layer)
806 !! Build fully connected layer from attributes and return layer
807 implicit none
808
809 ! Arguments
810 type(onnx_node_type), intent(in) :: node
811 !! Instance of ONNX node information
812 type(onnx_initialiser_type), dimension(:), intent(in) :: initialisers
813 !! Instance of ONNX initialiser information
814 type(onnx_tensor_type), dimension(:), intent(in) :: value_info
815 !! Instance of ONNX value info information
816 integer, optional, intent(in) :: verbose
817 !! Verbosity level
818 class(base_layer_type), allocatable :: layer
819 !! Instance of the 2D convolutional layer
820
821 ! Local variables
822 integer :: verbose_ = 0
823 !! Verbosity level
824
825
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(present(verbose)) verbose_ = verbose
826
21/78
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✓ Branch 48 taken 2 times.
✗ Branch 50 not taken.
✓ Branch 51 taken 2 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 2 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 2 times.
✗ Branch 56 not taken.
✓ Branch 57 taken 2 times.
✗ Branch 58 not taken.
✓ Branch 59 taken 2 times.
✗ Branch 60 not taken.
✓ Branch 61 taken 2 times.
✗ Branch 63 not taken.
✓ Branch 64 taken 2 times.
✓ Branch 65 taken 2 times.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✓ Branch 68 taken 2 times.
✓ Branch 70 taken 2 times.
✗ Branch 71 not taken.
✓ Branch 72 taken 2 times.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✓ Branch 75 taken 2 times.
✓ Branch 77 taken 2 times.
✗ Branch 78 not taken.
✓ Branch 79 taken 2 times.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✓ Branch 82 taken 2 times.
✓ Branch 84 taken 2 times.
✗ Branch 85 not taken.
4 allocate(layer, source=full_layer_type(num_outputs=0))
827
6/12
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 2 times.
2 call layer%build_from_onnx(node, initialisers, value_info, verbose=verbose_)
828
829 4 end function create_from_onnx_full_layer
830 !###############################################################################
831
832
833 !##############################################################################!
834 ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !
835 !##############################################################################!
836
837
838 !###############################################################################
839
1/2
✓ Branch 0 taken 3426 times.
✗ Branch 1 not taken.
3426 subroutine forward_full(this, input)
840 !! Forward propagation
841 implicit none
842
843 ! Arguments
844 class(full_layer_type), intent(inout) :: this
845 !! Instance of the fully connected layer
846 class(array_type), dimension(:,:), intent(in) :: input
847 !! Input values
848
849 type(array_type), pointer :: ptr => null()
850
851
852 ! Generate outputs from weights, biases, and inputs
853 !---------------------------------------------------------------------------
854
1/2
✓ Branch 0 taken 3426 times.
✗ Branch 1 not taken.
3426 if(this%use_bias)then
855
6/12
✗ Branch 0 not taken.
✓ Branch 1 taken 3426 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3426 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3426 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3426 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 3426 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 3426 times.
3426 ptr => matmul(this%params(1), input(1,1) ) + this%params(2)
856 else
857 ptr => matmul(this%params(1), input(1,1) )
858 end if
859
860 ! Apply activation function to activation
861 !---------------------------------------------------------------------------
862
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 3426 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3426 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3426 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3426 times.
3426 call this%output(1,1)%zero_grad()
863
3/4
✓ Branch 1 taken 3426 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 3419 times.
3426 if(trim(this%activation%name) .eq. "none")then
864
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 7 times.
7 call this%output(1,1)%assign_and_deallocate_source(ptr)
865 else
866 3419 call this%z(1)%zero_grad()
867 3419 call this%z(1)%assign_and_deallocate_source(ptr)
868 3419 this%z(1)%is_temporary = .false.
869 3419 ptr => this%activation%apply(this%z(1))
870
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 3419 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3419 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3419 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3419 times.
3419 call this%output(1,1)%assign_and_deallocate_source(ptr)
871 end if
872
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 3426 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3426 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3426 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3426 times.
3426 this%output(1,1)%is_temporary = .false.
873
874 3426 end subroutine forward_full
875 !###############################################################################
876
877
50/91
✓ Branch 0 taken 121 times.
✓ Branch 1 taken 101 times.
✓ Branch 2 taken 161 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 99 times.
✓ Branch 5 taken 121 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 13 times.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✓ Branch 36 taken 77 times.
✓ Branch 37 taken 44 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 77 times.
✓ Branch 40 taken 99 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 77 times.
✓ Branch 43 taken 99 times.
✓ Branch 44 taken 77 times.
✓ Branch 45 taken 176 times.
✗ Branch 46 not taken.
✓ Branch 47 taken 77 times.
✓ Branch 48 taken 143 times.
✓ Branch 49 taken 176 times.
✓ Branch 50 taken 44 times.
✓ Branch 51 taken 176 times.
✓ Branch 52 taken 44 times.
✓ Branch 53 taken 47 times.
✓ Branch 54 taken 74 times.
✓ Branch 55 taken 77 times.
✓ Branch 56 taken 44 times.
✓ Branch 57 taken 124 times.
✓ Branch 58 taken 77 times.
✓ Branch 59 taken 124 times.
✗ Branch 60 not taken.
✓ Branch 61 taken 124 times.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✓ Branch 64 taken 124 times.
✗ Branch 65 not taken.
✓ Branch 66 taken 124 times.
✗ Branch 67 not taken.
✓ Branch 68 taken 124 times.
✗ Branch 69 not taken.
✓ Branch 70 taken 124 times.
✓ Branch 71 taken 121 times.
✗ Branch 72 not taken.
✓ Branch 74 taken 121 times.
✗ Branch 75 not taken.
✓ Branch 77 taken 121 times.
✗ Branch 78 not taken.
✓ Branch 80 taken 121 times.
✓ Branch 81 taken 121 times.
✓ Branch 82 taken 2 times.
✓ Branch 83 taken 119 times.
✓ Branch 84 taken 2 times.
✓ Branch 85 taken 119 times.
✗ Branch 86 not taken.
✓ Branch 87 taken 121 times.
✗ Branch 88 not taken.
✓ Branch 89 taken 121 times.
✗ Branch 90 not taken.
✓ Branch 91 taken 121 times.
✗ Branch 92 not taken.
✓ Branch 93 taken 121 times.
1708 end module athena__full_layer
878