def test_squeezenet(): Device.load("test_config.json") if skip_runtime_test(): return import tvm.relay.testing.tf as tf_testing device = Device() def get_model(): model_path = tf_testing.get_workload_official( "https://storage.googleapis.com/download.tensorflow.org/models/tflite/model_zoo/upload_20180427/squeezenet_2018_04_27.tgz", "squeezenet.tflite", ) inputs = {"Placeholder": ((1, 224, 224, 3), "float32")} mod, params = _get_tflite_model(model_path, inputs_dict=inputs) return mod, params, inputs _build_and_run_network(*get_model(), device=device, tvm_ops=9, acl_partitions=31, atol=8, rtol=0)
def test_vgg16(): Device.load("test_config.json") if skip_runtime_test(): return device = Device() def get_model(): from keras.applications import VGG16 vgg16 = VGG16(include_top=True, weights="imagenet", input_shape=(224, 224, 3), classes=1000) inputs = {vgg16.input_names[0]: ((1, 224, 224, 3), "float32")} mod, params = _get_keras_model(vgg16, inputs) return mod, params, inputs _build_and_run_network(*get_model(), device=device, tvm_ops=4, acl_partitions=21, atol=0.002, rtol=0.01)
def test_mobilenet(): Device.load("test_config.json") if skip_runtime_test(): return device = Device() def get_model(): try: from keras.applications import MobileNet except ImportError: pytest.skip("Missing keras module") mobilenet = MobileNet(include_top=True, weights="imagenet", input_shape=(224, 224, 3), classes=1000) inputs = {mobilenet.input_names[0]: ((1, 224, 224, 3), "float32")} mod, params = _get_keras_model(mobilenet, inputs) return mod, params, inputs _build_and_run_network(*get_model(), device=device, tvm_ops=56, acl_partitions=31, atol=0.002, rtol=0.01)
def test_quantized_mobilenet(): Device.load("test_config.json") if skip_runtime_test(): return import tvm.relay.testing.tf as tf_testing device = Device() def get_model(): model_path = tf_testing.get_workload_official( "https://storage.googleapis.com/download.tensorflow.org/" "models/mobilenet_v1_2018_08_02/mobilenet_v1_1.0_224_quant.tgz", "mobilenet_v1_1.0_224_quant.tflite", ) inputs = {"input": ((1, 224, 224, 3), "uint8")} mod, params = _get_tflite_model(model_path, inputs_dict=inputs) return mod, params, inputs _build_and_run_network(*get_model(), device=device, tvm_ops=3, acl_partitions=30, atol=9, rtol=0)
def test_runtime_add(): Device.load("test_config.json") if skip_runtime_test(): return device = Device() np.random.seed(0) for dtype, low, high, atol, rtol, op, op_params in [ ("float32", -127, 128, 1e-7, 1e-7, relay.add, {}), ("uint8", 0, 255, 0.0, 1.0, relay.qnn.op.add, _qnn_params), ]: shape = (2, 2) for inputs in [ { "a": tvm.nd.array(np.random.uniform(low, high, shape).astype(dtype)), "b": tvm.nd.array(np.random.uniform(low, high, shape).astype(dtype)), } ]: outputs = [] func = _get_model(shape, dtype, iter(inputs), op, op_params) for acl in [True, False]: outputs.append(build_and_run(func, inputs, 1, None, device, enable_acl=acl)[0]) config = { "shape": shape, "dtype": dtype, "inputs": inputs, "operation": op, "op_params": op_params, } verify(outputs, atol=atol, rtol=rtol, config=config, verify_saturation=False)
def test_global_pooling(): Device.load("test_config.json") if skip_runtime_test(): return device = Device() np.random.seed(0) fp32_dtype = ("float32", -127, 128, 0.001, 0.001) uint8_dtype = ("uint8", 0, 255, 1, 0) trials = [ ["nn.global_max_pool2d", fp32_dtype, (8, 8, 16)], ["nn.global_max_pool2d", fp32_dtype, (9, 9, 16)], ["nn.global_max_pool2d", fp32_dtype, (8, 8, 16)], ["nn.global_max_pool2d", uint8_dtype, (8, 8, 16)], ["nn.global_max_pool2d", uint8_dtype, (9, 9, 16)], ["nn.global_avg_pool2d", fp32_dtype, (8, 8, 16)], ["nn.global_avg_pool2d", fp32_dtype, (8, 8, 16)], ["nn.global_avg_pool2d", fp32_dtype, (9, 9, 16)], ["nn.global_avg_pool2d", uint8_dtype, (8, 8, 16)], ["nn.global_avg_pool2d", uint8_dtype, (8, 8, 16)], ] for typef, (dtype, low, high, atol, rtol), input_shape in trials: shape = (1, *input_shape) outputs = [] inputs = { "a": tvm.nd.array(np.random.uniform(low, high, shape).astype(dtype)), } func = _get_global_pooling_model(shape, dtype, typef, iter(inputs)) config = { "shape": shape, "pooling type": typef, "dtype": dtype, } verify_saturation = True if dtype == "uint8" else False for acl in [False, True]: outputs.append( build_and_run(func, inputs, 1, None, device, enable_acl=acl, config=config)[0]) verify(outputs, atol=atol, rtol=rtol, config=config, verify_saturation=verify_saturation)
def test_dense(): Device.load("test_config.json") if skip_runtime_test(): return device = Device() np.random.seed(0) dtype = "float32" trials = [ [(1, 128), (16, 128), 16, True, 1], [(1, 128), (16, 128), 16, False, 1], [(32, 32), (32, 32), 32, True, 1], [(32, 32), (32, 32), 32, False, 1], [(1, 64), (1, 64), 1, True, 0], [(1, 64), (1, 64), 1, False, 0], [(11, 2), (2, 2), 2, True, 0], [(11, 2), (2, 2), 2, False, 0], ] for shape, weight_shape, units, composite, acl_partitions in trials: outputs = [] inputs = { "a": tvm.nd.array(np.random.uniform(-128, 127, shape).astype(dtype)) } func, params = _get_model(shape, weight_shape, units, dtype, var_names=iter(inputs), has_bias=composite) for acl in [False, True]: outputs.append( build_and_run( func, inputs, 1, params, device, enable_acl=acl, tvm_ops=(1 - acl_partitions) * (2 - int(not composite)), acl_partitions=acl_partitions, )[0]) config = { "shape": shape, "weight_shape": weight_shape, "units": units, "dtype": dtype, "composite operators (bias)": composite, } verify(outputs, atol=0.001, rtol=0.01, config=config)
def test_concatenate(): Device.load("test_config.json") if skip_runtime_test(): return device = Device() np.random.seed(0) for input_shape_a, input_shape_b, input_shape_c, axis, dtype in [ ([1, 234, 234, 256], [2, 234, 234, 256], [3, 234, 234, 256], 0, "float32"), ([1, 1, 234, 256], [1, 2, 234, 256], [1, 3, 234, 256], 1, "float32"), ([1, 234, 234, 1], [1, 234, 234, 2], [1, 234, 234, 3], -1, "float32"), ([1, 234, 234, 256], [2, 234, 234, 256], [3, 234, 234, 256], -4, "float32"), ([1, 234, 234, 256], [2, 234, 234, 256], [3, 234, 234, 256], 0, "uint8"), ([1, 1, 234, 256], [1, 2, 234, 256], [1, 3, 234, 256], 1, "uint8"), ([1, 234, 234, 1], [1, 234, 234, 2], [1, 234, 234, 3], -1, "uint8"), ([1, 234, 234, 256], [2, 234, 234, 256], [3, 234, 234, 256], -4, "uint8"), ]: outputs = [] inputs = { "a": tvm.nd.array(np.random.randn(*input_shape_a).astype(dtype)), "b": tvm.nd.array(np.random.randn(*input_shape_b).astype(dtype)), "c": tvm.nd.array(np.random.randn(*input_shape_c).astype(dtype)), } func = _get_model(inputs["a"].shape, inputs["b"].shape, inputs["c"].shape, axis, dtype, iter(inputs)) for acl in [False, True]: outputs.append( build_and_run(func, inputs, 1, None, device, enable_acl=acl, disabled_ops=[])[0]) config = { "input_shape_a": input_shape_a, "input_shape_b": input_shape_b, "input_shape_c": input_shape_c, "axis": axis, "dtype": dtype, } verify(outputs, atol=1e-7, rtol=1e-7, config=config)
def test_pooling(): Device.load("test_config.json") if skip_runtime_test(): return device = Device() np.random.seed(0) fp32_dtype = ("float32", -127, 128, 0.001, 0.001) uint8_dtype = ("uint8", 0, 255, 1, 0) # fmt: off trials = [ [ "nn.max_pool2d", fp32_dtype, (3, 3), (2, 2), (1, 1), (0, 0), False, False, (27, 27, 512), (0, 1), ], [ "nn.max_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (0, 0), False, True, (16, 16, 16), (0, 1), ], [ "nn.max_pool2d", fp32_dtype, (3, 3), (2, 2), (1, 1), (1, 1), True, True, (15, 15, 16), (0, 1), ], [ "nn.max_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1), ], [ "nn.max_pool2d", uint8_dtype, (3, 3), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1), ], [ "nn.max_pool2d", uint8_dtype, (2, 2), (2, 2), (1, 1), (1, 1), True, True, (15, 15, 16), (0, 1), ], [ "nn.max_pool2d", uint8_dtype, (2, 2), (2, 2), (3, 2), (1, 1), True, True, (15, 15, 16), (1, 0), ], [ "nn.avg_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (1, 1), False, False, (16, 16, 16), (0, 1), ], [ "nn.avg_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (0, 0), False, True, (16, 16, 16), (0, 1), ], [ "nn.avg_pool2d", fp32_dtype, (3, 3), (2, 2), (3, 2), (0, 1), True, False, (15, 15, 16), (1, 0), ], # 20.05: "exclude_padding equal false is not supported for AVG Pooling with padding on quantized types" # ["nn.avg_pool2d", uint8_dtype, (2, 2), (2, 2), (1, 1), False, True, (16, 16, 16)], [ "nn.avg_pool2d", uint8_dtype, (3, 3), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1), ], [ "nn.l2_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (0, 1), True, False, (16, 16, 16), (0, 1), ], [ "nn.l2_pool2d", fp32_dtype, (3, 3), (2, 2), (1, 1), (0, 0), False, False, (16, 16, 16), (0, 1), ], [ "nn.l2_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (1, 1), False, True, (15, 15, 16), (0, 1), ], ] # fmt: on for ( typef, (dtype, low, high, atol, rtol), size, stride, dilation, pad, ceil_mode, count_include_pad, input_shape, (tvm_ops, acl_partitions), ) in trials: shape = (1, *input_shape) outputs = [] inputs = { "a": tvm.nd.array(np.random.uniform(low, high, shape).astype(dtype)), } func = _get_pooling_model( shape, dtype, typef, size, stride, dilation, pad, ceil_mode, count_include_pad, iter(inputs), ) config = { "size": size, "stride": stride, "shape": shape, "pooling type": typef, "dtype": dtype, "padding": pad, "dilation": dilation, "ceil_mode": ceil_mode, "count_include_pad": count_include_pad, "inputs": inputs, } verify_saturation = True if dtype == "uint8" else False for acl in [False, True]: outputs.append( build_and_run( func, inputs, 1, None, device, enable_acl=acl, tvm_ops=tvm_ops, acl_partitions=acl_partitions, config=config, )[0]) verify(outputs, atol=atol, rtol=rtol, config=config, verify_saturation=verify_saturation)
def test_qnn_dense(): Device.load("test_config.json") if skip_runtime_test(): return device = Device() np.random.seed(0) dtype = "uint8" trials = [ [(1, 2), (2, 2), 2, True], [(1, 2), (2, 2), 2, False], [(4, 4), (4, 4), 4, True], [(4, 4), (4, 4), 4, False], [(16, 16), (4, 16), 4, True], [(16, 16), (4, 16), 4, False], [(1, 128), (16, 128), 16, True], [(1, 128), (16, 128), 16, False], [(32, 32), (32, 32), 32, True], [(32, 32), (32, 32), 32, False], [(1, 64), (1, 64), 1, True], [(1, 64), (1, 64), 1, False], ] for shape, weight_shape, units, composite in trials: outputs = [] inputs = { "a": tvm.nd.array(np.random.uniform(0, 255, shape).astype(dtype)) } input_zp = 100 input_sc = 0.5 kernel_zp = 50 kernel_sc = 0.03 output_zp, output_sc = _get_qnn_params(input_zp, input_sc, kernel_zp, kernel_sc, weight_shape[0], weight_shape[1]) func, params = _get_qnn_model( shape, weight_shape, units, dtype, input_zp, input_sc, kernel_zp, kernel_sc, output_zp, output_sc, var_names=iter(inputs), has_bias=composite, ) for acl in [False, True]: outputs.append( build_and_run( func, inputs, 1, params, device, enable_acl=acl, )[0]) config = { "shape": shape, "weight_shape": weight_shape, "units": units, "dtype": dtype, "composite operators (bias)": composite, "input scale": input_sc, "input zero point": input_zp, "kernel scale": kernel_sc, "kernel zero point": kernel_zp, "output scale": output_sc, "output zero point": output_zp, } verify(outputs, atol=1, rtol=0, config=config, verify_saturation=True)
def test_qnn_conv2d(): Device.load("test_config.json") if skip_runtime_test(): return device = Device() np.random.seed(0) dtype = "uint8" trials = [ # Normal convolution [2, 2, (1, 1), (1, 1), (1, 1), 4, (10, 10, 14), (False, False, False), False], [2, 1, (2, 2), (1, 1), (1, 1), 7, (12, 15, 16), (False, False, True), False], [3, 3, (2, 1), (1, 1), (1, 1), 4, (10, 10, 14), (False, True, False), False], [3, 3, (1, 1), (1, 1), (1, 1), 16, (12, 15, 16), (False, False, False), False], [5, 5, (1, 1), (2, 2), (1, 1), 4, (10, 10, 14), (True, False, False), False], [1, 3, (1, 1), (1, 1), (1, 1), 7, (20, 20, 20), (False, False, True), False], [2, 2, (2, 2), (1, 1), (1, 1), 4, (20, 20, 20), (False, True, False), False], [5, 5, (1, 1), (2, 2), (1, 1), 4, (10, 10, 14), (True, False, False), False], [3, 3, (2, 1), (1, 1), (1, 1), 7, (20, 20, 20), (False, False, False), False], [3, 3, (1, 1), (2, 2), (1, 1), 16, (10, 10, 14), (False, True, True), False], # Depth-wise convolution [3, 3, (1, 1), (1, 1), (1, 1), 20, (20, 20, 20), (False, False, True), True], [5, 5, (2, 2), (1, 1), (1, 1), 20, (20, 20, 20), (False, True, False), True], [3, 3, (2, 2), (2, 2), (1, 1), 14, (10, 10, 14), (True, False, False), True], [5, 5, (0, 0), (1, 1), (1, 1), 20, (20, 20, 20), (False, False, False), True], [3, 3, (1, 1), (2, 2), (1, 1), 14, (10, 10, 14), (False, True, True), True], ] for ( kernel_h, kernel_w, pad, stride, dilation, out_channels, shape, composite, is_depthwise, ) in trials: shape = (1, *shape) if is_depthwise: groups = shape[3] else: groups = 1 outputs = [] inputs = {"a": tvm.nd.array(np.random.uniform(0, 255, shape).astype(dtype))} input_zp = 100 input_sc = 0.5 kernel_zp = 25 kernel_sc = 0.03 output_zp, output_sc = _get_qnn_params( input_zp, input_sc, kernel_zp, kernel_sc, kernel_h, kernel_w, shape[3] ) func, params = _get_qnn_model( shape, kernel_h, kernel_w, pad, stride, dilation, groups, dtype, out_channels, input_zp, input_sc, kernel_zp, kernel_sc, output_zp, output_sc, iter(inputs), has_pad=composite[0], has_bias=composite[1], has_activation=composite[2], ) for acl in [False, True]: outputs.append(build_and_run(func, inputs, 1, params, device, enable_acl=acl)[0]) config = { "shape": shape, "groups": groups, "kernel size": (kernel_h, kernel_w), "padding": pad, "stride": stride, "dilation": dilation, "out channels": out_channels, "composite operators (pad, bias, activation)": composite, "input scale": input_sc, "input zero point": input_zp, "kernel scale": kernel_sc, "kernel zero point": kernel_zp, "output scale": output_sc, "output zero point": output_zp, } atol = 2 if is_depthwise else 1 verify(outputs, atol=atol, rtol=0, config=config, verify_saturation=True)