GCC Code Coverage Report


Directory: src/athena/
File: src/athena/athena_add_layer.f90
Date: 2026-04-15 16:08:59
Exec Total Coverage
Lines: 85 120 70.8%
Functions: 0 0 -%
Branches: 217 604 35.9%

Line Branch Exec Source
1 module athena__add_layer
2 !! Module containing implementation of an element-wise addition layer
3 !!
4 !! This module implements a merge layer that performs element-wise addition
5 !! of multiple input tensors. Commonly used for residual/skip connections.
6 !!
7 !! Mathematical operation:
8 !! output = sum(input_i) for i=1..N
9 !!
10 !! where N is the number of input layers. All inputs must have identical shapes.
11 !! Gradients are copied (not split) to all inputs during backpropagation.
12 use coreutils, only: real32, stop_program
13 use athena__base_layer, only: merge_layer_type, base_layer_type
14 use athena__diffstruc_extd, only: array_ptr_type, add_layers
15 use diffstruc, only: array_type, operator(+)
16 implicit none
17
18
19 private
20
21 public :: add_layer_type
22 public :: read_add_layer
23
24
25 type, extends(merge_layer_type) :: add_layer_type
26 !! Type for add layer with overloaded procedures
27 contains
28 procedure, pass(this) :: set_hyperparams => set_hyperparams_add
29 !! Set the hyperparameters for add layer
30 procedure, pass(this) :: init => init_add
31 !! Initialise add layer
32 procedure, pass(this) :: print_to_unit => print_to_unit_add
33 !! Print the layer to a file
34 procedure, pass(this) :: read => read_add
35 !! Read the layer from a file
36
37 procedure, pass(this) :: calc_input_shape => calc_input_shape_add
38 !! Calculate input shape based on shapes of input layers
39
40 procedure, pass(this) :: combine => combine_add
41 end type add_layer_type
42
43 interface add_layer_type
44 !! Interface for setting up the add layer
45 module function layer_setup( &
46 input_layer_ids, input_rank, verbose &
47 ) result(layer)
48 !! Setup a add layer
49 integer, dimension(:), intent(in) :: input_layer_ids
50 !! Input layer IDs
51 integer, optional, intent(in) :: input_rank
52 !! Input rank
53 integer, optional, intent(in) :: verbose
54 !! Verbosity level
55 type(add_layer_type) :: layer
56 end function layer_setup
57 end interface add_layer_type
58
59
60
61 contains
62
63 !###############################################################################
64 3 module function layer_setup( &
65 3 input_layer_ids, input_rank, verbose &
66 3 ) result(layer)
67 !! Setup a add layer
68 implicit none
69
70 ! Arguments
71 integer, dimension(:), intent(in) :: input_layer_ids
72 !! Input layer IDs
73 integer, optional, intent(in) :: input_rank
74 !! Input rank
75 integer, optional, intent(in) :: verbose
76 !! Verbosity level
77
78 type(add_layer_type) :: layer
79 !! Instance of the add layer
80
81 ! Local variables
82 integer :: input_rank_ = 0
83 !! Input rank
84 integer :: verbose_ = 0
85 !! Verbosity level
86
87
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if(present(verbose)) verbose_ = verbose
88
89
90 !---------------------------------------------------------------------------
91 ! Set hyperparameters
92 !---------------------------------------------------------------------------
93
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(present(input_rank))then
94 3 input_rank_ = input_rank
95 else
96 call stop_program( &
97 "input_rank or input_shape must be provided to concat layer" &
98 )
99 return
100 end if
101 call layer%set_hyperparams( &
102 input_layer_ids = input_layer_ids, &
103 input_rank = input_rank_, &
104 verbose = verbose_ &
105
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
3 )
106
107
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 end function layer_setup
108 !###############################################################################
109
110
111 !###############################################################################
112 4 subroutine set_hyperparams_add( &
113 this, &
114
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 input_layer_ids, &
115 input_rank, &
116 verbose &
117 )
118 !! Set the hyperparameters for add layer
119 implicit none
120
121 ! Arguments
122 class(add_layer_type), intent(inout) :: this
123 !! Instance of the add layer
124 integer, dimension(:), intent(in) :: input_layer_ids
125 !! Input layer IDs
126 integer, intent(in) :: input_rank
127 !! Input rank
128 integer, optional, intent(in) :: verbose
129 !! Verbosity level
130
131
132
5/8
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
4 this%name = "add"
133 4 this%type = "merg"
134 4 this%merge_mode = 1 ! pointwise mode
135
9/14
✗ 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 taken 1 times.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 3 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 8 times.
✓ Branch 16 taken 4 times.
12 this%input_layer_ids = input_layer_ids
136 4 this%input_rank = input_rank
137 4 this%output_rank = input_rank
138
139 4 end subroutine set_hyperparams_add
140 !###############################################################################
141
142
143 !###############################################################################
144
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 subroutine init_add(this, input_shape, verbose)
145 !! Initialise add layer
146 implicit none
147
148 ! Arguments
149 class(add_layer_type), intent(inout) :: this
150 !! Instance of the add layer
151 integer, dimension(:), intent(in) :: input_shape
152 !! Input shape
153 integer, optional, intent(in) :: verbose
154 !! Verbosity level
155
156 ! Local variables
157 integer :: i
158 !! Loop index
159 integer :: verbose_ = 0
160 !! Verbosity level
161
162
163 !---------------------------------------------------------------------------
164 ! Initialise optional arguments
165 !---------------------------------------------------------------------------
166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(present(verbose)) verbose_ = verbose
167
168
169 !---------------------------------------------------------------------------
170 ! Initialise input shape
171 !---------------------------------------------------------------------------
172
3/6
✗ 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.
3 this%input_rank = size(input_shape)
173
4/8
✓ 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 8 not taken.
✓ Branch 9 taken 3 times.
3 if(.not.allocated(this%input_shape)) call this%set_shape(input_shape)
174
175
176 !---------------------------------------------------------------------------
177 ! Initialise output shape
178 !---------------------------------------------------------------------------
179
10/20
✗ 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 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 3 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 3 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 3 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 4 times.
✓ Branch 23 taken 3 times.
7 this%output_shape = this%input_shape
180 3 this%output_rank = size(this%output_shape)
181
182
183 !---------------------------------------------------------------------------
184 ! Allocate arrays
185 !---------------------------------------------------------------------------
186
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
3 if(allocated(this%output)) deallocate(this%output)
187
15/26
✗ 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 taken 3 times.
✓ Branch 34 taken 3 times.
✓ Branch 35 taken 3 times.
✓ Branch 36 taken 3 times.
9 allocate(this%output(1,1))
188
189 3 end subroutine init_add
190 !###############################################################################
191
192
193 !##############################################################################!
194 ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !
195 !##############################################################################!
196
197
198 !###############################################################################
199 1 subroutine print_to_unit_add(this, unit)
200 !! Print add layer to unit
201 implicit none
202
203 ! Arguments
204 class(add_layer_type), intent(in) :: this
205 !! Instance of the add layer
206 integer, intent(in) :: unit
207 !! File unit
208
209 ! Local variables
210 integer :: i
211 !! Loop index
212 character(100) :: fmt
213
214
215 ! Write initial parameters
216 !---------------------------------------------------------------------------
217 1 write(unit,'(3X,"INPUT_RANK = ",I0)') this%input_rank
218 1 write(fmt,'("(3X,""INPUT_SHAPE ="",",I0,"(1X,I0))")') size(this%input_shape)
219 1 write(unit,fmt) this%input_shape
220 1 write(fmt,'("(3X,""INPUT_LAYER_IDS ="",",I0,"(1X,I0))")') size(this%input_layer_ids)
221 1 write(unit,fmt) this%input_layer_ids
222
223 1 end subroutine print_to_unit_add
224 !###############################################################################
225
226
227 !###############################################################################
228 1 subroutine read_add(this, unit, verbose)
229 !! Read add layer from file
230 use athena__tools_infile, only: assign_val, assign_vec, get_val
231 use coreutils, only: to_lower, to_upper, icount
232 implicit none
233
234 ! Arguments
235 class(add_layer_type), intent(inout) :: this
236 !! Instance of the add layer
237 integer, intent(in) :: unit
238 !! Unit number
239 integer, optional, intent(in) :: verbose
240 !! Verbosity level
241
242 ! Local variables
243 integer :: stat, verbose_ = 0
244 !! File status and verbosity level
245 integer :: itmp1 = 0
246 !! Temporary integer
247 integer :: input_rank = 0
248 !! Input rank
249 1 integer, dimension(:), allocatable :: input_shape, input_layer_ids
250 !! Input shape
251 character(256) :: buffer, tag, err_msg
252 !! Buffer, tag, and error message
253
254
255 ! Initialise optional arguments
256 !---------------------------------------------------------------------------
257
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(present(verbose)) verbose_ = verbose
258
259
260 ! Loop over tags in layer card
261 !---------------------------------------------------------------------------
262 3 tag_loop: do
263
264 ! Check for end of file
265 !------------------------------------------------------------------------
266 4 read(unit,'(A)',iostat=stat) buffer
267
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(stat.ne.0)then
268 write(err_msg,'("file encountered error (EoF?) before END ",A)') &
269 to_upper(this%name)
270 call stop_program(err_msg)
271 return
272 end if
273
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if(trim(adjustl(buffer)).eq."") cycle tag_loop
274
275 ! Check for end of layer card
276 !------------------------------------------------------------------------
277
4/6
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 3 times.
8 if(trim(adjustl(buffer)).eq."END "//to_upper(trim(this%name)))then
278 1 backspace(unit)
279 4 exit tag_loop
280 end if
281
282
2/4
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 tag=trim(adjustl(buffer))
283
5/10
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
3 if(scan(buffer,"=").ne.0) tag=trim(tag(:scan(tag,"=")-1))
284
285 ! Read parameters from file
286 !------------------------------------------------------------------------
287 6 select case(trim(tag))
288 case("INPUT_SHAPE")
289 1 itmp1 = icount(get_val(buffer))
290
7/14
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 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.
1 allocate(input_shape(itmp1), source=0)
291 1 call assign_vec(buffer, input_shape, itmp1)
292 case("INPUT_RANK")
293 2 call assign_val(buffer, input_rank, itmp1)
294 case("INPUT_LAYER_IDS")
295 1 itmp1 = icount(get_val(buffer))
296
7/14
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 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.
1 allocate(input_layer_ids(itmp1), source=0)
297 1 call assign_vec(buffer, input_layer_ids, itmp1)
298 case default
299 ! Don't look for "e" due to scientific notation of numbers
300 ! ... i.e. exponent (E+00)
301 if(scan(to_lower(trim(adjustl(buffer))),&
302 'abcdfghijklmnopqrstuvwxyz').eq.0)then
303 cycle tag_loop
304 elseif(tag(:3).eq.'END')then
305 cycle tag_loop
306 end if
307 write(err_msg,'("Unrecognised line in input file: ",A)') &
308 trim(adjustl(buffer))
309 call stop_program(err_msg)
310
4/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
6 return
311 end select
312 end do tag_loop
313
314
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(allocated(input_shape))then
315
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(input_rank.eq.0)then
316 input_rank = size(input_shape)
317
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 elseif(input_rank.ne.size(input_shape))then
318 write(err_msg,'("input_rank (",I0,") does not match input_shape (",I0,")")') &
319 input_rank, size(input_shape)
320 call stop_program(err_msg)
321 return
322 end if
323 elseif(input_rank.eq.0)then
324 write(err_msg,'("input_rank must be provided if input_shape is not")')
325 call stop_program(err_msg)
326 return
327 end if
328
329
330 ! Set hyperparameters and initialise layer
331 !---------------------------------------------------------------------------
332 call this%set_hyperparams( &
333 input_layer_ids = input_layer_ids, &
334 input_rank = input_rank, &
335 verbose = verbose_ &
336 1 )
337 1 call this%init(input_shape = input_shape)
338
339
340 ! Check for end of layer card
341 !---------------------------------------------------------------------------
342 1 read(unit,'(A)') buffer
343
3/6
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
2 if(trim(adjustl(buffer)).ne."END "//to_upper(trim(this%name)))then
344 write(0,*) trim(adjustl(buffer))
345 write(err_msg,'("END ",A," not where expected")') to_upper(this%name)
346 call stop_program(err_msg)
347 1 return
348 end if
349
350
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 end subroutine read_add
351 !###############################################################################
352
353
354 !###############################################################################
355 1 function read_add_layer(unit, verbose) result(layer)
356 !! Read add layer from file and return layer
357 implicit none
358
359 ! Arguments
360 integer, intent(in) :: unit
361 !! Unit number
362 integer, optional, intent(in) :: verbose
363 !! Verbosity level
364 class(base_layer_type), allocatable :: layer
365 !! Instance of the add layer
366
367 ! Local variables
368 integer :: verbose_ = 0
369 !! Verbosity level
370
371
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(present(verbose)) verbose_ = verbose
372 allocate(layer, source=add_layer_type( &
373
9/54
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ 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 taken 1 times.
✗ Branch 49 not taken.
✓ Branch 50 taken 1 times.
✗ Branch 51 not taken.
✓ Branch 52 taken 1 times.
✗ Branch 53 not taken.
✓ Branch 54 taken 1 times.
✓ Branch 55 taken 1 times.
✗ Branch 56 not taken.
2 input_layer_ids=[0,0], input_rank=1))
374 1 call layer%read(unit, verbose=verbose_)
375
376 2 end function read_add_layer
377 !###############################################################################
378
379
380 !##############################################################################!
381 ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !
382 !##############################################################################!
383
384
385 !###############################################################################
386
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 function calc_input_shape_add(this, input_shapes) result(input_shape)
387 !! Calculate input shape based on shapes of input layers
388 implicit none
389
390 ! Arguments
391 class(add_layer_type), intent(in) :: this
392 !! Instance of the layer
393 integer, dimension(:,:), intent(in) :: input_shapes
394 !! Input shapes
395 integer, allocatable, dimension(:) :: input_shape
396 !! Calculated input shape
397
398 ! Local variables
399 integer :: i
400
401 ! Check that all input shapes are the same
402
8/14
✗ 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 taken 1 times.
✓ Branch 19 taken 1 times.
2 do i = 2, size(input_shapes, 2), 1
403
14/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 not taken.
✓ Branch 28 taken 1 times.
✓ Branch 30 taken 2 times.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 2 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 1 times.
4 if(any(input_shapes(:,1).ne.input_shapes(:,i)))then
404 call stop_program("All input shapes to add layer must be the same")
405 return
406 end if
407 end do
408
409 ! Set input shape
410
9/18
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ 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 16 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 2 times.
✓ Branch 21 taken 1 times.
3 input_shape = input_shapes(:,1)
411
412 end function calc_input_shape_add
413 !###############################################################################
414
415
416
417 !##############################################################################!
418 ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !
419 !##############################################################################!
420
421
422 !###############################################################################
423
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 subroutine combine_add(this, input_list)
424 !! Forward propagation for 2D input
425 implicit none
426
427 ! Arguments
428 class(add_layer_type), intent(inout) :: this
429 !! Instance of the add layer
430 type(array_ptr_type), dimension(:), intent(in) :: input_list
431 !! Input values
432
433 ! Local variables
434 integer :: i, j, s
435 !! Loop index
436 type(array_type), pointer :: ptr
437 !! Pointer array
438
439
440
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(allocated(this%output))then
441
9/16
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1 times.
3 if(any(shape(this%output).ne.shape(input_list(1)%array)))then
442 deallocate(this%output)
443 allocate(this%output( &
444 size(input_list(1)%array,1), &
445 size(input_list(1)%array,2) &
446 ))
447 end if
448 else
449 allocate(this%output( &
450 size(input_list(1)%array,1), &
451 size(input_list(1)%array,2) &
452 ))
453 end if
454
455
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
2 do s = 1, size(input_list(1)%array, 2)
456
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
3 index_loop: do i = 1, size(input_list(1)%array, 1)
457
5/8
✗ 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 taken 2 times.
✓ Branch 10 taken 1 times.
3 do j = 1, size(input_list,1)
458
7/14
✗ 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.
✗ Branch 18 not taken.
✓ Branch 19 taken 2 times.
3 if(.not.input_list(j)%array(i,s)%allocated) cycle index_loop
459 end do
460
3/6
✗ 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.
1 ptr => add_layers(input_list, i, s)
461
4/8
✗ 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.
1 call this%output(i,s)%zero_grad()
462
4/8
✗ 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.
1 call this%output(i,s)%assign_and_deallocate_source(ptr)
463
4/8
✗ 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.
2 this%output(i,s)%is_temporary = .false.
464 end do index_loop
465 end do
466
467 1 end subroutine combine_add
468 !###############################################################################
469
470
33/124
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ 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 taken 1 times.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 1 times.
✓ Branch 40 taken 1 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 1 times.
✓ Branch 43 taken 1 times.
✓ Branch 44 taken 1 times.
✓ Branch 45 taken 2 times.
✓ Branch 46 taken 1 times.
✓ Branch 47 taken 1 times.
✓ Branch 48 taken 2 times.
✓ Branch 49 taken 1 times.
✓ Branch 50 taken 1 times.
✓ Branch 51 taken 2 times.
✗ 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 1 times.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✓ Branch 70 taken 1 times.
✓ Branch 71 taken 1 times.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✓ Branch 74 taken 1 times.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 99 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✓ Branch 109 taken 1 times.
✗ Branch 110 not taken.
✓ Branch 111 taken 1 times.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✓ Branch 114 taken 1 times.
✓ Branch 115 taken 1 times.
✗ Branch 116 not taken.
✓ Branch 118 taken 1 times.
✗ Branch 119 not taken.
✗ Branch 120 not taken.
✓ Branch 121 taken 1 times.
✓ Branch 122 taken 1 times.
✗ Branch 123 not taken.
✗ Branch 124 not taken.
✓ Branch 125 taken 1 times.
✓ Branch 126 taken 1 times.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✓ Branch 129 taken 1 times.
12 end module athena__add_layer
471