GCC Code Coverage Report


Directory: src/lib/
File: src/lib/mod_avgpool2d_layer.f90
Date: 2024-06-28 12:51:18
Exec Total Coverage
Lines: 91 136 66.9%
Functions: 0 0 -%
Branches: 434 903 48.1%

Line Branch Exec Source
1 !!!#############################################################################
2 !!! Code written by Ned Thaddeus Taylor
3 !!! Code part of the ATHENA library - a feedforward neural network library
4 !!!#############################################################################
5 !!! module contains implementation of a 2D average pooling layer
6 !!!#############################################################################
7 module avgpool2d_layer
8 use constants, only: real12
9 use base_layer, only: pool_layer_type
10 implicit none
11
12
13 type, extends(pool_layer_type) :: avgpool2d_layer_type
14 real(real12), allocatable, dimension(:,:,:,:) :: output
15 real(real12), allocatable, dimension(:,:,:,:) :: di ! gradient of input (i.e. delta)
16 contains
17 procedure, pass(this) :: get_output => get_output_avgpool2d
18 procedure, pass(this) :: init => init_avgpool2d
19 procedure, pass(this) :: set_batch_size => set_batch_size_avgpool2d
20 procedure, pass(this) :: print => print_avgpool2d
21 procedure, pass(this) :: forward => forward_rank
22 procedure, pass(this) :: backward => backward_rank
23 procedure, private, pass(this) :: forward_4d
24 procedure, private, pass(this) :: backward_4d
25 end type avgpool2d_layer_type
26
27
28 interface avgpool2d_layer_type
29 module function layer_setup( &
30 input_shape, batch_size, &
31 pool_size, stride) result(layer)
32 integer, dimension(:), optional, intent(in) :: input_shape
33 integer, optional, intent(in) :: batch_size
34 integer, dimension(..), optional, intent(in) :: pool_size
35 integer, dimension(..), optional, intent(in) :: stride
36 type(avgpool2d_layer_type) :: layer
37 end function layer_setup
38 end interface avgpool2d_layer_type
39
40
41 private
42 public :: avgpool2d_layer_type
43 public :: read_avgpool2d_layer
44
45
46 contains
47
48 !!!#############################################################################
49 !!! get layer outputs
50 !!!#############################################################################
51 4 pure subroutine get_output_avgpool2d(this, output)
52 implicit none
53 class(avgpool2d_layer_type), intent(in) :: this
54 real(real12), allocatable, dimension(..), intent(out) :: output
55
56 select rank(output)
57 rank(1)
58
7/10
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
6 output = reshape(this%output, [size(this%output)])
59 rank(2)
60 output = &
61
11/18
✗ 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 taken 3 times.
✓ Branch 13 taken 1 times.
✓ Branch 14 taken 2 times.
✓ Branch 15 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1 times.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
6 reshape(this%output, [product(this%output_shape),this%batch_size])
62 rank(4)
63
34/68
✗ 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.
✗ Branch 21 not taken.
✓ Branch 22 taken 2 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 2 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 2 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 2 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 2 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 2 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 2 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 2 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 2 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 2 times.
✗ 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 taken 2 times.
✗ Branch 59 not taken.
✓ Branch 60 taken 2 times.
✗ Branch 61 not taken.
✓ Branch 62 taken 2 times.
✗ Branch 63 not taken.
✓ Branch 64 taken 2 times.
✗ Branch 65 not taken.
✓ Branch 66 taken 2 times.
✗ Branch 67 not taken.
✓ Branch 68 taken 2 times.
✗ Branch 69 not taken.
✓ Branch 70 taken 2 times.
✗ Branch 71 not taken.
✓ Branch 72 taken 2 times.
✗ Branch 73 not taken.
✓ Branch 74 taken 2 times.
✗ Branch 75 not taken.
✓ Branch 76 taken 2 times.
✓ Branch 77 taken 2 times.
✓ Branch 78 taken 6 times.
✓ Branch 79 taken 2 times.
✓ Branch 80 taken 18 times.
✓ Branch 81 taken 6 times.
✓ Branch 82 taken 54 times.
✓ Branch 83 taken 18 times.
82 output = this%output
64 end select
65
66 4 end subroutine get_output_avgpool2d
67 !!!#############################################################################
68
69
70 !!!##########################################################################!!!
71 !!! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !!!
72 !!!##########################################################################!!!
73
74
75 !!!#############################################################################
76 !!! forward propagation assumed rank handler
77 !!!#############################################################################
78 2 pure subroutine forward_rank(this, input)
79 implicit none
80 class(avgpool2d_layer_type), intent(inout) :: this
81 real(real12), dimension(..), intent(in) :: input
82
83 select rank(input); rank(4)
84 2 call forward_4d(this, input)
85 end select
86 2 end subroutine forward_rank
87 !!!#############################################################################
88
89
90 !!!#############################################################################
91 !!! backward propagation assumed rank handler
92 !!!#############################################################################
93 1 pure subroutine backward_rank(this, input, gradient)
94 implicit none
95 class(avgpool2d_layer_type), intent(inout) :: this
96 real(real12), dimension(..), intent(in) :: input
97 real(real12), dimension(..), intent(in) :: gradient
98
99 select rank(input); rank(4)
100 1 select rank(gradient); rank(4)
101 1 call backward_4d(this, input, gradient)
102 end select
103 end select
104 1 end subroutine backward_rank
105 !!!#############################################################################
106
107
108 !!!##########################################################################!!!
109 !!! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !!!
110 !!!##########################################################################!!!
111
112
113 !!!#############################################################################
114 !!! set up layer
115 !!!#############################################################################
116 #if defined(GFORTRAN)
117 module function layer_setup( &
118 input_shape, batch_size, &
119 pool_size, stride) result(layer)
120 implicit none
121 integer, dimension(:), optional, intent(in) :: input_shape
122 integer, optional, intent(in) :: batch_size
123 integer, dimension(..), optional, intent(in) :: pool_size
124 integer, dimension(..), optional, intent(in) :: stride
125
126 type(avgpool2d_layer_type) :: layer
127 #else
128
0/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 module procedure layer_setup
129 implicit none
130 #endif
131
132
133
3/8
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
4 layer%name = "avgpool2d"
134 4 layer%input_rank = 3
135 allocate( &
136 layer%pool(layer%input_rank-1), &
137
16/32
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 4 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 4 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 4 times.
✓ Branch 18 taken 4 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 4 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 4 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 4 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 4 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 4 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 4 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 4 times.
4 layer%strd(layer%input_rank-1) )
138 !!-----------------------------------------------------------------------
139 !! set up pool size
140 !!-----------------------------------------------------------------------
141
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(present(pool_size))then
142 4 select rank(pool_size)
143 rank(0)
144
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 layer%pool = pool_size
145 rank(1)
146
3/6
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
2 layer%pool(1) = pool_size(1)
147
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
4 if(size(pool_size,dim=1).eq.1)then
148
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 layer%pool(2) = pool_size(1)
149
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 elseif(size(pool_size,dim=1).eq.2)then
150
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 layer%pool(2) = pool_size(2)
151 end if
152 end select
153 else
154 layer%pool = 2
155 end if
156
157
158 !!-----------------------------------------------------------------------
159 !! set up stride
160 !!-----------------------------------------------------------------------
161
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(present(stride))then
162 4 select rank(stride)
163 rank(0)
164
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 layer%strd = stride
165 rank(1)
166
3/6
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
2 layer%strd(1) = stride(1)
167
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
4 if(size(stride,dim=1).eq.1)then
168
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 layer%strd(2) = stride(1)
169
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 elseif(size(stride,dim=1).eq.2)then
170
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 layer%strd(2) = stride(2)
171 end if
172 end select
173 else
174 layer%strd = 2
175 end if
176
177
178 !!--------------------------------------------------------------------------
179 !! initialise batch size
180 !!--------------------------------------------------------------------------
181
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(present(batch_size)) layer%batch_size = batch_size
182
183
184 !!--------------------------------------------------------------------------
185 !! initialise layer shape
186 !!--------------------------------------------------------------------------
187
1/10
✗ Branch 0 not taken.
✓ Branch 1 taken 4 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.
4 if(present(input_shape)) call layer%init(input_shape=input_shape)
188
189 #if defined(GFORTRAN)
190 end function layer_setup
191 #else
192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
8 end procedure layer_setup
193 #endif
194 !!!#############################################################################
195
196
197 !!!#############################################################################
198 !!! initialise layer
199 !!!#############################################################################
200
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 subroutine init_avgpool2d(this, input_shape, batch_size, verbose)
201 implicit none
202 class(avgpool2d_layer_type), intent(inout) :: this
203 integer, dimension(:), intent(in) :: input_shape
204 integer, optional, intent(in) :: batch_size
205 integer, optional, intent(in) :: verbose
206
207 integer :: verbose_ = 0
208
209
210 !!--------------------------------------------------------------------------
211 !! initialise optional arguments
212 !!--------------------------------------------------------------------------
213
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(present(verbose)) verbose_ = verbose
214
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(present(batch_size)) this%batch_size = batch_size
215
216
217 !!--------------------------------------------------------------------------
218 !! initialise input shape
219 !!--------------------------------------------------------------------------
220
4/8
✓ 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.
1 if(.not.allocated(this%input_shape)) call this%set_shape(input_shape)
221
222
223 !!-----------------------------------------------------------------------
224 !! set up number of channels, width, height
225 !!-----------------------------------------------------------------------
226
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 this%num_channels = this%input_shape(3)
227
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 allocate(this%output_shape(3))
228
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_shape(3) = this%input_shape(3)
229 5 this%output_shape(:2) = &
230
22/42
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 1 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 1 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 1 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 1 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 1 times.
✗ Branch 51 not taken.
✓ Branch 52 taken 1 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 1 times.
✓ Branch 57 taken 2 times.
✓ Branch 58 taken 1 times.
✓ Branch 59 taken 2 times.
✗ Branch 60 not taken.
3 floor( (this%input_shape(:2) - this%pool)/real(this%strd)) + 1
231
232
233 !!--------------------------------------------------------------------------
234 !! initialise batch size-dependent arrays
235 !!--------------------------------------------------------------------------
236
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(this%batch_size.gt.0) call this%set_batch_size(this%batch_size)
237
238 1 end subroutine init_avgpool2d
239 !!!#############################################################################
240
241
242 !!!#############################################################################
243 !!! set batch size
244 !!!#############################################################################
245 1 subroutine set_batch_size_avgpool2d(this, batch_size, verbose)
246 implicit none
247 class(avgpool2d_layer_type), intent(inout) :: this
248 integer, intent(in) :: batch_size
249 integer, optional, intent(in) :: verbose
250
251 integer :: verbose_ = 0
252
253
254 !!--------------------------------------------------------------------------
255 !! initialise optional arguments
256 !!--------------------------------------------------------------------------
257
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(present(verbose)) verbose_ = verbose
258 1 this%batch_size = batch_size
259
260
261 !!--------------------------------------------------------------------------
262 !! allocate arrays
263 !!--------------------------------------------------------------------------
264
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(allocated(this%input_shape))then
265
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if(allocated(this%output)) deallocate(this%output)
266 allocate(this%output( &
267 2 this%output_shape(1), &
268 2 this%output_shape(2), this%num_channels, &
269 this%batch_size), &
270
41/74
✗ Branch 0 not taken.
✓ Branch 1 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 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 1 times.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 1 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 1 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 1 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 40 not taken.
✓ Branch 41 taken 1 times.
✗ Branch 43 not taken.
✓ Branch 44 taken 1 times.
✗ Branch 46 not taken.
✓ Branch 47 taken 1 times.
✗ Branch 49 not taken.
✓ Branch 50 taken 1 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 1 times.
✗ Branch 55 not taken.
✓ Branch 56 taken 1 times.
✗ Branch 58 not taken.
✓ Branch 59 taken 1 times.
✗ Branch 61 not taken.
✓ Branch 62 taken 1 times.
✗ Branch 64 not taken.
✓ Branch 65 taken 1 times.
✗ Branch 67 not taken.
✓ Branch 68 taken 1 times.
✗ Branch 70 not taken.
✓ Branch 71 taken 1 times.
✗ Branch 73 not taken.
✓ Branch 74 taken 1 times.
✗ Branch 76 not taken.
✓ Branch 77 taken 1 times.
✗ Branch 79 not taken.
✓ Branch 80 taken 1 times.
✗ Branch 82 not taken.
✓ Branch 83 taken 1 times.
✗ Branch 85 not taken.
✓ Branch 86 taken 1 times.
✓ Branch 88 taken 1 times.
✓ Branch 89 taken 1 times.
✓ Branch 90 taken 3 times.
✓ Branch 91 taken 1 times.
✓ Branch 92 taken 9 times.
✓ Branch 93 taken 3 times.
✓ Branch 94 taken 27 times.
✓ Branch 95 taken 9 times.
41 source=0._real12)
271
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if(allocated(this%di)) deallocate(this%di)
272 allocate(this%di( &
273 2 this%input_shape(1), &
274 2 this%input_shape(2), &
275 2 this%input_shape(3), &
276 this%batch_size), &
277
43/78
✗ Branch 0 not taken.
✓ Branch 1 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 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 1 times.
✓ Branch 26 taken 1 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✓ Branch 30 taken 1 times.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✓ Branch 33 taken 1 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 1 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 1 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 1 times.
✗ Branch 43 not taken.
✓ Branch 44 taken 1 times.
✗ Branch 46 not taken.
✓ Branch 47 taken 1 times.
✗ Branch 49 not taken.
✓ Branch 50 taken 1 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 1 times.
✗ Branch 55 not taken.
✓ Branch 56 taken 1 times.
✗ Branch 58 not taken.
✓ Branch 59 taken 1 times.
✗ Branch 61 not taken.
✓ Branch 62 taken 1 times.
✗ Branch 64 not taken.
✓ Branch 65 taken 1 times.
✗ Branch 67 not taken.
✓ Branch 68 taken 1 times.
✗ Branch 70 not taken.
✓ Branch 71 taken 1 times.
✗ Branch 73 not taken.
✓ Branch 74 taken 1 times.
✗ Branch 76 not taken.
✓ Branch 77 taken 1 times.
✗ Branch 79 not taken.
✓ Branch 80 taken 1 times.
✗ Branch 82 not taken.
✓ Branch 83 taken 1 times.
✗ Branch 85 not taken.
✓ Branch 86 taken 1 times.
✗ Branch 88 not taken.
✓ Branch 89 taken 1 times.
✗ Branch 91 not taken.
✓ Branch 92 taken 1 times.
✓ Branch 94 taken 1 times.
✓ Branch 95 taken 1 times.
✓ Branch 96 taken 3 times.
✓ Branch 97 taken 1 times.
✓ Branch 98 taken 27 times.
✓ Branch 99 taken 3 times.
✓ Branch 100 taken 243 times.
✓ Branch 101 taken 27 times.
275 source=0._real12)
278 end if
279
280 1 end subroutine set_batch_size_avgpool2d
281 !!!#############################################################################
282
283
284 !!!##########################################################################!!!
285 !!! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !!!
286 !!!##########################################################################!!!
287
288
289 !!!#############################################################################
290 !!! print layer to file
291 !!!#############################################################################
292 subroutine print_avgpool2d(this, file)
293 implicit none
294 class(avgpool2d_layer_type), intent(in) :: this
295 character(*), intent(in) :: file
296
297 integer :: unit
298
299 !! open file with new unit
300 !!--------------------------------------------------------------------------
301 open(newunit=unit, file=trim(file), access='append')
302
303 !! write convolution initial parameters
304 !!--------------------------------------------------------------------------
305 write(unit,'("AVGPOOL2D")')
306 write(unit,'(3X,"INPUT_SHAPE = ",3(1X,I0))') this%input_shape
307 if(all(this%pool.eq.this%pool(1)))then
308 write(unit,'(3X,"POOL_SIZE =",1X,I0)') this%pool(1)
309 else
310 write(unit,'(3X,"POOL_SIZE =",2(1X,I0))') this%pool
311 end if
312 if(all(this%strd.eq.this%strd(1)))then
313 write(unit,'(3X,"STRIDE =",1X,I0)') this%strd(1)
314 else
315 write(unit,'(3X,"STRIDE =",2(1X,I0))') this%strd
316 end if
317 write(unit,'("END AVGPOOL2D")')
318
319 !! close unit
320 !!--------------------------------------------------------------------------
321 close(unit)
322
323 end subroutine print_avgpool2d
324 !!!#############################################################################
325
326
327 !!!#############################################################################
328 !!! read layer from file
329 !!!#############################################################################
330 function read_avgpool2d_layer(unit) result(layer)
331 use infile_tools, only: assign_val, assign_vec
332 use misc, only: to_lower, icount
333 implicit none
334 integer, intent(in) :: unit
335
336 class(avgpool2d_layer_type), allocatable :: layer
337
338 integer :: stat
339 integer :: itmp1
340 integer, dimension(2) :: pool_size, stride
341 integer, dimension(3) :: input_shape
342 character(256) :: buffer, tag
343
344
345 !! loop over tags in layer card
346 tag_loop: do
347
348 !! check for end of file
349 read(unit,'(A)',iostat=stat) buffer
350 if(stat.ne.0)then
351 write(0,*) "ERROR: file encountered error (EoF?) before END AVGPOOL2D"
352 stop "Exiting..."
353 end if
354 if(trim(adjustl(buffer)).eq."") cycle tag_loop
355
356 !! check for end of convolution card
357 if(trim(adjustl(buffer)).eq."END AVGPOOL2D")then
358 backspace(unit)
359 exit tag_loop
360 end if
361
362 tag=trim(adjustl(buffer))
363 if(scan(buffer,"=").ne.0) tag=trim(tag(:scan(tag,"=")-1))
364
365 !! read parameters from save file
366 select case(trim(tag))
367 case("INPUT_SHAPE")
368 call assign_vec(buffer, input_shape, itmp1)
369 case("POOL_SIZE")
370 call assign_vec(buffer, pool_size, itmp1)
371 case("STRIDE")
372 call assign_vec(buffer, stride, itmp1)
373 case default
374 !! don't look for "e" due to scientific notation of numbers
375 !! ... i.e. exponent (E+00)
376 if(scan(to_lower(trim(adjustl(buffer))),&
377 'abcdfghijklmnopqrstuvwxyz').eq.0)then
378 cycle tag_loop
379 elseif(tag(:3).eq.'END')then
380 cycle tag_loop
381 end if
382 stop "Unrecognised line in input file: "//trim(adjustl(buffer))
383 end select
384 end do tag_loop
385
386 !! set transfer activation function
387
388 layer = avgpool2d_layer_type( input_shape=input_shape, &
389 pool_size = pool_size, stride = stride &
390 )
391
392 !! check for end of layer card
393 read(unit,'(A)') buffer
394 if(trim(adjustl(buffer)).ne."END AVGPOOL2D")then
395 write(*,*) trim(adjustl(buffer))
396 stop "ERROR: END AVGPOOL2D not where expected"
397 end if
398
399 end function read_avgpool2d_layer
400 !!!#############################################################################
401
402
403 !!!##########################################################################!!!
404 !!! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !!!
405 !!!##########################################################################!!!
406
407
408 !!!#############################################################################
409 !!! forward propagation
410 !!!#############################################################################
411 10 pure subroutine forward_4d(this, input)
412 implicit none
413 class(avgpool2d_layer_type), intent(inout) :: this
414
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
2 real(real12), dimension( &
415
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
2 this%input_shape(1), &
416 this%input_shape(2), &
417 this%num_channels, &
418 this%batch_size), &
419 intent(in) :: input
420
421 integer :: i, j, m, s
422 integer, dimension(2) :: stride_idx
423
424
425
8/8
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 54 times.
✓ Branch 7 taken 18 times.
82 this%output = 0._real12
426 !! perform the pooling operation
427 do concurrent(&
428 s = 1:this%batch_size, &
429 m = 1:this%num_channels, &
430 4 j = 1:this%output_shape(2), &
431
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 i = 1:this%output_shape(1))
432 #if defined(GFORTRAN)
433 stride_idx = ([i,j] - 1) * this%strd + 1
434 #else
435
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 54 times.
54 stride_idx(1) = (i-1) * this%strd(1) + 1
436
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 54 times.
54 stride_idx(2) = (j-1) * this%strd(2) + 1
437 #endif
438 432 this%output(i, j, m, s) = sum(&
439
2/4
✗ Branch 9 not taken.
✓ Branch 10 taken 54 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 54 times.
108 input( &
440 108 stride_idx(1):stride_idx(1)+this%pool(1)-1, &
441 108 stride_idx(2):stride_idx(2)+this%pool(2)-1, m, s)) / &
442
40/66
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 54 times.
✓ Branch 5 taken 18 times.
✓ Branch 6 taken 54 times.
✓ Branch 7 taken 54 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 54 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 54 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 54 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 54 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 54 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 54 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 54 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 54 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 54 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 54 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 54 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 54 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 54 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 54 times.
✓ Branch 40 taken 162 times.
✓ Branch 41 taken 54 times.
✓ Branch 42 taken 486 times.
✓ Branch 43 taken 162 times.
✗ Branch 44 not taken.
✓ Branch 45 taken 54 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 54 times.
✗ Branch 50 not taken.
✓ Branch 51 taken 54 times.
✗ Branch 53 not taken.
✓ Branch 54 taken 54 times.
✓ Branch 56 taken 108 times.
✓ Branch 57 taken 54 times.
✗ Branch 58 not taken.
✓ Branch 59 taken 54 times.
✗ Branch 61 not taken.
✓ Branch 62 taken 54 times.
✗ Branch 64 not taken.
✓ Branch 65 taken 54 times.
✗ Branch 67 not taken.
✓ Branch 68 taken 54 times.
✗ Branch 70 not taken.
✓ Branch 71 taken 54 times.
✗ Branch 73 not taken.
✓ Branch 74 taken 54 times.
✗ Branch 76 not taken.
✓ Branch 77 taken 54 times.
✗ Branch 79 not taken.
✓ Branch 80 taken 54 times.
998 product(this%pool)
443 end do
444
445 2 end subroutine forward_4d
446 !!!#############################################################################
447
448
449 !!!#############################################################################
450 !!! backward propagation
451 !!!#############################################################################
452 5 pure subroutine backward_4d(this, input, gradient)
453 implicit none
454 class(avgpool2d_layer_type), intent(inout) :: this
455 real(real12), dimension( &
456 this%input_shape(1), &
457 this%input_shape(2), &
458 this%num_channels, &
459 this%batch_size), &
460 intent(in) :: input
461 real(real12), &
462
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 dimension(&
463
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 this%output_shape(1), &
464 this%output_shape(2), &
465 this%num_channels, &
466 this%batch_size), &
467 intent(in) :: gradient
468
469 integer :: i, j, m, s
470 integer, dimension(2) :: stride_idx
471
472
473
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 27 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 243 times.
✓ Branch 7 taken 27 times.
275 this%di = 0._real12
474 !! compute gradients for input feature map
475 do concurrent( &
476 s = 1:this%batch_size, &
477 m = 1:this%num_channels, &
478 2 j = 1:this%output_shape(2), &
479
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 i = 1:this%output_shape(1))
480 #if defined(GFORTRAN)
481 stride_idx = ([i,j] - 1) * this%strd
482 #else
483
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27 times.
27 stride_idx(1) = (i-1) * this%strd(1)
484
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27 times.
27 stride_idx(2) = (j-1) * this%strd(2)
485 #endif
486 !! compute gradients for input feature map
487 378 this%di( &
488 54 stride_idx(1)+1:stride_idx(1)+this%pool(1), &
489 54 stride_idx(2)+1:stride_idx(2)+this%pool(2), m, s) = &
490 324 this%di( &
491 54 stride_idx(1)+1:stride_idx(1)+this%pool(1), &
492 54 stride_idx(2)+1:stride_idx(2)+this%pool(2), m, s) + &
493
60/106
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 27 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 27 times.
✓ Branch 7 taken 27 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 27 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 27 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 27 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 27 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 27 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 27 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 27 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 27 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 27 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 27 times.
✗ Branch 44 not taken.
✓ Branch 45 taken 27 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 27 times.
✗ Branch 50 not taken.
✓ Branch 51 taken 27 times.
✗ Branch 53 not taken.
✓ Branch 54 taken 27 times.
✗ Branch 56 not taken.
✓ Branch 57 taken 27 times.
✗ Branch 59 not taken.
✓ Branch 60 taken 27 times.
✗ Branch 62 not taken.
✓ Branch 63 taken 27 times.
✗ Branch 65 not taken.
✓ Branch 66 taken 27 times.
✗ Branch 68 not taken.
✓ Branch 69 taken 27 times.
✗ Branch 71 not taken.
✓ Branch 72 taken 27 times.
✗ Branch 74 not taken.
✓ Branch 75 taken 27 times.
✗ Branch 77 not taken.
✓ Branch 78 taken 27 times.
✗ Branch 80 not taken.
✓ Branch 81 taken 27 times.
✗ Branch 83 not taken.
✓ Branch 84 taken 27 times.
✗ Branch 86 not taken.
✓ Branch 87 taken 27 times.
✗ Branch 89 not taken.
✓ Branch 90 taken 27 times.
✗ Branch 92 not taken.
✓ Branch 93 taken 27 times.
✗ Branch 95 not taken.
✓ Branch 96 taken 27 times.
✗ Branch 98 not taken.
✓ Branch 99 taken 27 times.
✗ Branch 101 not taken.
✓ Branch 102 taken 27 times.
✗ Branch 104 not taken.
✓ Branch 105 taken 27 times.
✗ Branch 107 not taken.
✓ Branch 108 taken 27 times.
✗ Branch 110 not taken.
✓ Branch 111 taken 27 times.
✗ Branch 113 not taken.
✓ Branch 114 taken 27 times.
✗ Branch 116 not taken.
✓ Branch 117 taken 27 times.
✗ Branch 119 not taken.
✓ Branch 120 taken 27 times.
✓ Branch 122 taken 54 times.
✓ Branch 123 taken 27 times.
✗ Branch 124 not taken.
✓ Branch 125 taken 27 times.
✗ Branch 127 not taken.
✓ Branch 128 taken 27 times.
✗ Branch 130 not taken.
✓ Branch 131 taken 27 times.
✗ Branch 133 not taken.
✓ Branch 134 taken 27 times.
✗ Branch 136 not taken.
✓ Branch 137 taken 27 times.
✗ Branch 139 not taken.
✓ Branch 140 taken 27 times.
✗ Branch 142 not taken.
✓ Branch 143 taken 27 times.
✗ Branch 145 not taken.
✓ Branch 146 taken 27 times.
✓ Branch 148 taken 81 times.
✓ Branch 149 taken 27 times.
✓ Branch 150 taken 243 times.
✓ Branch 151 taken 81 times.
445 gradient(i, j, m, s) / product(this%pool)
494
495 end do
496
497 1 end subroutine backward_4d
498 !!!#############################################################################
499
500
53/87
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 4 times.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 4 times.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 4 times.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 2 times.
✓ Branch 25 taken 2 times.
✓ Branch 26 taken 2 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 2 times.
✓ Branch 29 taken 2 times.
✓ Branch 30 taken 2 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 2 times.
✓ Branch 33 taken 2 times.
✓ Branch 34 taken 2 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 2 times.
✓ Branch 37 taken 2 times.
✓ Branch 38 taken 2 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 3 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 3 times.
✓ Branch 45 taken 3 times.
✓ Branch 46 taken 3 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 3 times.
✗ Branch 49 not taken.
✗ 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 3 times.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✓ Branch 70 taken 3 times.
✓ Branch 71 taken 3 times.
✗ Branch 72 not taken.
✓ Branch 73 taken 2 times.
✓ Branch 74 taken 1 times.
✓ Branch 75 taken 3 times.
✗ Branch 76 not taken.
✓ Branch 77 taken 2 times.
✓ Branch 78 taken 1 times.
✓ Branch 79 taken 3 times.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✓ Branch 82 taken 3 times.
✓ Branch 83 taken 3 times.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✓ Branch 86 taken 3 times.
✓ Branch 87 taken 3 times.
✗ Branch 88 not taken.
✓ Branch 89 taken 2 times.
✓ Branch 90 taken 1 times.
✓ Branch 91 taken 3 times.
✗ Branch 92 not taken.
✓ Branch 93 taken 2 times.
✓ Branch 94 taken 1 times.
36 end module avgpool2d_layer
501 !!!#############################################################################
502