GCC Code Coverage Report


Directory: src/athena/
File: src/athena/athena_concat_layer.f90
Date: 2026-04-15 16:08:59
Exec Total Coverage
Lines: 84 117 71.8%
Functions: 0 0 -%
Branches: 203 577 35.2%

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