GCC Code Coverage Report


Directory: src/athena/
File: src/athena/athena_reshape_layer.f90
Date: 2026-04-15 16:08:59
Exec Total Coverage
Lines: 93 115 80.9%
Functions: 0 0 -%
Branches: 205 551 37.2%

Line Branch Exec Source
1 module athena__reshape_layer
2 !! Module containing implementation of a reshape layer
3 !!
4 !! This module implements a general reshape layer that can transform tensors
5 !! between arbitrary shapes while preserving the total number of elements.
6 !! Unlike flatten (which only converts to 1D), reshape allows any target shape.
7 !!
8 !! Mathematical operation:
9 !! Reshape: (d1, d2, ..., dn) -> (d1', d2', ..., dm')
10 !! where: d1 * d2 * ... * dn = d1' * d2' * ... * dm'
11 !!
12 !! Examples:
13 !! - (28, 28) -> (784) [flatten]
14 !! - (784) -> (28, 28) [unflatten]
15 !! - (64, 32, 32) -> (64, 1024) [spatial to sequence]
16 !! - (100, 50) -> (10, 10, 50) [add spatial dimension]
17 !!
18 !! Properties:
19 !! - No learnable parameters (pure reshape operation)
20 !! - Preserves all information (bijective mapping)
21 !! - No computation beyond memory reorganisation
22 !! - Gradients flow unchanged (chain rule applies directly)
23 use coreutils, only: real32, stop_program
24 use athena__base_layer, only: base_layer_type
25 use diffstruc, only: array_type, reshape
26 use athena__misc_types, only: &
27 onnx_node_type, onnx_initialiser_type, onnx_tensor_type
28 implicit none
29
30
31 private
32
33 public :: reshape_layer_type
34 public :: read_reshape_layer, create_from_onnx_reshape_layer
35
36
37 type, extends(base_layer_type) :: reshape_layer_type
38 !! Type for reshape layer with overloaded procedures
39 contains
40 procedure, pass(this) :: set_hyperparams => set_hyperparams_reshape
41 !! Set hyperparameters for reshape layer
42 procedure, pass(this) :: init => init_reshape
43 !! Initialise reshape layer
44 procedure, pass(this) :: print_to_unit => print_to_unit_reshape
45 !! Print reshape layer to unit
46 procedure, pass(this) :: read => read_reshape
47 !! Read reshape layer from file
48 procedure, pass(this) :: build_from_onnx => build_from_onnx_reshape
49 !! Build reshape layer from ONNX node and initialisers
50
51 procedure, pass(this) :: forward => forward_reshape
52 !! Forward propagation derived type handler
53
54 end type reshape_layer_type
55
56 interface reshape_layer_type
57 !! Interface for setting up the reshape layer
58 module function layer_setup( &
59 output_shape, input_shape, verbose &
60 ) result(layer)
61 !! Set up the reshape layer
62 integer, dimension(:), intent(in) :: output_shape
63 !! Target output shape (excluding batch dimension)
64 integer, dimension(:), optional, intent(in) :: input_shape
65 !! Input shape (excluding batch dimension)
66 integer, optional, intent(in) :: verbose
67 !! Verbosity level
68 type(reshape_layer_type) :: layer
69 !! Instance of the reshape layer
70 end function layer_setup
71 end interface reshape_layer_type
72
73
74
75 contains
76
77 !###############################################################################
78 8 module function layer_setup( &
79
4/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
8 output_shape, input_shape, verbose &
80 8 ) result(layer)
81 !! Set up the reshape layer
82 implicit none
83
84 ! Arguments
85 integer, dimension(:), intent(in) :: output_shape
86 !! Target output shape (excluding batch dimension)
87 integer, dimension(:), optional, intent(in) :: input_shape
88 !! Input shape (excluding batch dimension)
89 integer, optional, intent(in) :: verbose
90 !! Verbosity level
91
92 type(reshape_layer_type) :: layer
93 !! Instance of the reshape layer
94
95 ! Local variables
96 integer :: verbose_ = 0
97 !! Verbosity level
98
99
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 if(present(verbose)) verbose_ = verbose
100
101
102 !---------------------------------------------------------------------------
103 ! Set hyperparameters
104 !---------------------------------------------------------------------------
105
3/6
✗ 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.
8 call layer%set_hyperparams(output_shape, verbose_)
106
107
108 !---------------------------------------------------------------------------
109 ! Initialise layer
110 !---------------------------------------------------------------------------
111
6/10
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 6 times.
8 if(present(input_shape)) call layer%init(input_shape, verbose_)
112
113
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
16 end function layer_setup
114 !###############################################################################
115
116
117 !###############################################################################
118
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 subroutine set_hyperparams_reshape(this, output_shape, verbose)
119 !! Set hyperparameters for reshape layer
120 implicit none
121
122 ! Arguments
123 class(reshape_layer_type), intent(inout) :: this
124 !! Instance of the reshape layer
125 integer, dimension(:), intent(in) :: output_shape
126 !! Output rank
127 integer, optional, intent(in) :: verbose
128 !! Verbosity level
129
130 ! Local variables
131 integer :: verbose_ = 0
132 !! Verbosity level
133
134
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(present(verbose)) verbose_ = verbose
135
136 10 this%type = "rshp"
137
5/8
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 10 times.
10 this%name = "reshape"
138 10 this%input_rank = 0
139
10/14
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 10 times.
✓ Branch 9 taken 2 times.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✓ Branch 13 taken 8 times.
✓ Branch 14 taken 2 times.
✓ Branch 15 taken 16 times.
✓ Branch 16 taken 10 times.
26 this%output_shape = output_shape
140
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 10 times.
10 this%output_rank = size(output_shape)
141
142
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(verbose_ .gt. 0) write(*,'(" Setting up reshape layer")')
143
144 10 end subroutine set_hyperparams_reshape
145 !###############################################################################
146
147
148 !###############################################################################
149
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 subroutine init_reshape(this, input_shape, verbose)
150 !! Initialise reshape layer
151 implicit none
152
153 ! Arguments
154 class(reshape_layer_type), intent(inout) :: this
155 !! Instance of the reshape layer
156 integer, dimension(:), intent(in) :: input_shape
157 !! Input shape
158 integer, optional, intent(in) :: verbose
159 !! Verbosity level
160
161 ! Local variables
162 integer :: verbose_ = 0
163 !! Verbosity level
164 integer :: input_size, output_size
165 !! Total number of elements
166 integer :: i
167 !! Loop index
168
169
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 if(present(verbose)) verbose_ = verbose
170
171 !---------------------------------------------------------------------------
172 ! Set input shape
173 !---------------------------------------------------------------------------
174
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 7 times.
7 this%input_rank = size(input_shape)
175
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
7 if(allocated(this%input_shape)) deallocate(this%input_shape)
176
20/38
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 7 times.
✓ Branch 9 taken 7 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 7 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 7 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 7 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 7 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 7 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 7 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 7 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 7 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 7 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 7 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 7 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 7 times.
✗ Branch 44 not taken.
✓ Branch 45 taken 7 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 7 times.
✓ Branch 50 taken 17 times.
✓ Branch 51 taken 7 times.
24 allocate(this%input_shape, source=input_shape)
177
178
179 !---------------------------------------------------------------------------
180 ! Validate reshape compatibility
181 !---------------------------------------------------------------------------
182
5/8
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 7 times.
✓ Branch 9 taken 17 times.
✓ Branch 10 taken 7 times.
24 input_size = product(input_shape)
183
184
6/10
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 7 times.
✓ Branch 12 taken 12 times.
✓ Branch 13 taken 7 times.
19 output_size = product(this%output_shape)
185
186
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 if(input_size .ne. output_size)then
187 1 write(*,'("ERROR: Reshape layer - incompatible shapes")')
188 1 write(*,'(" Input shape has ",I0," elements")') input_size
189 1 write(*,'(" Output shape has ",I0," elements")') output_size
190 1 call stop_program("Reshape layer shape mismatch")
191 end if
192
193
194 !---------------------------------------------------------------------------
195 ! Print layer info
196 !---------------------------------------------------------------------------
197
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if(verbose_ .gt. 0)then
198 write(*,'(" Reshape layer initialised")')
199 write(*,'(" Input shape: ",*(I0," x "))') this%input_shape
200 write(*,'(" Output shape: ",*(I0," x "))') this%output_shape
201 end if
202
203 7 end subroutine init_reshape
204 !###############################################################################
205
206
207 !##############################################################################!
208 ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !
209 !##############################################################################!
210
211
212 !###############################################################################
213 1 subroutine print_to_unit_reshape(this, unit)
214 !! Print reshape layer to unit
215 implicit none
216
217 ! Arguments
218 class(reshape_layer_type), intent(in) :: this
219 !! Instance of the reshape layer
220 integer, intent(in) :: unit
221 !! File unit
222
223 ! Local variables
224 character(100) :: fmt
225 !! Format string
226
227
228 ! Write initial parameters
229 !---------------------------------------------------------------------------
230 1 write(unit,'(3X,"INPUT_RANK = ",I0)') this%input_rank
231 1 write(fmt,'("(3X,""INPUT_SHAPE ="",",I0,"(1X,I0))")') size(this%input_shape)
232 1 write(unit,fmt) this%input_shape
233 1 write(fmt,'("(3X,""OUTPUT_SHAPE ="",",I0,"(1X,I0))")') size(this%output_shape)
234 1 write(unit,fmt) this%output_shape
235
236 1 end subroutine print_to_unit_reshape
237 !###############################################################################
238
239
240 !###############################################################################
241 1 subroutine read_reshape(this, unit, verbose)
242 !! Read reshape layer from file
243 use athena__tools_infile, only: assign_val, assign_vec, get_val
244 use coreutils, only: to_lower, to_upper, icount
245 implicit none
246
247 ! Arguments
248 class(reshape_layer_type), intent(inout) :: this
249 !! Instance of the reshape layer
250 integer, intent(in) :: unit
251 !! File unit
252 integer, optional, intent(in) :: verbose
253 !! Verbosity level
254
255 ! Local variables
256 integer :: stat, verbose_ = 0
257 !! File status and verbosity level
258 integer :: itmp1 = 0
259 !! Temporary integer
260 integer :: input_rank = 0
261 !! Input rank
262 1 integer, dimension(:), allocatable :: input_shape, output_shape
263 !! Input shape
264 character(256) :: buffer, tag, err_msg
265 !! Buffer, tag, and error message
266 character(256) :: value_str
267 !! Temporary scalar value buffer
268
269
270 ! Initialise optional arguments
271 !---------------------------------------------------------------------------
272
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(present(verbose)) verbose_ = verbose
273
274
275 ! Loop over tags in layer card
276 !---------------------------------------------------------------------------
277 3 tag_loop: do
278
279 ! Check for end of file
280 !------------------------------------------------------------------------
281 4 read(unit,'(A)',iostat=stat) buffer
282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(stat.ne.0)then
283 write(err_msg,'("file encountered error (EoF?) before END ",A)') &
284 to_upper(this%name)
285 call stop_program(err_msg)
286 return
287 end if
288
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
289
290 ! Check for end of layer card
291 !------------------------------------------------------------------------
292
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
293 1 backspace(unit)
294 4 exit tag_loop
295 end if
296
297
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))
298
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))
299
300 ! Read parameters from save file
301 !------------------------------------------------------------------------
302 6 select case(trim(tag))
303 case("INPUT_RANK")
304
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 value_str = get_val(buffer)
305 1 read(value_str, *) input_rank
306 case("INPUT_SHAPE")
307 1 itmp1 = icount(get_val(buffer))
308
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)
309 1 call assign_vec(buffer, input_shape, itmp1)
310 case("OUTPUT_SHAPE")
311 1 itmp1 = icount(get_val(buffer))
312
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(output_shape(itmp1), source=0)
313 1 call assign_vec(buffer, output_shape, itmp1)
314 case default
315 ! Don't look for "e" due to scientific notation of numbers
316 ! ... i.e. exponent (E+00)
317 if( &
318 scan( &
319 to_lower(trim(adjustl(buffer))), &
320 'abcdfghijklmnopqrstuvwxyz' &
321 ) .eq. 0 &
322 )then
323 cycle tag_loop
324 elseif(tag(:3).eq.'END')then
325 cycle tag_loop
326 end if
327 write(err_msg,'("Unrecognised line in input file: ",A)') &
328 trim(adjustl(buffer))
329 call stop_program(err_msg)
330
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
331 end select
332 end do tag_loop
333
334
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(.not.allocated(output_shape))then
335 call stop_program('("Reshape layer missing OUTPUT_SHAPE")')
336 return
337 end if
338
339
340 ! Set hyperparameters and initialise layer
341 !---------------------------------------------------------------------------
342 1 call this%set_hyperparams(output_shape = output_shape, verbose = verbose_)
343 1 call this%init(input_shape = input_shape)
344
345
346 ! Check for end of layer card
347 !---------------------------------------------------------------------------
348 1 read(unit,'(A)') buffer
349
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
350 write(0,*) trim(adjustl(buffer))
351 write(err_msg,'("END ",A," not where expected")') to_upper(this%name)
352 call stop_program(err_msg)
353 1 return
354 end if
355
356
357
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 end subroutine read_reshape
358 !###############################################################################
359
360
361 !###############################################################################
362 1 function read_reshape_layer(unit, verbose) result(layer)
363 !! Read reshape layer from file
364 implicit none
365
366 ! Arguments
367 integer, intent(in) :: unit
368 !! File unit
369 integer, intent(in), optional :: verbose
370 !! Verbosity level
371 class(base_layer_type), allocatable :: layer
372 !! Instance of the reshape layer
373
374 ! Local variables
375 integer :: verbose_ = 0
376 !! Verbosity level
377
378
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(present(verbose)) verbose_ = verbose
379
8/52
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✓ Branch 48 taken 1 times.
✗ Branch 50 not taken.
✓ Branch 51 taken 1 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 1 times.
✓ Branch 54 taken 1 times.
✗ Branch 55 not taken.
2 allocate(layer, source=reshape_layer_type(output_shape=[0]))
380 1 call layer%read(unit, verbose=verbose_)
381
382 2 end function read_reshape_layer
383 !###############################################################################
384
385
386 !###############################################################################
387
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 subroutine build_from_onnx_reshape(this, node, initialisers, value_info, verbose)
388 !! Build reshape layer from ONNX node and initialiser
389 implicit none
390
391 ! Arguments
392 class(reshape_layer_type), intent(inout) :: this
393 !! Instance of the reshape layer
394 type(onnx_node_type), intent(in) :: node
395 !! ONNX node
396 type(onnx_initialiser_type), dimension(:), intent(in) :: initialisers
397 !! ONNX initialisers
398 type(onnx_tensor_type), dimension(:), intent(in) :: value_info
399 !! ONNX value infos
400 integer, intent(in) :: verbose
401 !! Verbosity level
402
403 ! Local variables
404 1 integer, dimension(:), allocatable :: output_shape
405 !! Output shape
406
407 ! Check size of initialisers is zero or one (shape can be an initialiser)
408
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 if(size(initialisers).gt.1)then
409 write(0,*) "WARNING: Multiple initialisers found for ONNX RESHAPE layer"
410 end if
411
412 ! Extract output shape from value_info (excluding batch dimension)
413
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 if(allocated(value_info(1)%dims))then
414
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 if(size(value_info(1)%dims).gt.1)then
415
10/20
✓ 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 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 2 times.
✓ Branch 24 taken 1 times.
3 output_shape = value_info(1)%dims(2:)
416 else
417 allocate(output_shape(1))
418 output_shape(1) = value_info(1)%dims(1)
419 end if
420 else
421 call stop_program("ONNX RESHAPE layer requires output shape in value_info")
422 return
423 end if
424
425 call this%set_hyperparams( &
426 output_shape = output_shape, &
427 verbose = verbose &
428 1 )
429
430
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 end subroutine build_from_onnx_reshape
431 !###############################################################################
432
433
434 !###############################################################################
435 1 function create_from_onnx_reshape_layer( &
436
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 node, initialisers, value_info, verbose &
437 1 ) result(layer)
438 !! Build reshape layer from ONNX node and initialiser
439 implicit none
440
441 ! Arguments
442 type(onnx_node_type), intent(in) :: node
443 !! ONNX node
444 type(onnx_initialiser_type), dimension(:), intent(in) :: initialisers
445 !! ONNX initialisers
446 type(onnx_tensor_type), dimension(:), intent(in) :: value_info
447 !! ONNX value infos
448 integer, intent(in), optional :: verbose
449 !! Verbosity level
450 class(base_layer_type), allocatable :: layer
451 !! Instance of the reshape layer
452
453 ! Local variables
454 integer :: verbose_ = 0
455 !! Verbosity level
456
457
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(present(verbose)) verbose_ = verbose
458
8/52
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✓ Branch 48 taken 1 times.
✗ Branch 50 not taken.
✓ Branch 51 taken 1 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 1 times.
✓ Branch 54 taken 1 times.
✗ Branch 55 not taken.
2 allocate(layer, source=reshape_layer_type(output_shape=[0]))
459
6/12
✗ 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.
1 call layer%build_from_onnx(node, initialisers, value_info, verbose=verbose_)
460
461 2 end function create_from_onnx_reshape_layer
462 !###############################################################################
463
464
465 !##############################################################################!
466 ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !
467 !##############################################################################!
468
469
470 !###############################################################################
471
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 subroutine forward_reshape(this, input)
472 !! Forward propagation derived type handler
473 implicit none
474
475 ! Arguments
476 class(reshape_layer_type), intent(inout) :: this
477 !! Instance of the reshape layer
478 class(array_type), dimension(:,:), intent(in) :: input
479 !! Input array
480
481 type(array_type), pointer :: ptr => null()
482
483 ! Reshape input
484 !---------------------------------------------------------------------------
485
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(1,1)%zero_grad()
486
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 ptr => reshape(input(1,1), this%output_shape)
487
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(1,1)%assign_and_deallocate_source(ptr)
488
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 this%output(1,1)%is_temporary = .false.
489
490 1 end subroutine forward_reshape
491 !###############################################################################
492
493
25/119
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 4 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 not taken.
✓ Branch 37 taken 4 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 44 not taken.
✓ Branch 45 taken 4 times.
✓ Branch 46 taken 4 times.
✓ Branch 47 taken 1 times.
✓ Branch 48 taken 7 times.
✓ Branch 49 taken 4 times.
✗ 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 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 4 times.
✗ Branch 110 not taken.
✓ Branch 111 taken 4 times.
✗ Branch 112 not taken.
✓ Branch 113 taken 4 times.
✗ Branch 114 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✓ Branch 118 taken 4 times.
✗ Branch 119 not taken.
✓ Branch 120 taken 2 times.
✓ Branch 121 taken 2 times.
✓ Branch 122 taken 4 times.
✗ Branch 123 not taken.
✗ Branch 124 not taken.
✓ Branch 125 taken 4 times.
24 end module athena__reshape_layer
494