GCC Code Coverage Report


Directory: src/lib/
File: src/lib/mod_maxpool1d_layer.f90
Date: 2024-06-28 12:51:18
Exec Total Coverage
Lines: 72 113 63.7%
Functions: 0 0 -%
Branches: 331 695 47.6%

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 1D maxpooling layer
6 !!!#############################################################################
7 module maxpool1d_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) :: maxpool1d_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_maxpool1d
18 procedure, pass(this) :: init => init_maxpool1d
19 procedure, pass(this) :: set_batch_size => set_batch_size_maxpool1d
20 procedure, pass(this) :: print => print_maxpool1d
21 procedure, pass(this) :: forward => forward_rank
22 procedure, pass(this) :: backward => backward_rank
23 procedure, private, pass(this) :: forward_3d
24 procedure, private, pass(this) :: backward_3d
25 end type maxpool1d_layer_type
26
27
28 interface maxpool1d_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(maxpool1d_layer_type) :: layer
37 end function layer_setup
38 end interface maxpool1d_layer_type
39
40
41 private
42 public :: maxpool1d_layer_type
43 public :: read_maxpool1d_layer
44
45
46 contains
47
48 !!!#############################################################################
49 !!! get layer outputs
50 !!!#############################################################################
51 3 pure subroutine get_output_maxpool1d(this, output)
52 implicit none
53 class(maxpool1d_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 3 times.
✓ Branch 2 taken 3 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.
5 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 2 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.
5 reshape(this%output, [product(this%output_shape),this%batch_size])
62 rank(3)
63
26/52
✗ 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 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 taken 1 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 1 times.
✗ Branch 49 not taken.
✓ Branch 50 taken 1 times.
✗ Branch 51 not taken.
✓ Branch 52 taken 1 times.
✗ Branch 53 not taken.
✓ Branch 54 taken 1 times.
✗ Branch 55 not taken.
✓ Branch 56 taken 1 times.
✗ Branch 57 not taken.
✓ Branch 58 taken 1 times.
✓ Branch 59 taken 1 times.
✓ Branch 60 taken 3 times.
✓ Branch 61 taken 1 times.
✓ Branch 62 taken 24 times.
✓ Branch 63 taken 3 times.
29 output = this%output
64 end select
65
66 3 end subroutine get_output_maxpool1d
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(maxpool1d_layer_type), intent(inout) :: this
81 real(real12), dimension(..), intent(in) :: input
82
83 select rank(input); rank(3)
84 1 call forward_3d(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(maxpool1d_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(3)
100 1 select rank(gradient); rank(3)
101 1 call backward_3d(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(maxpool1d_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 = "maxpool1d"
134 4 layer%input_rank = 2
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 2 times.
✓ Branch 1 taken 2 times.
4 layer%pool = pool_size
145 rank(1)
146
8/20
✗ 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 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 2 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 taken 2 times.
✓ Branch 23 taken 2 times.
4 layer%pool = pool_size
147 end select
148 else
149 layer%pool = 2
150 end if
151
152
153 !!-----------------------------------------------------------------------
154 !! set up stride
155 !!-----------------------------------------------------------------------
156
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
157 4 select rank(stride)
158 rank(0)
159
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 layer%strd = stride
160 rank(1)
161
8/20
✗ 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 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 2 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 taken 2 times.
✓ Branch 23 taken 2 times.
4 layer%strd = stride
162 end select
163 else
164 layer%strd = 2
165 end if
166
167
168 !!--------------------------------------------------------------------------
169 !! initialise batch size
170 !!--------------------------------------------------------------------------
171
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(present(batch_size)) layer%batch_size = batch_size
172
173
174 !!--------------------------------------------------------------------------
175 !! initialise layer shape
176 !!--------------------------------------------------------------------------
177
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)
178
179 #if defined(GFORTRAN)
180 end function layer_setup
181 #else
182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
8 end procedure layer_setup
183 #endif
184 !!!#############################################################################
185
186
187 !!!#############################################################################
188 !!! initialise layer
189 !!!#############################################################################
190
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 subroutine init_maxpool1d(this, input_shape, batch_size, verbose)
191 implicit none
192 class(maxpool1d_layer_type), intent(inout) :: this
193 integer, dimension(:), intent(in) :: input_shape
194 integer, optional, intent(in) :: batch_size
195 integer, optional, intent(in) :: verbose
196
197 integer :: verbose_ = 0
198
199
200 !!--------------------------------------------------------------------------
201 !! initialise optional arguments
202 !!--------------------------------------------------------------------------
203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(present(verbose)) verbose_ = verbose
204
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(present(batch_size)) this%batch_size = batch_size
205
206
207 !!--------------------------------------------------------------------------
208 !! initialise input shape
209 !!--------------------------------------------------------------------------
210
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)
211
212
213 !!-----------------------------------------------------------------------
214 !! set up number of channels, width, height
215 !!-----------------------------------------------------------------------
216
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(2)
217
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(2))
218
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(2) = this%input_shape(2)
219 2 this%output_shape(1) = &
220
9/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 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 taken 1 times.
✗ Branch 25 not taken.
1 floor( (this%input_shape(1) - this%pool(1))/real(this%strd(1))) + 1
221
222
223 !!--------------------------------------------------------------------------
224 !! initialise batch size-dependent arrays
225 !!--------------------------------------------------------------------------
226
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)
227
228 1 end subroutine init_maxpool1d
229 !!!#############################################################################
230
231
232 !!!#############################################################################
233 !!! set batch size
234 !!!#############################################################################
235 1 subroutine set_batch_size_maxpool1d(this, batch_size, verbose)
236 implicit none
237 class(maxpool1d_layer_type), intent(inout) :: this
238 integer, intent(in) :: batch_size
239 integer, optional, intent(in) :: verbose
240
241 integer :: verbose_ = 0
242
243
244 !!--------------------------------------------------------------------------
245 !! initialise optional arguments
246 !!--------------------------------------------------------------------------
247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(present(verbose)) verbose_ = verbose
248 1 this%batch_size = batch_size
249
250
251 !!--------------------------------------------------------------------------
252 !! allocate arrays
253 !!--------------------------------------------------------------------------
254
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(allocated(this%input_shape))then
255
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)
256 allocate(this%output( &
257 2 this%output_shape(1), this%num_channels, &
258 this%batch_size), &
259
31/56
✗ 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 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✗ Branch 25 not taken.
✓ Branch 26 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 not taken.
✓ Branch 58 taken 1 times.
✗ Branch 60 not taken.
✓ Branch 61 taken 1 times.
✗ Branch 63 not taken.
✓ Branch 64 taken 1 times.
✓ Branch 66 taken 1 times.
✓ Branch 67 taken 1 times.
✓ Branch 68 taken 3 times.
✓ Branch 69 taken 1 times.
✓ Branch 70 taken 24 times.
✓ Branch 71 taken 3 times.
29 source=0._real12)
260
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)
261 allocate(this%di( &
262 2 this%input_shape(1), &
263 2 this%input_shape(2), &
264 this%batch_size), &
265
33/60
✗ 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 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 1 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 31 not taken.
✓ Branch 32 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 not taken.
✓ Branch 58 taken 1 times.
✗ Branch 60 not taken.
✓ Branch 61 taken 1 times.
✗ Branch 63 not taken.
✓ Branch 64 taken 1 times.
✗ Branch 66 not taken.
✓ Branch 67 taken 1 times.
✗ Branch 69 not taken.
✓ Branch 70 taken 1 times.
✓ Branch 72 taken 1 times.
✓ Branch 73 taken 1 times.
✓ Branch 74 taken 3 times.
✓ Branch 75 taken 1 times.
✓ Branch 76 taken 54 times.
✓ Branch 77 taken 3 times.
59 source=0._real12)
266 end if
267
268 1 end subroutine set_batch_size_maxpool1d
269 !!!#############################################################################
270
271
272 !!!##########################################################################!!!
273 !!! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !!!
274 !!!##########################################################################!!!
275
276
277 !!!#############################################################################
278 !!! print layer to file
279 !!!#############################################################################
280 subroutine print_maxpool1d(this, file)
281 implicit none
282 class(maxpool1d_layer_type), intent(in) :: this
283 character(*), intent(in) :: file
284
285 integer :: unit
286
287 !! open file with new unit
288 !!--------------------------------------------------------------------------
289 open(newunit=unit, file=trim(file), access='append')
290
291 !! write convolution initial parameters
292 !!--------------------------------------------------------------------------
293 write(unit,'("MAXPOOL1D")')
294 write(unit,'(3X,"INPUT_SHAPE = ",3(1X,I0))') this%input_shape
295 write(unit,'(3X,"POOL_SIZE =",1X,I0)') this%pool(1)
296 write(unit,'(3X,"STRIDE =",1X,I0)') this%strd(1)
297 write(unit,'("END MAXPOOL1D")')
298
299 !! close unit
300 !!--------------------------------------------------------------------------
301 close(unit)
302
303 end subroutine print_maxpool1d
304 !!!#############################################################################
305
306
307 !!!#############################################################################
308 !!! read layer from file
309 !!!#############################################################################
310 function read_maxpool1d_layer(unit) result(layer)
311 use infile_tools, only: assign_val, assign_vec
312 use misc, only: to_lower, icount
313 implicit none
314 integer, intent(in) :: unit
315
316 class(maxpool1d_layer_type), allocatable :: layer
317
318 integer :: stat
319 integer :: itmp1
320 integer, dimension(1) :: pool_size, stride
321 integer, dimension(2) :: input_shape
322 character(256) :: buffer, tag
323
324
325 !! loop over tags in layer card
326 tag_loop: do
327
328 !! check for end of file
329 read(unit,'(A)',iostat=stat) buffer
330 if(stat.ne.0)then
331 write(0,*) "ERROR: file encountered error (EoF?) before END MAXPOOL1D"
332 stop "Exiting..."
333 end if
334 if(trim(adjustl(buffer)).eq."") cycle tag_loop
335
336 !! check for end of convolution card
337 if(trim(adjustl(buffer)).eq."END MAXPOOL1D")then
338 backspace(unit)
339 exit tag_loop
340 end if
341
342 tag=trim(adjustl(buffer))
343 if(scan(buffer,"=").ne.0) tag=trim(tag(:scan(tag,"=")-1))
344
345 !! read parameters from save file
346 select case(trim(tag))
347 case("INPUT_SHAPE")
348 call assign_vec(buffer, input_shape, itmp1)
349 case("POOL_SIZE")
350 call assign_vec(buffer, pool_size, itmp1)
351 case("STRIDE")
352 call assign_vec(buffer, stride, itmp1)
353 case default
354 !! don't look for "e" due to scientific notation of numbers
355 !! ... i.e. exponent (E+00)
356 if(scan(to_lower(trim(adjustl(buffer))),&
357 'abcdfghijklmnopqrstuvwxyz').eq.0)then
358 cycle tag_loop
359 elseif(tag(:3).eq.'END')then
360 cycle tag_loop
361 end if
362 stop "Unrecognised line in input file: "//trim(adjustl(buffer))
363 end select
364 end do tag_loop
365
366 !! set transfer activation function
367
368 layer = maxpool1d_layer_type( input_shape=input_shape, &
369 pool_size = pool_size, stride = stride &
370 )
371
372 !! check for end of layer card
373 read(unit,'(A)') buffer
374 if(trim(adjustl(buffer)).ne."END MAXPOOL1D")then
375 write(*,*) trim(adjustl(buffer))
376 stop "ERROR: END MAXPOOL1D not where expected"
377 end if
378
379 end function read_maxpool1d_layer
380 !!!#############################################################################
381
382
383 !!!##########################################################################!!!
384 !!! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * !!!
385 !!!##########################################################################!!!
386
387
388 !!!#############################################################################
389 !!! forward propagation
390 !!!#############################################################################
391 3 pure subroutine forward_3d(this, input)
392 implicit none
393 class(maxpool1d_layer_type), intent(inout) :: this
394
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 real(real12), dimension( &
395 this%input_shape(1), &
396 this%num_channels, &
397 this%batch_size), &
398 intent(in) :: input
399
400 integer :: i, m, s
401 integer :: stride_idx
402
403
404
6/6
✓ 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.
29 this%output = 0._real12
405 !! perform the pooling operation
406 do concurrent(&
407 s = 1:this%batch_size, &
408 m = 1:this%num_channels, &
409
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 i = 1:this%output_shape(1))
410
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24 times.
24 stride_idx = (i-1) * this%strd(1) + 1
411 144 this%output(i, m, s) = maxval(&
412
2/4
✗ Branch 5 not taken.
✓ Branch 6 taken 24 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 24 times.
48 input( &
413
26/44
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 24 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 24 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 24 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 24 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 24 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 24 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 24 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 24 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 24 times.
✓ Branch 24 taken 24 times.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 24 times.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✓ Branch 30 taken 72 times.
✓ Branch 31 taken 24 times.
✓ Branch 32 taken 27 times.
✓ Branch 33 taken 45 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 24 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 24 times.
✗ Branch 40 not taken.
✓ Branch 41 taken 24 times.
✗ Branch 43 not taken.
✓ Branch 44 taken 24 times.
✗ Branch 46 not taken.
✓ Branch 47 taken 24 times.
✗ Branch 49 not taken.
✓ Branch 50 taken 24 times.
177 stride_idx:stride_idx+this%pool(1)-1, m, s))
414 end do
415
416 1 end subroutine forward_3d
417 !!!#############################################################################
418
419
420 !!!#############################################################################
421 !!! backward propagation
422 !!!#############################################################################
423 5 pure subroutine backward_3d(this, input, gradient)
424 implicit none
425 class(maxpool1d_layer_type), intent(inout) :: this
426
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 real(real12), dimension( &
427 this%input_shape(1), &
428 this%num_channels, &
429 this%batch_size), &
430 intent(in) :: input
431 real(real12), &
432
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 dimension(&
433 this%output_shape(1), &
434 this%num_channels, &
435 this%batch_size), &
436 intent(in) :: gradient
437
438 integer :: i, m, s
439 integer :: stride_idx, max_idx
440
441
442
6/6
✓ 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.
59 this%di = 0._real12
443 !! compute gradients for input feature map
444 do concurrent( &
445 s = 1:this%batch_size, &
446 m = 1:this%num_channels, &
447
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 i = 1:this%output_shape(1))
448
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24 times.
24 stride_idx = (i-1) * this%strd(1)
449 !! find the index of the maximum value in the corresponding pooling window
450
2/4
✗ Branch 5 not taken.
✓ Branch 6 taken 24 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 24 times.
48 max_idx = maxloc(input( &
451
14/26
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 24 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 24 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 24 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 24 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 24 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 24 times.
✓ Branch 18 taken 24 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 24 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✓ Branch 24 taken 72 times.
✓ Branch 25 taken 24 times.
✓ Branch 26 taken 3 times.
✓ Branch 27 taken 69 times.
144 stride_idx+1:stride_idx+this%pool(1), m, s), dim=1)
452
453 !! compute gradients for input feature map
454 144 this%di( &
455 stride_idx+max_idx, m, s) = &
456 144 this%di( &
457
24/42
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 24 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 24 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 24 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 24 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 24 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 24 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 24 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 24 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 24 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 24 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 24 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 24 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 24 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 24 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 24 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 24 times.
✗ Branch 51 not taken.
✓ Branch 52 taken 24 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 24 times.
✗ Branch 57 not taken.
✓ Branch 58 taken 24 times.
57 stride_idx+max_idx, m, s) + gradient(i, m, s)
458
459 end do
460
461 1 end subroutine backward_3d
462 !!!#############################################################################
463
464
53/87
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 4 times.
✓ Branch 8 taken 5 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 5 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.
34 end module maxpool1d_layer
465 !!!#############################################################################
466