GCC Code Coverage Report


Directory: src/athena/
File: src/athena/athena_maxpool2d_layer.f90
Date: 2026-04-15 16:08:59
Exec Total Coverage
Lines: 94 114 82.5%
Functions: 0 0 -%
Branches: 231 643 35.9%

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