Helper function to test linear op with different configurations.
(
self,
make_module,
uses_bias,
num_batch_dims=1,
quant_type=None,
dtype: torch.dtype = torch.float,
atol=1e-03, # TODO(T212995726): Investigate right atol for rand[n] inputs
)
| 235 | return qconfig |
| 236 | |
| 237 | def _test_linear( |
| 238 | self, |
| 239 | make_module, |
| 240 | uses_bias, |
| 241 | num_batch_dims=1, |
| 242 | quant_type=None, |
| 243 | dtype: torch.dtype = torch.float, |
| 244 | atol=1e-03, # TODO(T212995726): Investigate right atol for rand[n] inputs |
| 245 | ): |
| 246 | """ |
| 247 | Helper function to test linear op with different configurations. |
| 248 | """ |
| 249 | edge_op = ( |
| 250 | "executorch_exir_dialects_edge__ops_aten_addmm_default" |
| 251 | if uses_bias |
| 252 | else "executorch_exir_dialects_edge__ops_aten_mm_default" |
| 253 | ) |
| 254 | |
| 255 | in_sizes = [3, 4, 4] |
| 256 | input_sizes = [4, 37, 17] |
| 257 | output_sizes = [4, 17, 37] |
| 258 | |
| 259 | quant_config = None |
| 260 | if quant_type is not None: |
| 261 | if quant_type == "per_channel": |
| 262 | quant_config = get_symmetric_quantization_config( |
| 263 | is_per_channel=True, |
| 264 | is_dynamic=False, |
| 265 | ) |
| 266 | elif quant_type == "per_tensor": |
| 267 | quant_config = get_symmetric_quantization_config( |
| 268 | is_per_channel=False, |
| 269 | is_dynamic=False, |
| 270 | ) |
| 271 | else: |
| 272 | raise ValueError(f"Unsupported quant type {quant_type}") |
| 273 | |
| 274 | """ |
| 275 | Note that torch.nn.Linear maps to aten.mm.default (no bias) or aten.addmm.default (bias), |
| 276 | which ares then transformed into aten.linear.default by the ConvertToLinear pass. |
| 277 | """ |
| 278 | for i, _ in enumerate(in_sizes): |
| 279 | torch._dynamo.reset() |
| 280 | in_size = int(in_sizes[i]) |
| 281 | input_size = int(input_sizes[i]) |
| 282 | output_size = int(output_sizes[i]) |
| 283 | input_shape = [in_size] * num_batch_dims + [input_size] |
| 284 | |
| 285 | module = make_module(input_size, output_size).eval().to(dtype) |
| 286 | inputs = (torch.randn(input_shape).to(dtype),) |
| 287 | dynamic_shape = {} |
| 288 | for i in range(num_batch_dims): |
| 289 | dynamic_shape[i] = torch.export.Dim(f"batch{i}", min=2, max=in_size) |
| 290 | |
| 291 | dynamic_shape = (dynamic_shape,) |
| 292 | |
| 293 | for legacy_mode in (True, False): |
| 294 | tester = Tester(module, inputs, dynamic_shapes=dynamic_shape) |
no test coverage detected