GCC Code Coverage Report


Directory: src/athena/
File: src/athena/athena_avgpool2d_layer.f90
Date: 2026-04-15 16:08:59
Exec Total Coverage
Lines: 80 116 69.0%
Functions: 0 0 -%
Branches: 212 647 32.8%

Line Branch Exec Source
1 module athena__avgpool2d_layer
2 !! Module containing implementation of a 2D average pooling layer
3 !!
4 !! This module implements 2D average pooling for downsampling by computing
5 !! mean values within pooling windows.
6 !!
7 !! Mathematical operation:
8 !! output[i,j,k] = (1/N) Σ_{m,n} input[i*stride+m, j*stride+n, k]
9 !!
10 !! where:
11 !! (i,j) are output spatial coordinates
12 !! k is the channel index
13 !! N = pool_h * pool_w is the window size
14 !! (m,n) iterate over the pooling window
15 !!
16 !! Provides smooth downsampling by averaging.
17 !! Shape: (width, height, channels) -> (width//stride, height//stride, channels)
18 use coreutils, only: real32, stop_program
19 use athena__base_layer, only: pool_layer_type, base_layer_type
20 use athena__pad2d_layer, only: pad2d_layer_type
21 use diffstruc, only: array_type
22 use athena__misc_types, only: &
23 onnx_node_type, onnx_initialiser_type, onnx_tensor_type
24 use athena__diffstruc_extd, only: avgpool2d
25 implicit none
26
27
28 private
29
30 public :: avgpool2d_layer_type
31 public :: read_avgpool2d_layer
32
33
34 type, extends(pool_layer_type) :: avgpool2d_layer_type
35 !! Type for 2D average pooling layer with overloaded procedures
36 contains
37 procedure, pass(this) :: set_hyperparams => set_hyperparams_avgpool2d
38 !! Set hyperparameters for 2D average pooling layer
39 procedure, pass(this) :: read => read_avgpool2d
40 !! Read 2D average pooling layer from file
41
42 procedure, pass(this) :: forward => forward_avgpool2d
43 !! Forward propagation derived type handler
44
45 end type avgpool2d_layer_type
46
47 interface avgpool2d_layer_type
48 !! Interface for setting up the 2D average pooling layer
49 module function layer_setup( input_shape, &
50 pool_size, stride, padding, verbose ) result(layer)
51 !! Set up the 2D average pooling layer
52 integer, dimension(:), optional, intent(in) :: input_shape
53 !! Input shape
54 integer, dimension(..), optional, intent(in) :: pool_size
55 !! Pool size
56 integer, dimension(..), optional, intent(in) :: stride
57 !! Stride
58 character(*), optional, intent(in) :: padding
59 !! Padding
60 integer, optional, intent(in) :: verbose
61 !! Verbosity level
62 type(avgpool2d_layer_type) :: layer
63 !! Instance of the 2D average pooling layer
64 end function layer_setup
65 end interface avgpool2d_layer_type
66
67
68
69 contains
70
71 !###############################################################################
72 7 module function layer_setup( &
73
0/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
7 input_shape, &
74 7 pool_size, stride, padding, verbose) result(layer)
75 !! Set up the 2D average pooling layer
76 implicit none
77
78 ! Arguments
79 integer, dimension(:), optional, intent(in) :: input_shape
80 !! Input shape
81 integer, dimension(..), optional, intent(in) :: pool_size
82 !! Pool size
83 integer, dimension(..), optional, intent(in) :: stride
84 !! Stride
85 character(*), optional, intent(in) :: padding
86 !! Padding
87 integer, optional, intent(in) :: verbose
88 !! Verbosity level
89
90 type(avgpool2d_layer_type) :: layer
91 !! Instance of the 2D average pooling layer
92
93 ! Local variables
94 integer :: verbose_ = 0
95 !! Verbosity level
96 integer, dimension(2) :: pool_size_, stride_
97 !! Pool size and stride
98 character(len=20) :: padding_
99 !! Padding
100
101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if(present(verbose)) verbose_ = verbose
102
103 !---------------------------------------------------------------------------
104 ! Set up pool size
105 !---------------------------------------------------------------------------
106
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
7 if(present(pool_size))then
107 6 select rank(pool_size)
108 rank(0)
109
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 pool_size_ = pool_size
110 rank(1)
111
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 pool_size_(1) = pool_size(1)
112
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 3 times.
8 if(size(pool_size,dim=1).eq.1)then
113
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 pool_size_(2) = pool_size(1)
114
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 elseif(size(pool_size,dim=1).eq.2)then
115
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
3 pool_size_(2) = pool_size(2)
116 end if
117 end select
118 else
119
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 pool_size_ = 2
120 end if
121
122
123 !---------------------------------------------------------------------------
124 ! Set up stride
125 !---------------------------------------------------------------------------
126
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
7 if(present(stride))then
127 6 select rank(stride)
128 rank(0)
129
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 stride_ = stride
130 rank(1)
131
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 stride_(1) = stride(1)
132
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 3 times.
8 if(size(stride,dim=1).eq.1)then
133
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 stride_(2) = stride(1)
134
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 elseif(size(stride,dim=1).eq.2)then
135
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
3 stride_(2) = stride(2)
136 end if
137 end select
138 else
139
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 stride_ = 2
140 end if
141
142
143 !---------------------------------------------------------------------------
144 ! Set up padding
145 !---------------------------------------------------------------------------
146
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
7 if(present(padding))then
147
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 padding_ = padding
148 else
149 5 padding_ = "valid"
150 end if
151
152
153 !---------------------------------------------------------------------------
154 ! Set hyperparameters
155 !---------------------------------------------------------------------------
156 call layer%set_hyperparams( &
157 pool_size=pool_size_, stride=stride_, &
158 padding=padding_, verbose=verbose_ &
159 7 )
160
161
162 !---------------------------------------------------------------------------
163 ! Initialise layer shape
164 !---------------------------------------------------------------------------
165
1/10
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
7 if(present(input_shape)) call layer%init(input_shape=input_shape)
166
167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
14 end function layer_setup
168 !###############################################################################
169
170
171 !###############################################################################
172 8 subroutine set_hyperparams_avgpool2d( &
173 this, pool_size, stride, padding, verbose &
174 )
175 !! Set hyperparameters for 2D average pooling layer
176 use coreutils, only: to_lower
177 implicit none
178
179 ! Arguments
180 class(avgpool2d_layer_type), intent(inout) :: this
181 !! Instance of the 2D average pooling layer
182 integer, dimension(2), intent(in) :: pool_size
183 !! Pool size
184 integer, dimension(2), intent(in) :: stride
185 !! Stride
186 character(*), optional, intent(in) :: padding
187 !! Padding
188 integer, optional, intent(in) :: verbose
189 !! Verbosity level
190
191 ! Local variables
192 character(len=20) :: padding_
193
194
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
8 this%name = "avgpool2d"
195 8 this%type = "pool"
196 8 this%subtype = "avg"
197 8 this%input_rank = 3
198 8 this%output_rank = 3
199
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
8 if(allocated(this%pool)) deallocate(this%pool)
200
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
8 if(allocated(this%strd)) deallocate(this%strd)
201 allocate( &
202 this%pool(this%input_rank-1), &
203 this%strd(this%input_rank-1) &
204
16/32
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✗ 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 13 not taken.
✓ Branch 14 taken 8 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 8 times.
✓ Branch 18 taken 8 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 8 times.
✗ Branch 21 not taken.
✗ 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 33 not taken.
✓ Branch 34 taken 8 times.
8 )
205
4/8
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 8 times.
32 this%pool = pool_size
206
4/8
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 8 times.
32 this%strd = stride
207
208 ! Handle padding
209
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 if(present(padding))then
210
2/4
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
7 padding_ = trim(adjustl(padding))
211 else
212 1 padding_ = "valid"
213 end if
214
215 23 select case(trim(adjustl(to_lower(padding_))))
216 case("valid", "none", "")
217 case default
218 this%pad_layer = pad2d_layer_type( &
219 4 padding = [ (this%pool-1)/2 ], &
220 method = padding_ &
221
32/96
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ 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 2 times.
✓ Branch 26 taken 1 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 1 times.
✓ Branch 29 taken 2 times.
✓ Branch 30 taken 1 times.
✓ Branch 32 taken 1 times.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✓ Branch 35 taken 1 times.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✓ Branch 40 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✓ Branch 43 taken 1 times.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ 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 taken 1 times.
✗ Branch 83 not taken.
✓ Branch 84 taken 1 times.
✗ Branch 85 not taken.
✓ Branch 86 taken 1 times.
✗ Branch 87 not taken.
✓ Branch 88 taken 1 times.
✓ Branch 89 taken 1 times.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✓ Branch 92 taken 1 times.
✗ Branch 93 not taken.
✓ Branch 94 taken 1 times.
✓ Branch 95 taken 1 times.
✗ Branch 96 not taken.
✓ Branch 97 taken 1 times.
✗ Branch 98 not taken.
✓ Branch 99 taken 2 times.
✓ Branch 100 taken 1 times.
✗ Branch 101 not taken.
✓ Branch 102 taken 2 times.
✗ Branch 103 not taken.
✓ Branch 104 taken 2 times.
✗ Branch 105 not taken.
✓ Branch 106 taken 2 times.
31 )
222 end select
223
224
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 end subroutine set_hyperparams_avgpool2d
225 !###############################################################################
226
227
228 !##############################################################################!
229 ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !
230 !##############################################################################!
231
232
233 !###############################################################################
234 1 subroutine read_avgpool2d(this, unit, verbose)
235 !! Read 2D average pooling layer from file
236 use athena__tools_infile, only: assign_val, assign_vec
237 use coreutils, only: to_lower, to_upper, icount
238 implicit none
239
240 ! Arguments
241 class(avgpool2d_layer_type), intent(inout) :: this
242 !! Instance of the 2D average pooling layer
243 integer, intent(in) :: unit
244 !! File unit
245 integer, optional, intent(in) :: verbose
246 !! Verbosity level
247
248 ! Local variables
249 integer :: verbose_ = 0
250 !! Verbosity level
251 integer :: stat
252 !! File status
253 integer :: itmp1
254 !! Temporary integer
255 integer, dimension(2) :: pool_size, stride
256 !! Pool size and stride
257 integer, dimension(3) :: input_shape
258 !! Input shape
259 character(256) :: buffer, tag, err_msg
260 !! Buffer for reading lines, tag for identifying lines, error message
261
262
263 ! Initialise optional arguments
264 !---------------------------------------------------------------------------
265
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(present(verbose)) verbose_ = verbose
266
267
268 ! Loop over tags in layer card
269 !---------------------------------------------------------------------------
270 3 tag_loop: do
271
272 ! Check for end of file
273 !------------------------------------------------------------------------
274 4 read(unit,'(A)',iostat=stat) buffer
275
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(stat.ne.0)then
276 write(err_msg,'("file encountered error (EoF?) before END ",A)') &
277 to_upper(this%name)
278 call stop_program(err_msg)
279 return
280 end if
281
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
282
283 ! Check for end of layer card
284 !------------------------------------------------------------------------
285
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
286 1 backspace(unit)
287 4 exit tag_loop
288 end if
289
290
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))
291
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))
292
293 ! Read parameters from save file
294 !------------------------------------------------------------------------
295 6 select case(trim(tag))
296 case("INPUT_SHAPE")
297 1 call assign_vec(buffer, input_shape, itmp1)
298 case("POOL_SIZE")
299 1 call assign_vec(buffer, pool_size, itmp1)
300 case("STRIDE")
301 1 call assign_vec(buffer, stride, itmp1)
302 case default
303 ! Don't look for "e" due to scientific notation of numbers
304 ! ... i.e. exponent (E+00)
305 if(scan(to_lower(trim(adjustl(buffer))),&
306 'abcdfghijklmnopqrstuvwxyz').eq.0)then
307 cycle tag_loop
308 elseif(tag(:3).eq.'END')then
309 cycle tag_loop
310 end if
311 write(err_msg,'("Unrecognised line in input file: ",A)') &
312 trim(adjustl(buffer))
313 call stop_program(err_msg)
314
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
315 end select
316 end do tag_loop
317
318 ! Set hyperparameters and initialise layer
319 !---------------------------------------------------------------------------
320 1 call this%set_hyperparams(pool_size=pool_size, stride=stride)
321 1 call this%init(input_shape = input_shape)
322
323
324 ! Check for end of layer card
325 !---------------------------------------------------------------------------
326 1 read(unit,'(A)') buffer
327
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
328 write(0,*) trim(adjustl(buffer))
329 write(err_msg,'("END ",A," not where expected")') to_upper(this%name)
330 call stop_program(err_msg)
331 1 return
332 end if
333
334 end subroutine read_avgpool2d
335 !###############################################################################
336
337
338 !###############################################################################
339 1 function read_avgpool2d_layer(unit, verbose) result(layer)
340 !! Read 2D average pooling layer from file and return layer
341 implicit none
342
343 ! Arguments
344 integer, intent(in) :: unit
345 !! File unit
346 integer, optional, intent(in) :: verbose
347 !! Verbosity level
348 class(base_layer_type), allocatable :: layer
349 !! Instance of the 2D average pooling layer
350
351 ! Local variables
352 integer :: verbose_ = 0
353 !! Verbosity level
354
355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(present(verbose)) verbose_ = verbose
356
12/128
✗ 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 not taken.
✓ Branch 55 taken 1 times.
✓ Branch 56 taken 1 times.
✗ Branch 57 not taken.
✓ Branch 58 taken 1 times.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✓ Branch 61 taken 1 times.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 65 not taken.
✓ Branch 66 taken 1 times.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ 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 110 not taken.
✗ Branch 111 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✗ Branch 117 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✗ Branch 120 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✗ Branch 124 not taken.
✗ Branch 125 not taken.
✗ Branch 126 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 129 not taken.
✗ Branch 130 not taken.
✗ Branch 131 not taken.
✗ Branch 132 not taken.
✗ Branch 133 not taken.
2 allocate(layer, source=avgpool2d_layer_type())
357 1 call layer%read(unit, verbose=verbose_)
358
359 2 end function read_avgpool2d_layer
360 !###############################################################################
361
362
363 !###############################################################################
364 subroutine build_from_onnx_avgpool2d( &
365 this, node, initialisers, value_info, verbose &
366 )
367 !! Read ONNX attributes for 2D average pooling layer
368 implicit none
369
370 ! Arguments
371 class(avgpool2d_layer_type), intent(inout) :: this
372 !! Instance of the 2D average pooling layer
373 type(onnx_node_type), intent(in) :: node
374 !! ONNX node information
375 type(onnx_initialiser_type), dimension(:), intent(in) :: initialisers
376 !! ONNX initialiser information
377 type(onnx_tensor_type), dimension(:), intent(in) :: value_info
378 !! ONNX value info
379 integer, intent(in) :: verbose
380 !! Verbosity level
381
382 ! Local variables
383 integer :: i
384 !! Loop index
385 integer, dimension(2) :: stride, pool_size, padding
386 !! Stride, kernel size, and padding
387 character(256) :: val
388 !! Attribute value
389 character(20) :: padding_method
390 !! Padding method
391
392 ! Set default values
393 stride = 1
394 pool_size = 2
395 padding = 0
396
397 do i = 1, size(node%attributes)
398 val = node%attributes(i)%val
399 select case(trim(adjustl(node%attributes(i)%name)))
400 case("kernel_shape")
401 read(val,*) pool_size
402 case("strides")
403 read(val,*) stride
404 case("pads")
405 read(val,*) padding
406 case default
407 ! Do nothing
408 write(0,*) "WARNING: Unrecognised attribute in ONNX AVGPOOL2D ", &
409 "layer: ", trim(adjustl(node%attributes(i)%name))
410 end select
411 end do
412
413 ! Check size of initialisers is zero
414 if(size(initialisers).ne.0)then
415 write(0,*) "WARNING: initialisers not used for ONNX AVGPOOL2D layer"
416 end if
417
418 ! Convert integer padding to character method
419 if(any(padding.gt.0))then
420 padding_method = "constant"
421 else
422 padding_method = "valid"
423 end if
424
425 call this%set_hyperparams( &
426 stride = stride, &
427 pool_size = pool_size, &
428 padding = padding_method &
429 )
430
431 end subroutine build_from_onnx_avgpool2d
432 !###############################################################################
433
434
435 !##############################################################################!
436 ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !
437 !##############################################################################!
438
439
440 !###############################################################################
441
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 subroutine forward_avgpool2d(this, input)
442 !! Forward propagation
443 implicit none
444
445 ! Arguments
446 class(avgpool2d_layer_type), intent(inout) :: this
447 !! Instance of the 2D average pooling layer
448 class(array_type), dimension(:,:), intent(in) :: input
449 !! Input values
450
451 ! Local variables
452 type(array_type), pointer :: ptr
453 !! Pointer array
454
455
456
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
2 call this%output(1,1)%zero_grad()
457 2 select case(allocated(this%pad_layer))
458 case(.true.)
459 call this%pad_layer%forward(input)
460 ptr => avgpool2d(this%pad_layer%output(1,1), this%pool, this%strd)
461 case default
462
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
2 ptr => avgpool2d(input(1,1), this%pool, this%strd)
463 end select
464
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
2 call this%output(1,1)%assign_and_deallocate_source(ptr)
465
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
2 this%output(1,1)%is_temporary = .false.
466
467 2 end subroutine forward_avgpool2d
468 !###############################################################################
469
470
52/135
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 12 times.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 2 times.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✓ Branch 13 taken 4 times.
✓ Branch 14 taken 4 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✓ Branch 36 taken 1 times.
✓ Branch 37 taken 7 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 1 times.
✓ Branch 40 taken 6 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 1 times.
✓ Branch 43 taken 6 times.
✓ Branch 44 taken 1 times.
✓ Branch 45 taken 7 times.
✓ Branch 46 taken 6 times.
✓ Branch 47 taken 1 times.
✓ Branch 48 taken 13 times.
✓ Branch 49 taken 1 times.
✓ Branch 50 taken 7 times.
✓ Branch 51 taken 8 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 8 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 1 times.
✓ Branch 56 taken 7 times.
✗ 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 6 times.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✓ Branch 70 taken 6 times.
✓ Branch 71 taken 6 times.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✓ Branch 74 taken 6 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 6 times.
✗ Branch 110 not taken.
✓ Branch 111 taken 6 times.
✗ Branch 112 not taken.
✓ Branch 113 taken 4 times.
✓ Branch 114 taken 2 times.
✓ Branch 115 taken 2 times.
✗ Branch 116 not taken.
✓ Branch 118 taken 6 times.
✗ Branch 119 not taken.
✓ Branch 120 taken 4 times.
✓ Branch 121 taken 2 times.
✓ Branch 122 taken 6 times.
✗ Branch 123 not taken.
✓ Branch 124 taken 4 times.
✓ Branch 125 taken 2 times.
✓ Branch 126 taken 6 times.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✓ Branch 129 taken 6 times.
✓ Branch 130 taken 6 times.
✗ Branch 131 not taken.
✗ Branch 132 not taken.
✓ Branch 133 taken 6 times.
✓ Branch 134 taken 6 times.
✗ Branch 135 not taken.
✓ Branch 136 taken 5 times.
✓ Branch 137 taken 1 times.
✓ Branch 138 taken 1 times.
✗ Branch 139 not taken.
56 end module athena__avgpool2d_layer
471