GCC Code Coverage Report


Directory: src/lib/
File: src/lib/mod_maxpool2d_layer.f90
Date: 2024-06-28 12:51:18
Exec Total Coverage
Lines: 92 136 67.6%
Functions: 0 0 -%
Branches: 428 885 48.4%

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 maxpooling layer
6 !!!#############################################################################
7 module maxpool2d_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) :: maxpool2d_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_maxpool2d
18 procedure, pass(this) :: init => init_maxpool2d
19 procedure, pass(this) :: set_batch_size => set_batch_size_maxpool2d
20 procedure, pass(this) :: print => print_maxpool2d
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 maxpool2d_layer_type
26
27
28 interface maxpool2d_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(maxpool2d_layer_type) :: layer
37 end function layer_setup
38 end interface maxpool2d_layer_type
39
40
41 private
42 public :: maxpool2d_layer_type
43 public :: read_maxpool2d_layer
44
45
46 contains
47
48 !!!#############################################################################
49 !!! get layer outputs
50 !!!#############################################################################
51 3 pure subroutine get_output_maxpool2d(this, output)
52 implicit none
53 class(maxpool2d_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 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 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 1 times.
✗ Branch 59 not taken.
✓ Branch 60 taken 1 times.
✗ Branch 61 not taken.
✓ Branch 62 taken 1 times.
✗ Branch 63 not taken.
✓ Branch 64 taken 1 times.
✗ Branch 65 not taken.
✓ Branch 66 taken 1 times.
✗ Branch 67 not taken.
✓ Branch 68 taken 1 times.
✗ Branch 69 not taken.
✓ Branch 70 taken 1 times.
✗ Branch 71 not taken.
✓ Branch 72 taken 1 times.
✗ Branch 73 not taken.
✓ Branch 74 taken 1 times.
✗ Branch 75 not taken.
✓ Branch 76 taken 1 times.
✓ Branch 77 taken 1 times.
✓ Branch 78 taken 3 times.
✓ Branch 79 taken 1 times.
✓ Branch 80 taken 24 times.
✓ Branch 81 taken 3 times.
✓ Branch 82 taken 192 times.
✓ Branch 83 taken 24 times.
221 output = this%output
64 end select
65
66 3 end subroutine get_output_maxpool2d
67 !!!#############################################################################
68
69
70 !!!##########################################################################!!!
71 !!! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !!!
72 !!!##########################################################################!!!
73
74
75 !!!#############################################################################
76 !!! forward propagation assumed rank handler
77 !!!#############################################################################
78 1 pure subroutine forward_rank(this, input)
79 implicit none
80 class(maxpool2d_layer_type), intent(inout) :: this
81 real(real12), dimension(..), intent(in) :: input
82
83 select rank(input); rank(4)
84 1 call forward_4d(this, input)
85 end select
86 1 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(maxpool2d_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(maxpool2d_layer_type) :: layer
127 #else
128
0/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5 module procedure layer_setup
129 implicit none
130 #endif
131
132
133
3/8
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 5 times.
5 layer%name = "maxpool2d"
134 5 layer%input_rank = 3
135 allocate( &
136 layer%pool(layer%input_rank-1), &
137
16/32
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 5 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 5 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 5 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 5 times.
✓ Branch 18 taken 5 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 5 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 5 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 5 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 5 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 5 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 5 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 5 times.
5 layer%strd(layer%input_rank-1) )
138 !!-----------------------------------------------------------------------
139 !! set up pool size
140 !!-----------------------------------------------------------------------
141
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
5 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
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 layer%pool = 2
155 end if
156
157
158 !!-----------------------------------------------------------------------
159 !! set up stride
160 !!-----------------------------------------------------------------------
161
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
5 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
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 layer%strd = 2
175 end if
176
177
178 !!--------------------------------------------------------------------------
179 !! initialise batch size
180 !!--------------------------------------------------------------------------
181
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 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 5 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.
5 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 5 times.
10 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_maxpool2d(this, input_shape, batch_size, verbose)
201 implicit none
202 class(maxpool2d_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_maxpool2d
239 !!!#############################################################################
240
241
242 !!!#############################################################################
243 !!! set batch size
244 !!!#############################################################################
245 1 subroutine set_batch_size_maxpool2d(this, batch_size, verbose)
246 implicit none
247 class(maxpool2d_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 24 times.
✓ Branch 93 taken 3 times.
✓ Branch 94 taken 192 times.
✓ Branch 95 taken 24 times.
221 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 54 times.
✓ Branch 99 taken 3 times.
✓ Branch 100 taken 972 times.
✓ Branch 101 taken 54 times.
1031 source=0._real12)
278 end if
279
280 1 end subroutine set_batch_size_maxpool2d
281 !!!#############################################################################
282
283
284 !!!##########################################################################!!!
285 !!! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !!!
286 !!!##########################################################################!!!
287
288
289 !!!#############################################################################
290 !!! print layer to file
291 !!!#############################################################################
292 subroutine print_maxpool2d(this, file)
293 implicit none
294 class(maxpool2d_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,'("MAXPOOL2D")')
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 MAXPOOL2D")')
318
319 !! close unit
320 !!--------------------------------------------------------------------------
321 close(unit)
322
323 end subroutine print_maxpool2d
324 !!!#############################################################################
325
326
327 !!!#############################################################################
328 !!! read layer from file
329 !!!#############################################################################
330 function read_maxpool2d_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(maxpool2d_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 MAXPOOL2D"
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 MAXPOOL2D")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 = maxpool2d_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 MAXPOOL2D")then
395 write(*,*) trim(adjustl(buffer))
396 stop "ERROR: END MAXPOOL2D not where expected"
397 end if
398
399 end function read_maxpool2d_layer
400 !!!#############################################################################
401
402
403 !!!##########################################################################!!!
404 !!! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !!!
405 !!!##########################################################################!!!
406
407
408 !!!#############################################################################
409 !!! forward propagation
410 !!!#############################################################################
411 5 pure subroutine forward_4d(this, input)
412 implicit none
413 class(maxpool2d_layer_type), intent(inout) :: this
414
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 real(real12), dimension( &
415
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 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 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 192 times.
✓ Branch 7 taken 24 times.
221 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 2 j = 1:this%output_shape(2), &
431
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))
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 192 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 192 times.
192 stride_idx(1) = (i-1) * this%strd(1) + 1
436
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 192 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 192 times.
192 stride_idx(2) = (j-1) * this%strd(2) + 1
437 #endif
438 1536 this%output(i, j, m, s) = maxval(&
439
2/4
✗ Branch 9 not taken.
✓ Branch 10 taken 192 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 192 times.
384 input( &
440 384 stride_idx(1):stride_idx(1)+this%pool(1)-1, &
441
40/66
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 64 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 192 times.
✓ Branch 5 taken 64 times.
✓ Branch 6 taken 192 times.
✓ Branch 7 taken 192 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 192 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 192 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 192 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 192 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 192 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 192 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 192 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 192 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 192 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 192 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 192 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 192 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 192 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 192 times.
✓ Branch 40 taken 576 times.
✓ Branch 41 taken 192 times.
✓ Branch 42 taken 1728 times.
✓ Branch 43 taken 576 times.
✓ Branch 44 taken 1536 times.
✓ Branch 45 taken 192 times.
✓ Branch 46 taken 9 times.
✓ Branch 47 taken 1527 times.
✓ Branch 48 taken 192 times.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✓ Branch 51 taken 192 times.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✓ Branch 55 taken 192 times.
✗ Branch 57 not taken.
✓ Branch 58 taken 192 times.
✗ Branch 60 not taken.
✓ Branch 61 taken 192 times.
✗ Branch 63 not taken.
✓ Branch 64 taken 192 times.
✗ Branch 66 not taken.
✓ Branch 67 taken 192 times.
✗ Branch 69 not taken.
✓ Branch 70 taken 192 times.
✗ Branch 72 not taken.
✓ Branch 73 taken 192 times.
✗ Branch 75 not taken.
✓ Branch 76 taken 192 times.
3145 stride_idx(2):stride_idx(2)+this%pool(2)-1, m, s))
442 end do
443
444 1 end subroutine forward_4d
445 !!!#############################################################################
446
447
448 !!!#############################################################################
449 !!! backward propagation
450 !!!#############################################################################
451 9 pure subroutine backward_4d(this, input, gradient)
452 implicit none
453 class(maxpool2d_layer_type), intent(inout) :: this
454
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 real(real12), dimension( &
455
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 this%input_shape(1), &
456 this%input_shape(2), &
457 this%num_channels, &
458 this%batch_size), &
459 intent(in) :: input
460 real(real12), &
461
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 dimension(&
462
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), &
463 this%output_shape(2), &
464 this%num_channels, &
465 this%batch_size), &
466 intent(in) :: gradient
467
468 integer :: i, j, m, s
469 integer, dimension(2) :: stride_idx, max_idx
470
471
472
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 54 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 972 times.
✓ Branch 7 taken 54 times.
1031 this%di = 0._real12
473 !! compute gradients for input feature map
474 do concurrent( &
475 s = 1:this%batch_size, &
476 m = 1:this%num_channels, &
477 2 j = 1:this%output_shape(2), &
478
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))
479 #if defined(GFORTRAN)
480 stride_idx = ([i,j] - 1) * this%strd
481 #else
482
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 192 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 192 times.
192 stride_idx(1) = (i-1) * this%strd(1)
483
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 192 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 192 times.
192 stride_idx(2) = (j-1) * this%strd(2)
484 #endif
485 !! find the index of the maximum value in the corresponding pooling window
486 max_idx = maxloc(input( &
487 384 stride_idx(1)+1:stride_idx(1)+this%pool(1), &
488
12/24
✗ Branch 0 not taken.
✓ Branch 1 taken 192 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 192 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 192 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 192 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 192 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 192 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 192 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 192 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 192 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 192 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 192 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 192 times.
192 stride_idx(2)+1:stride_idx(2)+this%pool(2), m, s))
489
490 !! compute gradients for input feature map
491 1536 this%di( &
492 stride_idx(1)+max_idx(1), &
493 stride_idx(2)+max_idx(2), m, s) = &
494 1536 this%di( &
495 stride_idx(1)+max_idx(1), &
496
32/56
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 64 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 192 times.
✓ Branch 5 taken 64 times.
✓ Branch 6 taken 192 times.
✓ Branch 7 taken 192 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 192 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 192 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 192 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 192 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 192 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 192 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 192 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 192 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 192 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 192 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 192 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 192 times.
✗ Branch 44 not taken.
✓ Branch 45 taken 192 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 192 times.
✗ Branch 50 not taken.
✓ Branch 51 taken 192 times.
✗ Branch 53 not taken.
✓ Branch 54 taken 192 times.
✗ Branch 56 not taken.
✓ Branch 57 taken 192 times.
✗ Branch 59 not taken.
✓ Branch 60 taken 192 times.
✗ Branch 62 not taken.
✓ Branch 63 taken 192 times.
✗ Branch 65 not taken.
✓ Branch 66 taken 192 times.
✗ Branch 68 not taken.
✓ Branch 69 taken 192 times.
✗ Branch 71 not taken.
✓ Branch 72 taken 192 times.
✗ Branch 74 not taken.
✓ Branch 75 taken 192 times.
✗ Branch 77 not taken.
✓ Branch 78 taken 192 times.
457 stride_idx(2)+max_idx(2), m, s) + gradient(i, j, m, s)
497
498 end do
499
500 1 end subroutine backward_4d
501 !!!#############################################################################
502
503
53/87
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 9 times.
✓ Branch 8 taken 10 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 10 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 9 times.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 9 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 4 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 4 times.
✓ Branch 45 taken 4 times.
✓ Branch 46 taken 4 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 4 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 4 times.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✓ Branch 70 taken 4 times.
✓ Branch 71 taken 4 times.
✗ Branch 72 not taken.
✓ Branch 73 taken 3 times.
✓ Branch 74 taken 1 times.
✓ Branch 75 taken 4 times.
✗ Branch 76 not taken.
✓ Branch 77 taken 3 times.
✓ Branch 78 taken 1 times.
✓ Branch 79 taken 4 times.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✓ Branch 82 taken 4 times.
✓ Branch 83 taken 4 times.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✓ Branch 86 taken 4 times.
✓ Branch 87 taken 4 times.
✗ Branch 88 not taken.
✓ Branch 89 taken 3 times.
✓ Branch 90 taken 1 times.
✓ Branch 91 taken 4 times.
✗ Branch 92 not taken.
✓ Branch 93 taken 3 times.
✓ Branch 94 taken 1 times.
48 end module maxpool2d_layer
504 !!!#############################################################################
505