|
23 | 23 | from tvm import relay |
24 | 24 | from tvm.relay.op.contrib import cmsisnn |
25 | 25 |
|
26 | | -from tvm.testing.aot import generate_ref_data, AOTTestModel, compile_and_run |
| 26 | +from tvm.testing.aot import generate_ref_data, AOTTestModel, compile_models, compile_and_run |
27 | 27 |
|
28 | 28 | from tvm.micro.testing.aot_test_utils import AOT_USMP_CORSTONE300_RUNNER |
29 | 29 | from utils import ( |
@@ -119,6 +119,100 @@ def make_model( |
119 | 119 | return last_op, params |
120 | 120 |
|
121 | 121 |
|
| 122 | +@tvm.testing.requires_cmsisnn |
| 123 | +@pytest.mark.parametrize("padding", ["SAME", "VALID"]) |
| 124 | +@pytest.mark.parametrize("enable_bias", [True, False]) |
| 125 | +@pytest.mark.parametrize( |
| 126 | + "input_zero_point, input_scale, kernel_scale, out_channels", |
| 127 | + [(10, 0.0128, [0.11, 0.22], 2)], |
| 128 | +) |
| 129 | +def test_conv2d_number_primfunc_args( |
| 130 | + padding, |
| 131 | + enable_bias, |
| 132 | + input_zero_point, |
| 133 | + input_scale, |
| 134 | + kernel_scale, |
| 135 | + out_channels, |
| 136 | +): |
| 137 | + interface_api = "c" |
| 138 | + use_unpacked_api = True |
| 139 | + test_runner = AOT_USMP_CORSTONE300_RUNNER |
| 140 | + |
| 141 | + ifm_shape = (1, 64, 100, 4) |
| 142 | + kernel_size = (3, 3) |
| 143 | + strides = (1, 1) |
| 144 | + dilation = (1, 1) |
| 145 | + dtype = "int8" |
| 146 | + groups = 1 |
| 147 | + weight_format = "HWIO" |
| 148 | + kernel_h = kernel_size[0] |
| 149 | + kernel_w = kernel_size[1] |
| 150 | + kernel_shape = (kernel_h, kernel_w, ifm_shape[3] // groups, out_channels) |
| 151 | + kernel_zero_point = 0 |
| 152 | + in_min, in_max = get_range_for_dtype_str(dtype) |
| 153 | + relu_type = "RELU" |
| 154 | + |
| 155 | + output_scale, output_zero_point = get_conv2d_qnn_params( |
| 156 | + kernel_shape, |
| 157 | + input_scale, |
| 158 | + input_zero_point, |
| 159 | + kernel_scale, |
| 160 | + kernel_zero_point, |
| 161 | + dtype, |
| 162 | + dtype, |
| 163 | + dtype, |
| 164 | + ) |
| 165 | + |
| 166 | + model, params = make_model( |
| 167 | + ifm_shape, |
| 168 | + kernel_shape, |
| 169 | + input_zero_point, |
| 170 | + input_scale, |
| 171 | + kernel_zero_point, |
| 172 | + kernel_scale, |
| 173 | + output_zero_point, |
| 174 | + output_scale, |
| 175 | + padding, |
| 176 | + strides, |
| 177 | + dilation, |
| 178 | + groups, |
| 179 | + dtype, |
| 180 | + dtype, |
| 181 | + out_channels, |
| 182 | + weight_format, |
| 183 | + enable_bias, |
| 184 | + relu_type, |
| 185 | + ) |
| 186 | + orig_mod = make_module(model) |
| 187 | + cmsisnn_mod = cmsisnn.partition_for_cmsisnn(orig_mod, params) |
| 188 | + |
| 189 | + # validate pattern matching |
| 190 | + assert_partitioned_function(orig_mod, cmsisnn_mod) |
| 191 | + |
| 192 | + # compile the model |
| 193 | + rng = np.random.default_rng(12345) |
| 194 | + inputs = {"input": rng.integers(in_min, high=in_max, size=ifm_shape, dtype=dtype)} |
| 195 | + output_list = generate_ref_data(orig_mod["main"], inputs, params) |
| 196 | + |
| 197 | + compiled_models = compile_models( |
| 198 | + AOTTestModel(module=cmsisnn_mod, inputs=inputs, outputs=output_list, params=params), |
| 199 | + interface_api, |
| 200 | + use_unpacked_api, |
| 201 | + ) |
| 202 | + |
| 203 | + # validate number of TIR primfunc args |
| 204 | + expected_num_params = 6 if enable_bias else 5 |
| 205 | + cmsisnn_tir_mod = None |
| 206 | + for target, mod in compiled_models[0].executor_factory.lowered_ir_mods.items(): |
| 207 | + if "cmsis-nn" == target.kind.name: |
| 208 | + cmsisnn_tir_mod = mod |
| 209 | + |
| 210 | + cmsisnn_func = cmsisnn_tir_mod["tvmgen_default_cmsis_nn_main_0"] |
| 211 | + assert ( |
| 212 | + len(cmsisnn_func.params) == expected_num_params |
| 213 | + ), "Generated unexpected number of function arguments" |
| 214 | + |
| 215 | + |
122 | 216 | @tvm.testing.requires_cmsisnn |
123 | 217 | @pytest.mark.parametrize("padding", ["SAME", "VALID"]) |
124 | 218 | @pytest.mark.parametrize("relu_type", ["RELU"]) |
|
0 commit comments