| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | module athena__onnx_nop_utils | ||
| 2 | !! Shared utility routines for NOP ONNX export/import. | ||
| 3 | use coreutils, only: real32, stop_program | ||
| 4 | use athena__base_layer, only: base_layer_type | ||
| 5 | use athena__misc_types, only: onnx_attribute_type, onnx_node_type, & | ||
| 6 | onnx_initialiser_type | ||
| 7 | use athena__onnx_utils, only: emit_node, col_to_row_major_2d, & | ||
| 8 | row_to_col_major_2d | ||
| 9 | use diffstruc, only: array_type | ||
| 10 | implicit none | ||
| 11 | |||
| 12 | private | ||
| 13 | |||
| 14 | public :: emit_nop_input_transpose | ||
| 15 | public :: emit_nop_output_tail | ||
| 16 | public :: emit_float_initialiser | ||
| 17 | public :: emit_matrix_initialiser | ||
| 18 | public :: emit_nop_metadata | ||
| 19 | public :: parse_nop_metadata | ||
| 20 | public :: extract_nop_prefix | ||
| 21 | public :: load_nop_param_from_inits | ||
| 22 | public :: find_initialiser_by_name | ||
| 23 | public :: infer_dynamic_lno_poles | ||
| 24 | public :: find_onnx_expanded_node_by_suffix | ||
| 25 | public :: find_node_initialiser_index | ||
| 26 | public :: detect_onnx_expanded_nop_activation | ||
| 27 | public :: load_onnx_expanded_matrix_param | ||
| 28 | |||
| 29 | contains | ||
| 30 | |||
| 31 | !############################################################################### | ||
| 32 | 3 | subroutine emit_nop_input_transpose(prefix, input_name, nodes, num_nodes, & | |
| 33 | output_name) | ||
| 34 | !! Emit the common NOP input transpose. | ||
| 35 | implicit none | ||
| 36 | |||
| 37 | character(*), intent(in) :: prefix, input_name | ||
| 38 | type(onnx_node_type), intent(inout) :: nodes(:) | ||
| 39 | integer, intent(inout) :: num_nodes | ||
| 40 | character(*), intent(in) :: output_name | ||
| 41 | |||
| 42 | character(4096) :: perm_attr | ||
| 43 | |||
| 44 | perm_attr = ' "attribute": [{"name": "perm", "ints": ' // & | ||
| 45 | 3 | '["1", "0"], "type": "INTS"}]' | |
| 46 | |||
| 47 | call emit_node('Transpose', '/' // trim(prefix) // '/Transpose', & | ||
| 48 | ✗ | trim(output_name), trim(perm_attr), nodes, num_nodes, & | |
| 49 |
7/14✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3 times.
✓ Branch 15 taken 3 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 3 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 3 times.
✗ Branch 20 not taken.
|
3 | in1=trim(input_name)) |
| 50 | |||
| 51 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | end subroutine emit_nop_input_transpose |
| 52 | !############################################################################### | ||
| 53 | |||
| 54 | |||
| 55 | !############################################################################### | ||
| 56 | 3 | subroutine emit_nop_output_tail(prefix, activation_name, is_last_layer, & | |
| 57 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | input_name, nodes, num_nodes, final_output) |
| 58 | !! Emit the common transpose and optional activation at the end of a NOP. | ||
| 59 | use coreutils, only: to_camel_case | ||
| 60 | implicit none | ||
| 61 | |||
| 62 | character(*), intent(in) :: prefix, activation_name, input_name | ||
| 63 | logical, intent(in) :: is_last_layer | ||
| 64 | type(onnx_node_type), intent(inout) :: nodes(:) | ||
| 65 | integer, intent(inout) :: num_nodes | ||
| 66 | character(128), intent(out) :: final_output | ||
| 67 | |||
| 68 | character(4096) :: perm_attr | ||
| 69 | character(128) :: transpose_output | ||
| 70 | character(128) :: activation_op, activation_node | ||
| 71 | character(4096) :: activation_attr | ||
| 72 | |||
| 73 | perm_attr = ' "attribute": [{"name": "perm", "ints": ' // & | ||
| 74 | 3 | '["1", "0"], "type": "INTS"}]' | |
| 75 | |||
| 76 |
2/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
|
3 | if(is_last_layer .and. trim(activation_name) .eq. 'none')then |
| 77 | ✗ | transpose_output = 'output' | |
| 78 | else | ||
| 79 | write(transpose_output, '("/",A,"/Transpose_1_output_0")') & | ||
| 80 |
1/2✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
|
3 | trim(prefix) |
| 81 | end if | ||
| 82 | |||
| 83 | call emit_node('Transpose', '/' // trim(prefix) // '/Transpose_1', & | ||
| 84 | ✗ | trim(transpose_output), trim(perm_attr), nodes, num_nodes, & | |
| 85 |
7/14✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3 times.
✓ Branch 15 taken 3 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 3 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 3 times.
✗ Branch 20 not taken.
|
3 | in1=trim(input_name)) |
| 86 | |||
| 87 |
2/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
|
3 | if(trim(activation_name) .ne. 'none')then |
| 88 | activation_op = to_camel_case( & | ||
| 89 | trim(adjustl(activation_name)), & | ||
| 90 |
2/4✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
|
3 | capitalise_first_letter = .true.) |
| 91 | 3 | activation_attr = '' | |
| 92 |
2/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
|
3 | if(trim(activation_name) .eq. 'leaky_relu')then |
| 93 | ✗ | activation_op = 'LeakyRelu' | |
| 94 | activation_attr = ' "attribute": [{"name": "alpha", ' // & | ||
| 95 | ✗ | '"f": 0.01, "type": "FLOAT"}]' | |
| 96 | end if | ||
| 97 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | if(is_last_layer)then |
| 98 | 3 | final_output = 'output' | |
| 99 | else | ||
| 100 | write(final_output, '("/",A,"/",A,"_output_0")') & | ||
| 101 | ✗ | trim(prefix), trim(activation_op) | |
| 102 | end if | ||
| 103 |
3/6✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
✗ Branch 10 not taken.
|
3 | activation_node = '/' // trim(prefix) // '/' // trim(activation_op) |
| 104 | call emit_node(trim(activation_op), trim(activation_node), & | ||
| 105 | ✗ | trim(final_output), trim(activation_attr), nodes, num_nodes, & | |
| 106 |
8/16✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
✓ Branch 12 taken 3 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 3 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 3 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 3 times.
✓ Branch 20 taken 3 times.
✗ Branch 21 not taken.
|
3 | in1=trim(transpose_output)) |
| 107 | else | ||
| 108 | ✗ | final_output = transpose_output | |
| 109 | end if | ||
| 110 | |||
| 111 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | end subroutine emit_nop_output_tail |
| 112 | !############################################################################### | ||
| 113 | |||
| 114 | |||
| 115 | !############################################################################### | ||
| 116 |
2/4✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
|
13 | subroutine emit_float_initialiser(name, data, dims, inits, num_inits) |
| 117 | !! Emit a float32 initialiser with explicit dimensions. | ||
| 118 | implicit none | ||
| 119 | |||
| 120 | character(*), intent(in) :: name | ||
| 121 | real(real32), intent(in) :: data(:) | ||
| 122 | integer, intent(in) :: dims(:) | ||
| 123 | type(onnx_initialiser_type), intent(inout) :: inits(:) | ||
| 124 | integer, intent(inout) :: num_inits | ||
| 125 | |||
| 126 | 13 | num_inits = num_inits + 1 | |
| 127 |
4/8✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 13 times.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 13 times.
✗ Branch 10 not taken.
|
13 | inits(num_inits)%name = trim(name) |
| 128 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
|
13 | inits(num_inits)%data_type = 1 |
| 129 |
12/24✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 13 times.
✓ Branch 15 taken 13 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 13 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 13 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 13 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 13 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 13 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 13 times.
|
13 | allocate(inits(num_inits)%dims(size(dims))) |
| 130 |
9/18✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 13 times.
✓ Branch 15 taken 13 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 13 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 26 times.
✓ Branch 22 taken 13 times.
|
39 | inits(num_inits)%dims = dims |
| 131 |
12/24✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 13 times.
✓ Branch 15 taken 13 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 13 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 13 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 13 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 13 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 13 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 13 times.
|
13 | allocate(inits(num_inits)%data(size(data))) |
| 132 |
9/18✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 13 times.
✓ Branch 15 taken 13 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 13 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 1376 times.
✓ Branch 22 taken 13 times.
|
1389 | inits(num_inits)%data = data |
| 133 | |||
| 134 |
1/2✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
|
13 | end subroutine emit_float_initialiser |
| 135 | !############################################################################### | ||
| 136 | |||
| 137 | |||
| 138 | !############################################################################### | ||
| 139 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | subroutine emit_matrix_initialiser(name, data_col_major, rows, cols, inits, & |
| 140 | num_inits) | ||
| 141 | !! Emit a 2D float32 initialiser after converting to row-major order. | ||
| 142 | implicit none | ||
| 143 | |||
| 144 | character(*), intent(in) :: name | ||
| 145 | real(real32), intent(in) :: data_col_major(:) | ||
| 146 | integer, intent(in) :: rows, cols | ||
| 147 | type(onnx_initialiser_type), intent(inout) :: inits(:) | ||
| 148 | integer, intent(inout) :: num_inits | ||
| 149 | |||
| 150 | 4 | real(real32), allocatable :: row_major(:) | |
| 151 | |||
| 152 |
10/20✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 4 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 4 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 4 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 4 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 4 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 4 times.
|
4 | allocate(row_major(size(data_col_major))) |
| 153 |
4/8✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 4 times.
|
4 | call col_to_row_major_2d(data_col_major, row_major, rows, cols) |
| 154 | ✗ | call emit_float_initialiser(name, row_major, [rows, cols], inits, & | |
| 155 |
5/8✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
|
12 | num_inits) |
| 156 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | deallocate(row_major) |
| 157 | |||
| 158 |
2/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
|
8 | end subroutine emit_matrix_initialiser |
| 159 | !############################################################################### | ||
| 160 | |||
| 161 | |||
| 162 | !############################################################################### | ||
| 163 | 4 | subroutine emit_nop_metadata(layer, prefix, metadata, num_meta) | |
| 164 | !! Build the metadata entry required to reconstruct a NOP layer. | ||
| 165 | implicit none | ||
| 166 | |||
| 167 | class(base_layer_type), intent(in) :: layer | ||
| 168 | character(*), intent(in) :: prefix | ||
| 169 | character(4096), intent(inout) :: metadata(:) | ||
| 170 | integer, intent(inout) :: num_meta | ||
| 171 | |||
| 172 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | type(onnx_attribute_type), allocatable :: attrs(:) |
| 173 | integer :: i | ||
| 174 | character(2048) :: value_str | ||
| 175 | |||
| 176 |
11/34✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✗ 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 19 times.
✓ Branch 12 taken 4 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 19 times.
✓ Branch 28 taken 4 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 19 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 19 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 19 times.
|
46 | attrs = layer%get_attributes() |
| 177 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if(.not.allocated(attrs)) return |
| 178 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if(size(attrs) .eq. 0) return |
| 179 | |||
| 180 |
2/4✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
|
4 | value_str = 'subtype=' // trim(adjustl(layer%name)) |
| 181 |
2/2✓ Branch 0 taken 19 times.
✓ Branch 1 taken 4 times.
|
23 | do i = 1, size(attrs) |
| 182 | ✗ | value_str = trim(value_str) // ';' // trim(attrs(i)%name) // '=' // & | |
| 183 |
8/16✓ Branch 2 taken 19 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 19 times.
✓ Branch 10 taken 19 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 19 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 19 times.
✓ Branch 22 taken 19 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 19 times.
✗ Branch 25 not taken.
|
23 | trim(adjustl(attrs(i)%val)) |
| 184 | end do | ||
| 185 | |||
| 186 | 4 | num_meta = num_meta + 1 | |
| 187 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | write(metadata(num_meta), '(A)') & |
| 188 | ' {"key": "athena_nop_' // trim(prefix) // & | ||
| 189 |
3/6✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
|
8 | '", "value": "' // trim(value_str) // '"}' |
| 190 | |||
| 191 |
8/14✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 19 times.
✓ Branch 7 taken 4 times.
✓ Branch 8 taken 19 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 19 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 19 times.
✗ Branch 13 not taken.
|
31 | end subroutine emit_nop_metadata |
| 192 | !############################################################################### | ||
| 193 | |||
| 194 | |||
| 195 | !############################################################################### | ||
| 196 | 4 | subroutine parse_nop_metadata(meta_value, & | |
| 197 | ✗ | num_inputs, num_outputs, num_modes, use_bias, activation_name) | |
| 198 | !! Parse common NOP hyperparameters from metadata value string. | ||
| 199 | implicit none | ||
| 200 | |||
| 201 | character(*), intent(in) :: meta_value | ||
| 202 | integer, intent(inout) :: num_inputs, num_outputs, num_modes | ||
| 203 | logical, intent(inout) :: use_bias | ||
| 204 | character(64), intent(inout) :: activation_name | ||
| 205 | |||
| 206 | integer :: k, pos, pos2, stat | ||
| 207 | character(256) :: token, key, val | ||
| 208 | logical :: logical_val | ||
| 209 | |||
| 210 | 4 | pos = 1 | |
| 211 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 23 times.
|
27 | do while(pos .le. len_trim(meta_value)) |
| 212 |
2/4✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 23 times.
|
23 | pos2 = index(meta_value(pos:), ';') |
| 213 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 19 times.
|
23 | if(pos2 .eq. 0)then |
| 214 |
5/10✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
|
4 | token = meta_value(pos:len_trim(meta_value)) |
| 215 | 4 | pos = len_trim(meta_value) + 1 | |
| 216 | else | ||
| 217 |
5/10✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19 times.
✓ Branch 5 taken 19 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 19 times.
✓ Branch 10 taken 19 times.
✗ Branch 11 not taken.
|
19 | token = meta_value(pos:pos+pos2-2) |
| 218 | 19 | pos = pos + pos2 | |
| 219 | end if | ||
| 220 | 23 | k = index(token, '=') | |
| 221 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
|
23 | if(k .eq. 0) cycle |
| 222 |
4/8✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 23 times.
✓ Branch 7 taken 23 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 23 times.
✗ Branch 10 not taken.
|
23 | key = trim(adjustl(token(1:k-1))) |
| 223 |
4/8✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 23 times.
✓ Branch 7 taken 23 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 23 times.
✗ Branch 10 not taken.
|
23 | val = trim(adjustl(token(k+1:))) |
| 224 | 46 | select case(trim(key)) | |
| 225 | case('num_inputs') | ||
| 226 | 4 | read(val, *) num_inputs | |
| 227 | case('num_outputs') | ||
| 228 | 4 | read(val, *) num_outputs | |
| 229 | case('num_modes', 'num_basis') | ||
| 230 | 3 | read(val, *) num_modes | |
| 231 | case('use_bias') | ||
| 232 | 4 | read(val, *, iostat=stat) logical_val | |
| 233 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
8 | if(stat .eq. 0)then |
| 234 | ✗ | use_bias = logical_val | |
| 235 | else | ||
| 236 | 8 | select case(trim(adjustl(val))) | |
| 237 | case('1', 'T', 't', 'true', 'TRUE', 'True') | ||
| 238 | 4 | use_bias = .true. | |
| 239 | case('0', 'F', 'f', 'false', 'FALSE', 'False') | ||
| 240 | ✗ | use_bias = .false. | |
| 241 | case default | ||
| 242 |
2/5✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
8 | call stop_program('parse_nop_metadata: invalid use_bias value') |
| 243 | end select | ||
| 244 | end if | ||
| 245 | case('activation') | ||
| 246 |
9/12✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 4 times.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 4 times.
✗ Branch 12 not taken.
|
46 | activation_name = trim(val) |
| 247 | end select | ||
| 248 | end do | ||
| 249 | |||
| 250 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | end subroutine parse_nop_metadata |
| 251 | !############################################################################### | ||
| 252 | |||
| 253 | |||
| 254 | !############################################################################### | ||
| 255 | 4 | function extract_nop_prefix(meta_key) result(prefix) | |
| 256 | !! Extract the node prefix from an athena_nop_node_X metadata key. | ||
| 257 | implicit none | ||
| 258 | |||
| 259 | character(*), intent(in) :: meta_key | ||
| 260 | character(64) :: prefix | ||
| 261 | |||
| 262 | integer :: pos | ||
| 263 | |||
| 264 |
2/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | prefix = trim(meta_key) |
| 265 | 4 | pos = index(prefix, 'athena_nop_') | |
| 266 |
4/8✓ 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 7 taken 4 times.
✗ Branch 8 not taken.
|
4 | if(pos .gt. 0) prefix = prefix(pos+11:) |
| 267 | |||
| 268 | 4 | end function extract_nop_prefix | |
| 269 | !############################################################################### | ||
| 270 | |||
| 271 | |||
| 272 | !############################################################################### | ||
| 273 | 14 | subroutine load_nop_param_from_inits( & | |
| 274 | 14 | param, prefix, suffix, inits, num_inits, dims) | |
| 275 | !! Load a parameter from ONNX initialisers into a diffstruc array. | ||
| 276 | implicit none | ||
| 277 | |||
| 278 | type(array_type), intent(inout) :: param | ||
| 279 | character(*), intent(in) :: prefix, suffix | ||
| 280 | type(onnx_initialiser_type), intent(in) :: inits(:) | ||
| 281 | integer, intent(in) :: num_inits | ||
| 282 | integer, intent(in) :: dims(2) | ||
| 283 | |||
| 284 | integer :: k | ||
| 285 | character(128) :: target_name | ||
| 286 | 14 | real(real32), allocatable :: col_data(:) | |
| 287 | |||
| 288 |
1/2✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
|
14 | write(target_name, '(A,A)') trim(prefix), suffix |
| 289 | |||
| 290 |
1/2✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
|
32 | do k = 1, num_inits |
| 291 |
6/10✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32 times.
✓ Branch 8 taken 32 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 32 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 18 times.
✓ Branch 13 taken 14 times.
|
32 | if(trim(inits(k)%name) .ne. trim(target_name)) cycle |
| 292 |
3/6✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 14 times.
|
14 | if(.not.allocated(inits(k)%data)) cycle |
| 293 | |||
| 294 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
|
14 | if(dims(2) .gt. 1)then |
| 295 |
9/18✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 7 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 7 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 7 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 7 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 7 times.
|
7 | allocate(col_data(size(inits(k)%data))) |
| 296 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
|
7 | call row_to_col_major_2d(inits(k)%data, col_data, dims(1), dims(2)) |
| 297 |
13/24✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 7 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 7 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 7 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 7 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 7 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 7 times.
✓ Branch 33 taken 1313 times.
✓ Branch 34 taken 7 times.
|
1320 | param%val(:,1) = col_data |
| 298 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
|
14 | deallocate(col_data) |
| 299 | else | ||
| 300 |
15/28✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 7 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 7 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 7 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 7 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 7 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 7 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 7 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 7 times.
✓ Branch 39 taken 68 times.
✓ Branch 40 taken 7 times.
|
75 | param%val(:,1) = inits(k)%data |
| 301 | end if | ||
| 302 | 14 | return | |
| 303 | end do | ||
| 304 | |||
| 305 |
2/4✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
|
28 | end subroutine load_nop_param_from_inits |
| 306 | !############################################################################### | ||
| 307 | |||
| 308 | |||
| 309 | !############################################################################### | ||
| 310 | 40 | integer function find_initialiser_by_name(name, inits, num_inits) | |
| 311 | !! Return the index of a named initialiser, or zero when not found. | ||
| 312 | implicit none | ||
| 313 | |||
| 314 | character(*), intent(in) :: name | ||
| 315 | type(onnx_initialiser_type), intent(in) :: inits(:) | ||
| 316 | integer, intent(in) :: num_inits | ||
| 317 | |||
| 318 | integer :: i | ||
| 319 | |||
| 320 | 40 | find_initialiser_by_name = 0 | |
| 321 |
2/2✓ Branch 0 taken 106 times.
✓ Branch 1 taken 9 times.
|
115 | do i = 1, num_inits |
| 322 |
6/10✗ Branch 0 not taken.
✓ Branch 1 taken 106 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 106 times.
✓ Branch 8 taken 106 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 106 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 31 times.
✓ Branch 13 taken 75 times.
|
115 | if(trim(inits(i)%name) .eq. trim(name))then |
| 323 | 31 | find_initialiser_by_name = i | |
| 324 | 31 | return | |
| 325 | end if | ||
| 326 | end do | ||
| 327 | |||
| 328 |
1/2✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
|
49 | end function find_initialiser_by_name |
| 329 | !############################################################################### | ||
| 330 | |||
| 331 | |||
| 332 | !############################################################################### | ||
| 333 | 1 | subroutine infer_dynamic_lno_poles(e_args_init, d_args_init, num_inputs, & | |
| 334 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | num_outputs, poles) |
| 335 | !! Reconstruct dynamic LNO poles from exported encoder/decoder arguments. | ||
| 336 | implicit none | ||
| 337 | |||
| 338 | type(onnx_initialiser_type), intent(in) :: e_args_init, d_args_init | ||
| 339 | integer, intent(in) :: num_inputs, num_outputs | ||
| 340 | real(real32), intent(out) :: poles(:) | ||
| 341 | |||
| 342 | integer :: k, idx, num_modes | ||
| 343 | real(real32) :: pi_value | ||
| 344 | |||
| 345 |
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 | num_modes = size(poles) |
| 346 | |||
| 347 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if(num_inputs .gt. 1 .and. allocated(e_args_init%data))then |
| 348 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
|
7 | do k = 1, num_modes |
| 349 | 6 | idx = (k - 1) * num_inputs + num_inputs | |
| 350 |
4/8✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6 times.
|
7 | poles(k) = -e_args_init%data(idx) |
| 351 | end do | ||
| 352 | 1 | return | |
| 353 | end if | ||
| 354 | |||
| 355 | ✗ | if(num_outputs .gt. 1 .and. allocated(d_args_init%data))then | |
| 356 | ✗ | do k = 1, num_modes | |
| 357 | ✗ | idx = (num_outputs - 1) * num_modes + k | |
| 358 | ✗ | poles(k) = -d_args_init%data(idx) | |
| 359 | end do | ||
| 360 | ✗ | return | |
| 361 | end if | ||
| 362 | |||
| 363 | ✗ | pi_value = acos(-1.0_real32) | |
| 364 | ✗ | do k = 1, num_modes | |
| 365 | ✗ | poles(k) = real(k, real32) * pi_value | |
| 366 | end do | ||
| 367 | |||
| 368 | end subroutine infer_dynamic_lno_poles | ||
| 369 | !############################################################################### | ||
| 370 | |||
| 371 | !############################################################################### | ||
| 372 | 33 | integer function find_onnx_expanded_node_by_suffix( & | |
| 373 | 33 | nodes, num_nodes, prefix, suffix) | |
| 374 | !! Return the node index matching one /layerN/suffix name, or zero. | ||
| 375 | implicit none | ||
| 376 | |||
| 377 | ! Arguments | ||
| 378 | type(onnx_node_type), intent(in) :: nodes(:) | ||
| 379 | !! Parsed ONNX nodes | ||
| 380 | integer, intent(in) :: num_nodes | ||
| 381 | !! Number of valid node entries | ||
| 382 | character(*), intent(in) :: prefix, suffix | ||
| 383 | !! Layer prefix and trailing node name token | ||
| 384 | |||
| 385 | ! Local variables | ||
| 386 | integer :: i | ||
| 387 | !! Loop index | ||
| 388 | character(128) :: target_name | ||
| 389 | !! Full node name to match | ||
| 390 | |||
| 391 |
2/4✓ Branch 3 taken 33 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 33 times.
✗ Branch 8 not taken.
|
33 | write(target_name, '("/",A,"/",A)') trim(prefix), trim(suffix) |
| 392 | 33 | find_onnx_expanded_node_by_suffix = 0 | |
| 393 | |||
| 394 |
2/2✓ Branch 0 taken 191 times.
✓ Branch 1 taken 14 times.
|
205 | do i = 1, num_nodes |
| 395 |
6/10✗ Branch 0 not taken.
✓ Branch 1 taken 191 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 191 times.
✓ Branch 8 taken 191 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 191 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 19 times.
✓ Branch 13 taken 172 times.
|
205 | if(trim(nodes(i)%name) .eq. trim(target_name))then |
| 396 | 19 | find_onnx_expanded_node_by_suffix = i | |
| 397 | 19 | return | |
| 398 | end if | ||
| 399 | end do | ||
| 400 | |||
| 401 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
47 | end function find_onnx_expanded_node_by_suffix |
| 402 | !############################################################################### | ||
| 403 | |||
| 404 | |||
| 405 | !############################################################################### | ||
| 406 |
1/2✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
|
11 | integer function find_node_initialiser_index(node, inits, num_inits) |
| 407 | !! Return the first initialiser referenced by a node's inputs. | ||
| 408 | implicit none | ||
| 409 | |||
| 410 | ! Arguments | ||
| 411 | type(onnx_node_type), intent(in) :: node | ||
| 412 | !! Parsed ONNX node whose inputs may reference an initialiser | ||
| 413 | type(onnx_initialiser_type), intent(in) :: inits(:) | ||
| 414 | !! Parsed ONNX initialisers | ||
| 415 | integer, intent(in) :: num_inits | ||
| 416 | !! Number of valid initialiser entries | ||
| 417 | |||
| 418 | ! Local variables | ||
| 419 | integer :: i, init_idx | ||
| 420 | !! Loop index and candidate initialiser index | ||
| 421 | |||
| 422 | 11 | find_node_initialiser_index = 0 | |
| 423 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
|
11 | if(.not.allocated(node%inputs)) return |
| 424 | |||
| 425 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | do i = 1, size(node%inputs) |
| 426 |
5/10✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 14 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 14 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 14 times.
|
14 | init_idx = find_initialiser_by_name(node%inputs(i), inits, num_inits) |
| 427 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 3 times.
|
14 | if(init_idx .gt. 0)then |
| 428 | 11 | find_node_initialiser_index = init_idx | |
| 429 | 11 | return | |
| 430 | end if | ||
| 431 | end do | ||
| 432 | |||
| 433 | ✗ | end function find_node_initialiser_index | |
| 434 | !############################################################################### | ||
| 435 | |||
| 436 | |||
| 437 | !############################################################################### | ||
| 438 | 3 | function detect_onnx_expanded_nop_activation(prefix, nodes, num_nodes) & | |
| 439 | result(name) | ||
| 440 | !! Reconstruct the activation name from the tail of an expanded-ONNX NOP | ||
| 441 | !! cluster. | ||
| 442 | use athena__onnx_utils, only: onnx_to_athena_activation | ||
| 443 | implicit none | ||
| 444 | |||
| 445 | ! Arguments | ||
| 446 | character(*), intent(in) :: prefix | ||
| 447 | !! Layer node prefix without leading slash | ||
| 448 | type(onnx_node_type), intent(in) :: nodes(:) | ||
| 449 | !! Parsed ONNX nodes | ||
| 450 | integer, intent(in) :: num_nodes | ||
| 451 | !! Number of valid node entries | ||
| 452 | character(64) :: name | ||
| 453 | !! Reconstructed ATHENA activation name | ||
| 454 | integer :: i | ||
| 455 | character(128) :: cluster_prefix | ||
| 456 | |||
| 457 |
1/2✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
|
3 | write(cluster_prefix, '("/",A,"/")') trim(prefix) |
| 458 | 3 | name = 'none' | |
| 459 | |||
| 460 |
1/2✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
|
28 | do i = 1, num_nodes |
| 461 |
5/10✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 28 times.
✓ Branch 8 taken 28 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 28 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 28 times.
|
28 | if(index(trim(nodes(i)%name), trim(cluster_prefix)) .ne. 1) cycle |
| 462 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 28 times.
|
56 | select case(trim(nodes(i)%op_type)) |
| 463 | case('Relu', 'LeakyRelu', 'Sigmoid', 'Softmax', 'Tanh', 'Selu', & | ||
| 464 | 'Swish') | ||
| 465 |
3/6✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
|
3 | name = onnx_to_athena_activation(trim(nodes(i)%op_type)) |
| 466 |
3/4✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 25 times.
|
59 | return |
| 467 | end select | ||
| 468 | end do | ||
| 469 | |||
| 470 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | end function detect_onnx_expanded_nop_activation |
| 471 | !############################################################################### | ||
| 472 | |||
| 473 | |||
| 474 | !############################################################################### | ||
| 475 | 4 | subroutine load_onnx_expanded_matrix_param(param, init, rows, cols) | |
| 476 | !! Copy a row-major ONNX matrix initialiser into a diffstruc parameter. | ||
| 477 | implicit none | ||
| 478 | |||
| 479 | ! Arguments | ||
| 480 | type(array_type), intent(inout) :: param | ||
| 481 | !! Destination diffstruc parameter tensor | ||
| 482 | type(onnx_initialiser_type), intent(in) :: init | ||
| 483 | !! Row-major ONNX initialiser data | ||
| 484 | integer, intent(in) :: rows, cols | ||
| 485 | !! Matrix shape | ||
| 486 | |||
| 487 | ! Local variables | ||
| 488 | 4 | real(real32), allocatable :: col_major(:) | |
| 489 | !! Temporary column-major buffer for ATHENA internal storage | ||
| 490 | |||
| 491 |
7/14✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ 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 11 not taken.
✓ Branch 12 taken 4 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 4 times.
|
4 | allocate(col_major(rows * cols)) |
| 492 | 4 | call row_to_col_major_2d(init%data, col_major, rows, cols) | |
| 493 |
13/24✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 4 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 4 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 4 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 4 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 4 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 4 times.
✓ Branch 33 taken 928 times.
✓ Branch 34 taken 4 times.
|
932 | param%val(:,1) = col_major |
| 494 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | deallocate(col_major) |
| 495 | |||
| 496 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | end subroutine load_onnx_expanded_matrix_param |
| 497 | !############################################################################### | ||
| 498 | |||
| 499 | end module athena__onnx_nop_utils | ||
| 500 |