GCC Code Coverage Report


Directory: src/lib/
File: src/lib/mod_batchnorm1d_layer.f90
Date: 2024-06-28 12:51:18
Exec Total Coverage
Lines: 143 239 59.8%
Functions: 0 0 -%
Branches: 741 1700 43.6%

Line Branch Exec Source
1 !!!#############################################################################
2 !!! Code written by Ned Thaddeus Taylor
3 !!! Code part of the ATHENA library - a feedforward neural network library
4 !!!#############################################################################
5 !!! module contains implementation of 0D and 1D batch normalisation layers
6 !!!#############################################################################
7 module batchnorm1d_layer
8 use constants, only: real12
9 use base_layer, only: batch_layer_type, learnable_layer_type
10 use custom_types, only: initialiser_type
11 implicit none
12
13
14 type, extends(batch_layer_type) :: batchnorm1d_layer_type
15 integer :: num_inputs = 1
16 real(real12), allocatable, dimension(:,:,:) :: output
17 real(real12), allocatable, dimension(:,:,:) :: di ! gradient of input (i.e. delta)
18 contains
19 procedure, pass(this) :: get_output => get_output_batchnorm1d
20 procedure, pass(this) :: init => init_batchnorm1d
21 procedure, pass(this) :: set_batch_size => set_batch_size_batchnorm1d
22 procedure, pass(this) :: print => print_batchnorm1d
23
24 procedure, pass(this) :: forward => forward_rank
25 procedure, pass(this) :: backward => backward_rank
26 procedure, private, pass(this) :: forward_3d
27 procedure, private, pass(this) :: backward_3d
28
29 procedure, pass(this) :: reduce => layer_reduction
30 procedure, pass(this) :: merge => layer_merge
31 procedure :: add_t_t => layer_add !t = type, r = real, i = int
32 generic :: operator(+) => add_t_t !, public
33 end type batchnorm1d_layer_type
34
35
36 interface batchnorm1d_layer_type
37 module function layer_setup( &
38 input_shape, batch_size, &
39 num_channels, num_inputs, &
40 momentum, epsilon, &
41 gamma_init_mean, gamma_init_std, &
42 beta_init_mean, beta_init_std, &
43 kernel_initialiser, bias_initialiser, &
44 moving_mean_initialiser, moving_variance_initialiser &
45 ) result(layer)
46 integer, dimension(:), optional, intent(in) :: input_shape
47 integer, optional, intent(in) :: batch_size
48 integer, optional, intent(in) :: num_channels, num_inputs
49 real(real12), optional, intent(in) :: momentum, epsilon
50 real(real12), optional, intent(in) :: gamma_init_mean, gamma_init_std
51 real(real12), optional, intent(in) :: beta_init_mean, beta_init_std
52 character(*), optional, intent(in) :: &
53 kernel_initialiser, bias_initialiser, &
54 moving_mean_initialiser, moving_variance_initialiser
55 type(batchnorm1d_layer_type) :: layer
56 end function layer_setup
57 end interface batchnorm1d_layer_type
58
59
60 private
61 public :: batchnorm1d_layer_type
62 public :: read_batchnorm1d_layer
63
64
65 contains
66
67 !!!#############################################################################
68 !!! layer reduction
69 !!!#############################################################################
70 1 subroutine layer_reduction(this, rhs)
71 implicit none
72 class(batchnorm1d_layer_type), intent(inout) :: this
73 class(learnable_layer_type), intent(in) :: rhs
74
75 select type(rhs)
76 class is(batchnorm1d_layer_type)
77
12/24
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 1 times.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✓ Branch 31 taken 2 times.
✓ Branch 32 taken 1 times.
3 this%dg = this%dg + rhs%dg
78
14/28
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 1 times.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✓ Branch 35 taken 2 times.
✓ Branch 36 taken 1 times.
4 this%db = this%db + rhs%db
79 end select
80
81 1 end subroutine layer_reduction
82 !!!#############################################################################
83
84
85 !!!#############################################################################
86 !!! layer addition
87 !!!#############################################################################
88 1 function layer_add(a, b) result(output)
89 implicit none
90 class(batchnorm1d_layer_type), intent(in) :: a, b
91 type(batchnorm1d_layer_type) :: output
92
93
25/50
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 1 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 1 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 1 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 1 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 1 times.
✗ Branch 43 not taken.
✓ Branch 44 taken 1 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 1 times.
✗ Branch 49 not taken.
✓ Branch 50 taken 1 times.
1 output = a
94
13/26
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 1 times.
✓ Branch 27 taken 1 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✓ Branch 33 taken 2 times.
✓ Branch 34 taken 1 times.
3 output%dg = output%dg + b%dg
95
13/26
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 1 times.
✓ Branch 27 taken 1 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✓ Branch 33 taken 2 times.
✓ Branch 34 taken 1 times.
3 output%db = output%db + b%db
96
97
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 end function layer_add
98 !!!#############################################################################
99
100
101 !!!#############################################################################
102 !!! layer merge
103 !!!#############################################################################
104 1 subroutine layer_merge(this, input)
105 implicit none
106 class(batchnorm1d_layer_type), intent(inout) :: this
107 class(learnable_layer_type), intent(in) :: input
108
109 select type(input)
110 class is(batchnorm1d_layer_type)
111
12/24
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 1 times.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✓ Branch 31 taken 2 times.
✓ Branch 32 taken 1 times.
3 this%dg = this%dg + input%dg
112
14/28
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 1 times.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✓ Branch 35 taken 2 times.
✓ Branch 36 taken 1 times.
4 this%db = this%db + input%db
113 end select
114
115 1 end subroutine layer_merge
116 !!!#############################################################################
117
118
119 !!!##########################################################################!!!
120 !!! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !!!
121 !!!##########################################################################!!!
122
123
124 !!!#############################################################################
125 !!! get layer outputs
126 !!!#############################################################################
127 4 pure subroutine get_output_batchnorm1d(this, output)
128 implicit none
129 class(batchnorm1d_layer_type), intent(in) :: this
130 real(real12), allocatable, dimension(..), intent(out) :: output
131
132 select rank(output)
133 rank(1)
134
7/10
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
5 output = reshape(this%output, [size(this%output)])
135 rank(2)
136 output = reshape(this%output, &
137
11/18
✗ 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 taken 3 times.
✓ Branch 13 taken 3 times.
✓ Branch 14 taken 6 times.
✓ Branch 15 taken 3 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 3 times.
✓ Branch 19 taken 3 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 3 times.
✗ Branch 22 not taken.
12 [product(this%output_shape(:)), this%batch_size])
138 rank(3)
139 output = this%output
140 end select
141
142 4 end subroutine get_output_batchnorm1d
143 !!!#############################################################################
144
145
146 !!!##########################################################################!!!
147 !!! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !!!
148 !!!##########################################################################!!!
149
150
151 !!!#############################################################################
152 !!! forward propagation assumed rank handler
153 !!!#############################################################################
154 2 pure subroutine forward_rank(this, input)
155 implicit none
156 class(batchnorm1d_layer_type), intent(inout) :: this
157 real(real12), dimension(..), intent(in) :: input
158
159 select rank(input)
160 rank(2)
161 2 call forward_3d(this, input)
162 rank(3)
163 call forward_3d(this, input)
164 end select
165 2 end subroutine forward_rank
166 !!!#############################################################################
167
168
169 !!!#############################################################################
170 !!! backward propagation assumed rank handler
171 !!!#############################################################################
172 1 pure subroutine backward_rank(this, input, gradient)
173 implicit none
174 class(batchnorm1d_layer_type), intent(inout) :: this
175 real(real12), dimension(..), intent(in) :: input
176 real(real12), dimension(..), intent(in) :: gradient
177
178 select rank(input); rank(2)
179 1 select rank(gradient); rank(2)
180 1 call backward_3d(this, input, gradient)
181 end select
182 end select
183 select rank(input); rank(3)
184 select rank(gradient); rank(3)
185 call backward_3d(this, input, gradient)
186 end select
187 end select
188 1 end subroutine backward_rank
189 !!!#############################################################################
190
191
192 !!!##########################################################################!!!
193 !!! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !!!
194 !!!##########################################################################!!!
195
196
197 !!!#############################################################################
198 !!! set up layer
199 !!!#############################################################################
200 6 module function layer_setup( &
201
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
6 input_shape, batch_size, &
202 num_channels, num_inputs, &
203 momentum, epsilon, &
204 gamma_init_mean, gamma_init_std, &
205 beta_init_mean, beta_init_std, &
206 kernel_initialiser, bias_initialiser, &
207 moving_mean_initialiser, moving_variance_initialiser &
208 ) result(layer)
209 use initialiser, only: get_default_initialiser
210 implicit none
211 integer, dimension(:), optional, intent(in) :: input_shape
212 integer, optional, intent(in) :: batch_size
213 integer, optional, intent(in) :: num_channels, num_inputs
214 real(real12), optional, intent(in) :: momentum, epsilon
215 real(real12), optional, intent(in) :: gamma_init_mean, gamma_init_std
216 real(real12), optional, intent(in) :: beta_init_mean, beta_init_std
217 character(*), optional, intent(in) :: &
218 kernel_initialiser, bias_initialiser, &
219 moving_mean_initialiser, moving_variance_initialiser
220
221 type(batchnorm1d_layer_type) :: layer
222
223
224
3/8
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
6 layer%name = "batchnorm1d"
225 6 layer%input_rank = 1
226 !!--------------------------------------------------------------------------
227 !! initialise batch size
228 !!--------------------------------------------------------------------------
229
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(present(batch_size)) layer%batch_size = batch_size
230
231
232 !!--------------------------------------------------------------------------
233 !! set up number of channels (alt. number of features)
234 !!--------------------------------------------------------------------------
235 ! layer%num_channels = -1
236 ! if(present(num_channels).and.present(num_inputs))then
237 ! write(0,*) "ERROR: both num_channels and num_inputs present"
238 ! write(0,*) "These represent the same parameter, so are conflicting"
239 ! stop 1
240 ! end if
241
242
243 !!--------------------------------------------------------------------------
244 !! set up momentum and epsilon
245 !!--------------------------------------------------------------------------
246
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if(present(momentum))then
247 1 layer%momentum = momentum
248 else
249 5 layer%momentum = 0._real12
250 end if
251
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if(present(epsilon))then
252 1 layer%epsilon = epsilon
253 else
254 5 layer%epsilon = 1.E-5_real12
255 end if
256
257
258 !!--------------------------------------------------------------------------
259 !! set up initialiser mean and standard deviations
260 !!--------------------------------------------------------------------------
261
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if(present(gamma_init_mean)) layer%gamma_init_mean = gamma_init_mean
262
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if(present(gamma_init_std)) layer%gamma_init_std = gamma_init_std
263
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if(present(beta_init_mean)) layer%beta_init_mean = beta_init_mean
264
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if(present(beta_init_std)) layer%beta_init_std = beta_init_std
265
266
267 !!--------------------------------------------------------------------------
268 !! define gamma and beta initialisers
269 !!--------------------------------------------------------------------------
270
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
6 if(present(kernel_initialiser)) layer%kernel_initialiser = kernel_initialiser
271
4/4
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 1 times.
6 if(trim(layer%kernel_initialiser).eq.'') &
272 5 layer%kernel_initialiser = 'ones'
273 !get_default_initialiser("batch")
274 write(*,'("BATCHNORM1D kernel (gamma) initialiser: ",A)') &
275
1/2
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
6 trim(layer%kernel_initialiser)
276
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
6 if(present(bias_initialiser)) layer%bias_initialiser = bias_initialiser
277
4/4
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 1 times.
6 if(trim(layer%bias_initialiser).eq.'') &
278 5 layer%bias_initialiser = 'zeros'
279 !get_default_initialiser("batch")
280 write(*,'("BATCHNORM1D bias (beta) initialiser: ",A)') &
281
1/2
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
6 trim(layer%bias_initialiser)
282
283
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if(present(moving_mean_initialiser)) &
284
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 layer%moving_mean_initialiser = moving_mean_initialiser
285
4/4
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 1 times.
6 if(trim(layer%moving_mean_initialiser).eq.'') &
286 5 layer%moving_mean_initialiser = 'zeros'
287 !get_default_initialiser("batch")
288 write(*,'("BATCHNORM1D moving mean initialiser: ",A)') &
289
1/2
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
6 trim(layer%moving_mean_initialiser)
290
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if(present(moving_variance_initialiser)) &
291
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 layer%moving_variance_initialiser = moving_variance_initialiser
292
4/4
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 1 times.
6 if(trim(layer%moving_variance_initialiser).eq.'') &
293 5 layer%moving_variance_initialiser = 'ones'
294 !get_default_initialiser("batch")
295 write(*,'("BATCHNORM1D moving variance initialiser: ",A)') &
296
1/2
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
6 trim(layer%moving_variance_initialiser)
297
298
299 !!--------------------------------------------------------------------------
300 !! initialise layer shape
301 !!--------------------------------------------------------------------------
302
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 if(present(input_shape))then
303
4/8
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 4 times.
4 call layer%init(input_shape=input_shape)
304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 elseif(present(num_channels).and.present(num_inputs))then
305 call layer%init(input_shape=[num_inputs, num_channels])
306
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 elseif(present(num_channels))then
307
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 call layer%init(input_shape=[num_channels])
308
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 elseif(present(num_inputs))then
309
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 call layer%init(input_shape=[num_inputs])
310 end if
311
312
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
12 end function layer_setup
313 !!!#############################################################################
314
315
316 !!!#############################################################################
317 !!! initialise layer
318 !!!#############################################################################
319
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 subroutine init_batchnorm1d(this, input_shape, batch_size, verbose)
320 use initialiser, only: initialiser_setup
321 implicit none
322 class(batchnorm1d_layer_type), intent(inout) :: this
323 integer, dimension(:), intent(in) :: input_shape
324 integer, optional, intent(in) :: batch_size
325 integer, optional, intent(in) :: verbose
326
327 integer :: verbose_ = 0
328 12 class(initialiser_type), allocatable :: t_initialiser
329
330
331 !!--------------------------------------------------------------------------
332 !! initialise optional arguments
333 !!--------------------------------------------------------------------------
334
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(present(verbose)) verbose_ = verbose
335
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(present(batch_size)) this%batch_size = batch_size
336
337
338 !!--------------------------------------------------------------------------
339 !! initialise input shape
340 !!--------------------------------------------------------------------------
341
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(.not.allocated(this%input_shape))then
342
7/14
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 6 times.
✓ Branch 18 taken 6 times.
✗ Branch 19 not taken.
6 if(size(input_shape).eq.1.or.size(input_shape).eq.2)then
343
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
6 this%input_rank = size(input_shape)
344 end if
345
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
6 call this%set_shape(input_shape)
346 end if
347
348
349 !!--------------------------------------------------------------------------
350 !! set up output shape
351 !!--------------------------------------------------------------------------
352
10/20
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 6 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 6 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 6 times.
✓ Branch 23 taken 6 times.
12 this%output_shape = this%input_shape
353
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
6 this%num_channels = this%input_shape(this%input_rank)
354
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(size(this%input_shape).eq.2)then
355 this%num_inputs = this%input_shape(1)
356 end if
357
358
359 !!--------------------------------------------------------------------------
360 !! allocate mean, variance, gamma, beta, dg, db
361 !!--------------------------------------------------------------------------
362
13/24
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 6 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 6 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 6 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 6 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 6 times.
✓ Branch 29 taken 36 times.
✓ Branch 30 taken 6 times.
42 allocate(this%mean(this%num_channels), source=0._real12)
363
18/34
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 6 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 6 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 6 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 6 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 6 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 6 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 6 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 6 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 6 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 6 times.
✓ Branch 44 taken 36 times.
✓ Branch 45 taken 6 times.
42 allocate(this%variance, source=this%mean)
364
18/34
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 6 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 6 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 6 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 6 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 6 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 6 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 6 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 6 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 6 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 6 times.
✓ Branch 44 taken 36 times.
✓ Branch 45 taken 6 times.
42 allocate(this%gamma, source=this%mean)
365
18/34
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 6 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 6 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 6 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 6 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 6 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 6 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 6 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 6 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 6 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 6 times.
✓ Branch 44 taken 36 times.
✓ Branch 45 taken 6 times.
42 allocate(this%beta, source=this%mean)
366
18/34
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 6 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 6 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 6 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 6 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 6 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 6 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 6 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 6 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 6 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 6 times.
✓ Branch 44 taken 36 times.
✓ Branch 45 taken 6 times.
42 allocate(this%dg, source=this%mean)
367
18/34
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 6 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 6 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 6 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 6 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 6 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 6 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 6 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 6 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 6 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 6 times.
✓ Branch 44 taken 36 times.
✓ Branch 45 taken 6 times.
42 allocate(this%db, source=this%mean)
368
369
370 !!--------------------------------------------------------------------------
371 !! initialise gamma
372 !!--------------------------------------------------------------------------
373
4/8
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6 times.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
12 allocate(t_initialiser, source=initialiser_setup(this%kernel_initialiser))
374 6 t_initialiser%mean = this%gamma_init_mean
375 6 t_initialiser%std = this%gamma_init_std
376 24 call t_initialiser%initialise(this%gamma, &
377 fan_in =this%num_channels, &
378
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6 times.
6 fan_out=this%num_channels)
379
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
6 deallocate(t_initialiser)
380
381 !! initialise beta
382 !!--------------------------------------------------------------------------
383
4/8
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6 times.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
12 allocate(t_initialiser, source=initialiser_setup(this%bias_initialiser))
384 6 t_initialiser%mean = this%beta_init_mean
385 6 t_initialiser%std = this%beta_init_std
386 24 call t_initialiser%initialise(this%beta, &
387 fan_in =this%num_channels, &
388
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6 times.
6 fan_out=this%num_channels)
389
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
6 deallocate(t_initialiser)
390
391
392 !!--------------------------------------------------------------------------
393 !! initialise moving mean
394 !!--------------------------------------------------------------------------
395 allocate(t_initialiser, &
396
4/8
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✓ Branch 9 taken 6 times.
✗ Branch 10 not taken.
12 source=initialiser_setup(this%moving_mean_initialiser))
397 24 call t_initialiser%initialise(this%mean, &
398 fan_in =this%num_channels, &
399
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6 times.
6 fan_out=this%num_channels)
400
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
6 deallocate(t_initialiser)
401
402 !! initialise moving variance
403 !!--------------------------------------------------------------------------
404 allocate(t_initialiser, &
405
4/8
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✓ Branch 9 taken 6 times.
✗ Branch 10 not taken.
12 source=initialiser_setup(this%moving_variance_initialiser))
406 24 call t_initialiser%initialise(this%variance, &
407 fan_in =this%num_channels, &
408
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6 times.
6 fan_out=this%num_channels)
409
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
6 deallocate(t_initialiser)
410
411
412 !!--------------------------------------------------------------------------
413 !! initialise batch size-dependent arrays
414 !!--------------------------------------------------------------------------
415
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(this%batch_size.gt.0) call this%set_batch_size(this%batch_size)
416
417
1/4
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
30 end subroutine init_batchnorm1d
418 !!!#############################################################################
419
420
421 !!!#############################################################################
422 !!! set batch size
423 !!!#############################################################################
424 6 subroutine set_batch_size_batchnorm1d(this, batch_size, verbose)
425 implicit none
426 class(batchnorm1d_layer_type), intent(inout) :: this
427 integer, intent(in) :: batch_size
428 integer, optional, intent(in) :: verbose
429
430 integer :: verbose_ = 0
431
432
433 !!--------------------------------------------------------------------------
434 !! initialise optional arguments
435 !!--------------------------------------------------------------------------
436
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(present(verbose)) verbose_ = verbose
437 6 this%batch_size = batch_size
438
439
440 !!--------------------------------------------------------------------------
441 !! set norm
442 !!--------------------------------------------------------------------------
443 6 this%norm = real(this%batch_size, real12)
444
445
446 !!--------------------------------------------------------------------------
447 !! allocate arrays
448 !!--------------------------------------------------------------------------
449
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(allocated(this%input_shape))then
450
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if(allocated(this%output)) deallocate(this%output)
451 allocate(this%output( &
452 this%num_inputs, &
453 this%num_channels, &
454 this%batch_size), &
455
29/52
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 6 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 6 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 6 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 6 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 6 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 6 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 6 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 6 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 6 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 6 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 6 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 6 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 6 times.
✗ Branch 51 not taken.
✓ Branch 52 taken 6 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 6 times.
✗ Branch 57 not taken.
✓ Branch 58 taken 6 times.
✓ Branch 60 taken 22 times.
✓ Branch 61 taken 6 times.
✓ Branch 62 taken 164 times.
✓ Branch 63 taken 22 times.
✓ Branch 64 taken 164 times.
✓ Branch 65 taken 164 times.
356 source=0._real12)
456
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if(allocated(this%di)) deallocate(this%di)
457
44/82
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 6 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 6 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 6 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 6 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 6 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 6 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 6 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 6 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 6 times.
✗ Branch 40 not taken.
✓ Branch 41 taken 6 times.
✗ Branch 43 not taken.
✓ Branch 44 taken 6 times.
✗ Branch 46 not taken.
✓ Branch 47 taken 6 times.
✗ Branch 49 not taken.
✓ Branch 50 taken 6 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 6 times.
✗ Branch 55 not taken.
✓ Branch 56 taken 6 times.
✗ Branch 58 not taken.
✓ Branch 59 taken 6 times.
✗ Branch 61 not taken.
✓ Branch 62 taken 6 times.
✗ Branch 64 not taken.
✓ Branch 65 taken 6 times.
✗ Branch 67 not taken.
✓ Branch 68 taken 6 times.
✗ Branch 70 not taken.
✓ Branch 71 taken 6 times.
✗ Branch 73 not taken.
✓ Branch 74 taken 6 times.
✗ Branch 76 not taken.
✓ Branch 77 taken 6 times.
✗ Branch 79 not taken.
✓ Branch 80 taken 6 times.
✗ Branch 82 not taken.
✓ Branch 83 taken 6 times.
✗ Branch 85 not taken.
✓ Branch 86 taken 6 times.
✗ Branch 88 not taken.
✓ Branch 89 taken 6 times.
✗ Branch 91 not taken.
✓ Branch 92 taken 6 times.
✗ Branch 94 not taken.
✓ Branch 95 taken 6 times.
✗ Branch 97 not taken.
✓ Branch 98 taken 6 times.
✗ Branch 100 not taken.
✓ Branch 101 taken 6 times.
✗ Branch 103 not taken.
✓ Branch 104 taken 6 times.
✓ Branch 106 taken 22 times.
✓ Branch 107 taken 6 times.
✓ Branch 108 taken 164 times.
✓ Branch 109 taken 22 times.
✓ Branch 110 taken 164 times.
✓ Branch 111 taken 164 times.
356 allocate(this%di, source=this%output)
458 end if
459
460 6 end subroutine set_batch_size_batchnorm1d
461 !!!#############################################################################
462
463
464 !!!##########################################################################!!!
465 !!! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !!!
466 !!!##########################################################################!!!
467
468
469 !!!#############################################################################
470 !!! print layer to file
471 !!!#############################################################################
472 subroutine print_batchnorm1d(this, file)
473 implicit none
474 class(batchnorm1d_layer_type), intent(in) :: this
475 character(*), intent(in) :: file
476
477 integer :: unit
478 integer :: m
479
480 !! open file with new unit
481 !!--------------------------------------------------------------------------
482 open(newunit=unit, file=trim(file), access='append')
483
484 !! write convolution initial parameters
485 !!--------------------------------------------------------------------------
486 write(unit,'("BATCHNORM1D")')
487 write(unit,'(3X,"INPUT_SHAPE = ",2(1X,I0))') this%input_shape
488 write(unit,'(3X,"MOMENTUM = ",F0.9)') this%momentum
489 write(unit,'(3X,"EPSILON = ",F0.9)') this%epsilon
490 write(unit,'(3X,"NUM_CHANNELS = ",I0)') this%num_channels
491 write(unit,'("GAMMA")')
492 do m=1,this%num_channels
493 write(unit,'(5(E16.8E2))') this%gamma(m)
494 end do
495 write(unit,'("END GAMMA")')
496 write(unit,'("BETA")')
497 do m=1,this%num_channels
498 write(unit,'(5(E16.8E2))') this%beta(m)
499 end do
500 write(unit,'("END BATCHNORM1D")')
501
502 !! close unit
503 !!--------------------------------------------------------------------------
504 close(unit)
505
506 end subroutine print_batchnorm1d
507 !!!#############################################################################
508
509
510 !!!#############################################################################
511 !!! read layer from file
512 !!!#############################################################################
513 function read_batchnorm1d_layer(unit, verbose) result(layer)
514 use infile_tools, only: assign_val, assign_vec
515 use misc, only: to_lower, icount
516 implicit none
517 integer, intent(in) :: unit
518 integer, optional, intent(in) :: verbose
519
520 class(batchnorm1d_layer_type), allocatable :: layer
521
522 integer :: stat, verbose_ = 0
523 integer :: itmp1, c, i, j, k
524 integer :: num_channels
525 real(real12) :: momentum = 0._real12, epsilon = 1.E-5_real12
526 logical :: found_gamma=.false., found_beta=.false.
527 character(14) :: kernel_initialiser='', bias_initialiser=''
528 character(256) :: buffer, tag
529
530 integer, dimension(3) :: input_shape
531 real(real12), allocatable, dimension(:) :: data_list
532
533
534 !!--------------------------------------------------------------------------
535 !! initialise optional arguments
536 !!--------------------------------------------------------------------------
537 if(present(verbose)) verbose_ = verbose
538
539
540 !!--------------------------------------------------------------------------
541 !! loop over tags in layer card
542 !!--------------------------------------------------------------------------
543 tag_loop: do
544
545 !! check for end of file
546 read(unit,'(A)',iostat=stat) buffer
547 if(stat.ne.0)then
548 write(0,*) "ERROR: file encountered error (EoF?) before END BATCHNORM1D"
549 stop "Exiting..."
550 end if
551 if(trim(adjustl(buffer)).eq."") cycle tag_loop
552
553 !! check for end of convolution card
554 if(trim(adjustl(buffer)).eq."END BATCHNORM1D")then
555 backspace(unit)
556 exit tag_loop
557 end if
558
559 tag=trim(adjustl(buffer))
560 if(scan(buffer,"=").ne.0) tag=trim(tag(:scan(tag,"=")-1))
561
562 !! read parameters from save file
563 select case(trim(tag))
564 case("INPUT_SHAPE")
565 call assign_vec(buffer, input_shape, itmp1)
566 case("MOMENTUM")
567 call assign_val(buffer, momentum, itmp1)
568 case("EPSILON")
569 call assign_val(buffer, epsilon, itmp1)
570 case("KERNEL_INITIALISER")
571 call assign_val(buffer, kernel_initialiser, itmp1)
572 case("BIAS_INITIALISER")
573 call assign_val(buffer, bias_initialiser, itmp1)
574 case("GAMMA")
575 found_gamma = .true.
576 kernel_initialiser = 'zeros'
577 bias_initialiser = 'zeros'
578 exit tag_loop
579 case("beta")
580 found_beta = .true.
581 kernel_initialiser = 'zeros'
582 bias_initialiser = 'zeros'
583 exit tag_loop
584 case default
585 !! don't look for "e" due to scientific notation of numbers
586 !! ... i.e. exponent (E+00)
587 if(scan(to_lower(trim(adjustl(buffer))),&
588 'abcdfghijklmnopqrstuvwxyz').eq.0)then
589 cycle tag_loop
590 elseif(tag(:3).eq.'END')then
591 cycle tag_loop
592 end if
593 stop "Unrecognised line in input file: "//trim(adjustl(buffer))
594 end select
595 end do tag_loop
596
597
598 !!--------------------------------------------------------------------------
599 !! set transfer activation function
600 !!--------------------------------------------------------------------------
601 num_channels = input_shape(size(input_shape))
602 layer = batchnorm1d_layer_type( input_shape=input_shape, &
603 momentum = momentum, epsilon = epsilon &
604 )
605
606
607 !!--------------------------------------------------------------------------
608 !! check if WEIGHTS card was found
609 !!--------------------------------------------------------------------------
610 allocate(data_list(num_channels), source=0._real12)
611 do i=1,2
612 if(found_gamma.or.found_beta)then
613 c = 1
614 k = 1
615 data_list = 0._real12
616 data_concat_loop: do while(c.le.num_channels)
617 read(unit,'(A)',iostat=stat) buffer
618 if(stat.ne.0) exit data_concat_loop
619 k = icount(buffer)
620 read(buffer,*,iostat=stat) (data_list(j),j=c,c+k-1)
621 c = c + k
622 end do data_concat_loop
623 if(found_gamma)then
624 layer%gamma = data_list
625 found_gamma = .false.
626 elseif(found_beta)then
627 layer%beta = data_list
628 found_beta = .false.
629 end if
630 read(unit,'(A)',iostat=stat) buffer
631 if(index(trim(adjustl(buffer)),"GAMMA").eq.1) found_gamma = .true.
632 if(index(trim(adjustl(buffer)),"BETA").eq.1) found_beta = .true.
633 end if
634 end do
635 deallocate(data_list)
636
637
638 !! check for end of layer card
639 !!-----------------------------------------------------------------------
640 read(unit,'(A)') buffer
641 if(trim(adjustl(buffer)).ne."END BATCHNORM1D")then
642 write(*,*) trim(adjustl(buffer))
643 stop "ERROR: END BATCHNORM1D not where expected"
644 end if
645
646 end function read_batchnorm1d_layer
647 !!!#############################################################################
648
649
650 !!!##########################################################################!!!
651 !!! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !!!
652 !!!##########################################################################!!!
653
654
655 !!!#############################################################################
656 !!! forward propagation
657 !!!#############################################################################
658 2 pure subroutine forward_3d(this, input)
659 implicit none
660 class(batchnorm1d_layer_type), intent(inout) :: this
661 real(real12), dimension( &
662 this%num_inputs, &
663 this%num_channels, &
664 this%batch_size), &
665 intent(in) :: input
666
667 integer :: m
668 4 real(real12), dimension(this%num_channels) :: t_mean, t_variance
669
670
671 2 select case(this%inference)
672 case(.true.)
673 do concurrent(m=1:this%num_channels)
674 !! normalize each feature
675 this%output(:,m,:) = this%gamma(m) * (input(:,m,:) - this%mean(m)) / &
676 sqrt( &
677 this%batch_size / (this%batch_size - 1) * this%variance(m) + &
678 this%epsilon) + &
679 this%beta(m)
680 end do
681 case default
682
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 16 times.
✓ Branch 10 taken 2 times.
18 t_mean = 0._real12
683
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 16 times.
✓ Branch 10 taken 2 times.
18 t_variance = 0._real12
684
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 do concurrent(m=1:this%num_channels)
685 !! calculate current mean and variance
686
14/24
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 16 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 16 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 16 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 16 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 16 times.
✓ Branch 24 taken 80 times.
✓ Branch 25 taken 16 times.
✓ Branch 26 taken 80 times.
✓ Branch 27 taken 80 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 16 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 16 times.
176 t_mean(m) = sum(input(:,m,:)) / this%norm
687
16/28
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 16 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 16 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 16 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 16 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 16 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 16 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 16 times.
✓ Branch 30 taken 80 times.
✓ Branch 31 taken 16 times.
✓ Branch 32 taken 80 times.
✓ Branch 33 taken 80 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 16 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 16 times.
176 t_variance(m) = sum((input(:,m,:) - t_mean(m))**2._real12) / this%norm
688
689 !! CONVERT TO USING inverse square root of variance (i.e. inverse std)
690 !! would also need to include epsilon in the sqrt denominator
691
692 !! update running averages
693
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if(this%momentum.gt.1.E-8_real12)then
694 this%mean(m) = this%momentum * this%mean(m) + &
695 (1._real12 - this%momentum) * t_mean(m)
696 this%variance(m) = this%momentum * this%variance(m) + &
697 (1._real12 - this%momentum) * t_variance(m)
698 else
699
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 16 times.
16 this%mean(m) = t_mean(m)
700
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 16 times.
16 this%variance(m) = t_variance(m)
701 end if
702
703 !! normalize each feature
704
1/2
✗ Branch 7 not taken.
✓ Branch 8 taken 16 times.
16 this%output(:,m,:) = this%gamma(m) * (input(:,m,:) - this%mean(m)) / &
705
33/60
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 16 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 16 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 16 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 16 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 16 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 16 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 16 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 16 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 16 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 16 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 16 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 16 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 16 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 16 times.
✗ Branch 44 not taken.
✓ Branch 45 taken 16 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 16 times.
✗ Branch 50 not taken.
✓ Branch 51 taken 16 times.
✗ Branch 53 not taken.
✓ Branch 54 taken 16 times.
✗ Branch 56 not taken.
✓ Branch 57 taken 16 times.
✗ Branch 59 not taken.
✓ Branch 60 taken 16 times.
✗ Branch 62 not taken.
✓ Branch 63 taken 16 times.
✗ Branch 65 not taken.
✓ Branch 66 taken 16 times.
✗ Branch 68 not taken.
✓ Branch 69 taken 16 times.
✗ Branch 70 not taken.
✓ Branch 71 taken 16 times.
✗ Branch 73 not taken.
✓ Branch 74 taken 16 times.
✓ Branch 76 taken 80 times.
✓ Branch 77 taken 16 times.
✓ Branch 78 taken 80 times.
✓ Branch 79 taken 80 times.
194 sqrt(this%variance(m) + this%epsilon) + this%beta(m)
706
707 end do
708 end select
709
710 2 end subroutine forward_3d
711 !!!#############################################################################
712
713
714 !!!#############################################################################
715 !!! backward propagation
716 !!!#############################################################################
717 1 pure subroutine backward_3d(this, input, gradient)
718 implicit none
719 class(batchnorm1d_layer_type), intent(inout) :: this
720 real(real12), dimension( &
721 this%num_inputs, &
722 this%num_channels, &
723 this%batch_size), &
724 intent(in) :: input
725 real(real12), dimension( &
726 this%num_inputs, &
727 this%num_channels, &
728 this%batch_size), &
729 intent(in) :: gradient
730
731 integer :: m
732 real(real12), dimension( &
733 this%num_inputs, &
734 this%num_channels, &
735 2 this%batch_size) :: x_hat, dx_hat
736
737
738 1 do concurrent(m=1:this%num_channels)
739 !! recalculate x_hat (i.e. normalised input)
740
2/4
✗ Branch 15 not taken.
✓ Branch 16 taken 8 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 8 times.
16 x_hat(:,m,:) = (input(:,m,:) - this%mean(m)) / &
741
24/44
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 8 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 8 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 8 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 8 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 8 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 8 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 8 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 8 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 8 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 8 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 8 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 8 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 8 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 8 times.
✗ Branch 40 not taken.
✓ Branch 41 taken 8 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 8 times.
✓ Branch 44 taken 40 times.
✓ Branch 45 taken 8 times.
✓ Branch 46 taken 40 times.
✓ Branch 47 taken 40 times.
104 sqrt(this%variance(m) + this%epsilon)
742
743 !! calculate gradient of normalised input
744
24/44
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 8 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 8 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 8 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 8 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 8 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 8 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 8 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 8 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 8 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 8 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 8 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 8 times.
✗ Branch 51 not taken.
✓ Branch 52 taken 8 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 8 times.
✗ Branch 57 not taken.
✓ Branch 58 taken 8 times.
✓ Branch 60 taken 40 times.
✓ Branch 61 taken 8 times.
✓ Branch 62 taken 40 times.
✓ Branch 63 taken 40 times.
88 dx_hat(:,m,:) = gradient(:,m,:) * this%gamma(m)
745
746 !! calculate gradient of inputs
747 96 this%di(:,m,:) = &
748 16 1._real12 / (this%norm * sqrt(this%variance(m) + this%epsilon)) * &
749
1/2
✗ Branch 7 not taken.
✓ Branch 8 taken 8 times.
8 ( this%norm * dx_hat(:,m,:) - &
750
2/4
✗ Branch 15 not taken.
✓ Branch 16 taken 8 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 8 times.
16 sum(dx_hat(:,m,:)) - x_hat(:,m,:) * &
751
67/122
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 8 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 8 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 8 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 8 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 8 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 8 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 8 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 8 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 8 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 8 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 8 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 8 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 8 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 8 times.
✗ Branch 40 not taken.
✓ Branch 41 taken 8 times.
✗ Branch 43 not taken.
✓ Branch 44 taken 8 times.
✗ Branch 46 not taken.
✓ Branch 47 taken 8 times.
✗ Branch 49 not taken.
✓ Branch 50 taken 8 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 8 times.
✗ Branch 55 not taken.
✓ Branch 56 taken 8 times.
✗ Branch 58 not taken.
✓ Branch 59 taken 8 times.
✗ Branch 61 not taken.
✓ Branch 62 taken 8 times.
✗ Branch 64 not taken.
✓ Branch 65 taken 8 times.
✗ Branch 66 not taken.
✓ Branch 67 taken 8 times.
✗ Branch 68 not taken.
✓ Branch 69 taken 8 times.
✗ Branch 70 not taken.
✓ Branch 71 taken 8 times.
✗ Branch 72 not taken.
✓ Branch 73 taken 8 times.
✗ Branch 74 not taken.
✓ Branch 75 taken 8 times.
✗ Branch 76 not taken.
✓ Branch 77 taken 8 times.
✓ Branch 78 taken 40 times.
✓ Branch 79 taken 8 times.
✓ Branch 80 taken 40 times.
✓ Branch 81 taken 40 times.
✗ Branch 82 not taken.
✓ Branch 83 taken 8 times.
✗ Branch 85 not taken.
✓ Branch 86 taken 8 times.
✗ Branch 88 not taken.
✓ Branch 89 taken 8 times.
✗ Branch 91 not taken.
✓ Branch 92 taken 8 times.
✗ Branch 94 not taken.
✓ Branch 95 taken 8 times.
✗ Branch 97 not taken.
✓ Branch 98 taken 8 times.
✗ Branch 100 not taken.
✓ Branch 101 taken 8 times.
✗ Branch 103 not taken.
✓ Branch 104 taken 8 times.
✗ Branch 106 not taken.
✓ Branch 107 taken 8 times.
✗ Branch 109 not taken.
✓ Branch 110 taken 8 times.
✗ Branch 112 not taken.
✓ Branch 113 taken 8 times.
✗ Branch 115 not taken.
✓ Branch 116 taken 8 times.
✗ Branch 118 not taken.
✓ Branch 119 taken 8 times.
✗ Branch 121 not taken.
✓ Branch 122 taken 8 times.
✗ Branch 124 not taken.
✓ Branch 125 taken 8 times.
✗ Branch 127 not taken.
✓ Branch 128 taken 8 times.
✗ Branch 130 not taken.
✓ Branch 131 taken 8 times.
✗ Branch 133 not taken.
✓ Branch 134 taken 8 times.
✓ Branch 136 taken 40 times.
✓ Branch 137 taken 8 times.
✓ Branch 138 taken 40 times.
✓ Branch 139 taken 40 times.
✗ Branch 140 not taken.
✓ Branch 141 taken 8 times.
✗ Branch 142 not taken.
✓ Branch 143 taken 8 times.
✗ Branch 144 not taken.
✓ Branch 145 taken 8 times.
✗ Branch 147 not taken.
✓ Branch 148 taken 8 times.
✓ Branch 150 taken 40 times.
✓ Branch 151 taken 8 times.
✓ Branch 152 taken 40 times.
✓ Branch 153 taken 40 times.
272 sum(dx_hat(:,m,:) * x_hat(:,m,:)))
752
753 !! calculate gradient of gamma and beta
754
24/44
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 8 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 8 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 8 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 8 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 8 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 8 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 8 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 8 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 8 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 8 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 8 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 8 times.
✗ Branch 51 not taken.
✓ Branch 52 taken 8 times.
✓ Branch 54 taken 40 times.
✓ Branch 55 taken 8 times.
✓ Branch 56 taken 40 times.
✓ Branch 57 taken 40 times.
✗ Branch 58 not taken.
✓ Branch 59 taken 8 times.
✗ Branch 61 not taken.
✓ Branch 62 taken 8 times.
88 this%dg(m) = sum(gradient(:,m,:) * x_hat(:,m,:))
755
16/26
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 8 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 8 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 8 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 8 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 8 times.
✓ Branch 26 taken 40 times.
✓ Branch 27 taken 8 times.
✓ Branch 28 taken 40 times.
✓ Branch 29 taken 40 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 8 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 8 times.
89 this%db(m) = sum(gradient(:,m,:))
756 end do
757
758 1 end subroutine backward_3d
759 !!!#############################################################################
760
761
57/110
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 3 times.
✓ Branch 9 taken 7 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 7 times.
✓ Branch 12 taken 2 times.
✓ Branch 13 taken 7 times.
✓ Branch 14 taken 2 times.
✓ Branch 15 taken 7 times.
✓ Branch 16 taken 2 times.
✓ Branch 17 taken 7 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 7 times.
✓ Branch 20 taken 1 times.
✓ Branch 21 taken 7 times.
✓ Branch 22 taken 1 times.
✓ Branch 23 taken 7 times.
✓ Branch 24 taken 1 times.
✓ Branch 25 taken 7 times.
✓ Branch 26 taken 1 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 1 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 1 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✓ Branch 40 taken 4 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✓ Branch 43 taken 4 times.
✓ Branch 45 taken 4 times.
✓ Branch 46 taken 4 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 4 times.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✓ Branch 67 taken 4 times.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✓ Branch 70 taken 4 times.
✓ Branch 71 taken 4 times.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✓ Branch 74 taken 4 times.
✓ Branch 75 taken 4 times.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✓ Branch 78 taken 4 times.
✓ Branch 79 taken 4 times.
✗ Branch 80 not taken.
✓ Branch 81 taken 4 times.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✓ Branch 86 taken 4 times.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✓ Branch 89 taken 4 times.
✓ Branch 90 taken 4 times.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✓ Branch 93 taken 4 times.
✓ Branch 94 taken 4 times.
✗ Branch 95 not taken.
✗ Branch 96 not taken.
✓ Branch 97 taken 4 times.
✓ Branch 98 taken 4 times.
✗ Branch 99 not taken.
✗ Branch 100 not taken.
✓ Branch 101 taken 4 times.
✓ Branch 102 taken 4 times.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✓ Branch 105 taken 4 times.
✓ Branch 106 taken 4 times.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✓ Branch 109 taken 4 times.
✓ Branch 110 taken 4 times.
✗ Branch 111 not taken.
✗ Branch 112 not taken.
✓ Branch 113 taken 4 times.
✓ Branch 114 taken 4 times.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✓ Branch 117 taken 4 times.
41 end module batchnorm1d_layer
762 !!!#############################################################################
763