GCC Code Coverage Report


Directory: src/athena/
File: src/athena/athena_activation_linear.f90
Date: 2026-04-15 16:08:59
Exec Total Coverage
Lines: 28 45 62.2%
Functions: 0 0 -%
Branches: 22 131 16.8%

Line Branch Exec Source
1 module athena__activation_linear
2 !! Module containing implementation of the linear activation function
3 !!
4 !! This module implements a scaled linear (affine) activation function.
5 !!
6 !! Mathematical operation:
7 !! \[ f(x) = \alpha x \]
8 !!
9 !! where \(\alpha\) is a scaling factor (typically \(\alpha=1\))
10 !!
11 !! Derivative:
12 !! \[ f'(x) = \alpha \]
13 !!
14 !! Properties: Linear transformation, no non-linearity introduced
15 !! Used for regression outputs or when no activation is desired
16 use coreutils, only: real32, print_warning
17 use diffstruc, only: array_type, operator(*)
18 use athena__misc_types, only: base_actv_type
19 use athena__misc_types, only: onnx_attribute_type
20 implicit none
21
22
23 private
24
25 public :: linear_actv_type, create_from_onnx_linear_activation
26
27
28 type, extends(base_actv_type) :: linear_actv_type
29 contains
30 procedure, pass(this) :: apply => apply_linear
31 procedure, pass(this) :: reset => reset_linear
32 procedure, pass(this) :: apply_attributes => apply_attributes_linear
33 procedure, pass(this) :: export_attributes => export_attributes_linear
34 end type linear_actv_type
35
36 interface linear_actv_type
37 procedure initialise
38 end interface linear_actv_type
39
40
41
42 contains
43
44 !###############################################################################
45
0/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
25 function initialise(scale, attributes) result(activation)
46 !! Initialise a linear activation function
47 implicit none
48
49 ! Arguments
50 real(real32), intent(in), optional :: scale
51 !! Optional scale factor for activation output
52 type(onnx_attribute_type), dimension(:), intent(in), optional :: attributes
53 !! Optional array of ONNX attributes
54 type(linear_actv_type) :: activation
55 !! Linear activation type
56
57
58 25 call activation%reset()
59
60
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 24 times.
25 if(present(scale)) activation%scale = scale
61
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 24 times.
25 if(abs(activation%scale-1._real32) .gt. 1.e-6_real32)then
62 1 activation%apply_scaling = .true.
63 end if
64
65
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if(present(attributes))then
66 call activation%apply_attributes(attributes)
67 end if
68
69
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
50 end function initialise
70 !-------------------------------------------------------------------------------
71 25 pure subroutine reset_linear(this)
72 !! Reset linear activation function attributes and variables
73 implicit none
74
75 ! Arguments
76 class(linear_actv_type), intent(inout) :: this
77 !! Linear activation type
78
79 25 this%name = "linear"
80 25 this%scale = 1._real32
81 25 this%threshold = 0._real32
82 25 this%apply_scaling = .false.
83
84 25 end subroutine reset_linear
85 !-------------------------------------------------------------------------------
86 function create_from_onnx_linear_activation(attributes) result(activation)
87 !! Create linear activation function from ONNX attributes
88 implicit none
89
90 ! Arguments
91 type(onnx_attribute_type), dimension(:), intent(in) :: attributes
92 !! Array of ONNX attributes
93
94 class(base_actv_type), allocatable :: activation
95 !! Instance of activation type
96
97 allocate(activation, source = linear_actv_type(attributes = attributes))
98
99 end function create_from_onnx_linear_activation
100 !###############################################################################
101
102
103 !###############################################################################
104
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 subroutine apply_attributes_linear(this, attributes)
105 !! Load ONNX attributes into linear activation function
106 implicit none
107
108 ! Arguments
109 class(linear_actv_type), intent(inout) :: this
110 !! Linear activation type
111 type(onnx_attribute_type), dimension(:), intent(in) :: attributes
112 !! Array of ONNX attributes
113
114 ! Local variables
115 integer :: i
116 !! Loop variable
117
118 ! Load provided attributes
119
5/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 taken 2 times.
✓ Branch 10 taken 2 times.
4 do i=1, size(attributes,dim=1)
120
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
6 select case(trim(attributes(i)%name))
121 case("scale")
122
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
2 read(attributes(i)%val,*) this%scale
123
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
4 if(abs(this%scale-1._real32) .gt. 1.e-6_real32)then
124 1 this%apply_scaling = .true.
125 else
126 1 this%apply_scaling = .false.
127 end if
128 case("name")
129 if(trim(attributes(i)%val) .ne. trim(this%name))then
130 call print_warning( &
131 'Linear activation: name attribute "' // &
132 trim(attributes(i)%val) // &
133 '"" does not match expected "' // trim(this%name)//'"' &
134 )
135
136 end if
137 case default
138 call print_warning( &
139 'Linear activation: unknown attribute '// &
140 trim(attributes(i)%name) &
141
2/9
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
4 )
142 end select
143 end do
144
145 2 end subroutine apply_attributes_linear
146 !###############################################################################
147
148
149 !###############################################################################
150 pure function export_attributes_linear(this) result(attributes)
151 !! Export linear activation function attributes as ONNX attributes
152 implicit none
153
154 ! Arguments
155 class(linear_actv_type), intent(in) :: this
156 !! Linear activation type
157 type(onnx_attribute_type), allocatable, dimension(:) :: attributes
158 !! Array of ONNX attributes
159
160 ! Local variables
161 character(50) :: buffer
162 !! Temporary string buffer
163
164 allocate(attributes(2))
165
166 write(buffer, '(A)') this%name
167 attributes(1) = onnx_attribute_type( &
168 "name", "string", trim(adjustl(buffer)) )
169
170 write(buffer, '(F10.6)') this%scale
171 attributes(2) = onnx_attribute_type( &
172 "scale", "float", trim(adjustl(buffer)) )
173
174 end function export_attributes_linear
175 !###############################################################################
176
177
178 !###############################################################################
179 24 function apply_linear(this, val) result(output)
180 !! Apply linear activation to 1D array
181 !!
182 !! Computes: f = scale * x
183 implicit none
184
185 ! Arguments
186 class(linear_actv_type), intent(in) :: this
187 !! Linear activation type
188 type(array_type), intent(in) :: val
189 !! Input values
190 type(array_type), pointer :: output
191 !! Scaled output values
192
193
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 22 times.
24 if(this%apply_scaling)then
194 2 output => val * this%scale
195 else
196 22 output => val * 1._real32 ! multiplication by 1 to ensure new allocation
197 end if
198 24 end function apply_linear
199 !###############################################################################
200
201 133 end module athena__activation_linear
202