Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions tests/lint/pylint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ set -euxo pipefail
python3 -m pylint python/tvm --rcfile="$(dirname "$0")"/pylintrc
python3 -m pylint vta/python/vta --rcfile="$(dirname "$0")"/pylintrc
python3 -m pylint tests/python/unittest/test_tvmscript_type.py --rcfile="$(dirname "$0")"/pylintrc
python3 -m pylint tests/python/contrib/test_cmsisnn --rcfile="$(dirname "$0")"/pylintrc

17 changes: 17 additions & 0 deletions tests/python/contrib/test_cmsisnn/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Infrastructure and tests for CMSIS-NN"""
22 changes: 12 additions & 10 deletions tests/python/contrib/test_cmsisnn/test_binary_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,26 @@
"""CMSIS-NN integration tests: binary ops"""

import itertools
import sys

import numpy as np
from enum import Enum
import pytest

import tvm
from tvm import relay
from tvm.relay.op.contrib import cmsisnn
from tvm.testing.aot import generate_ref_data, AOTTestModel, compile_and_run
from tvm.micro.testing.aot_test_utils import (
AOT_USMP_CORSTONE300_RUNNER,
)

from utils import (
from .utils import (
skip_if_no_reference_system,
make_module,
make_qnn_relu,
get_range_for_dtype_str,
assert_partitioned_function,
assert_no_external_function,
)
from tvm.testing.aot import generate_ref_data, AOTTestModel, compile_and_run
from tvm.micro.testing.aot_test_utils import (
AOT_CORSTONE300_RUNNER,
AOT_USMP_CORSTONE300_RUNNER,
)


def generate_tensor_constant():
Expand Down Expand Up @@ -104,6 +101,7 @@ def make_model(
def test_op_int8(
op, relu_type, input_0_scale, input_0_zero_point, input_1_scale, input_1_zero_point
):
"""Tests QNN Conv2D operator for CMSIS-NN"""
interface_api = "c"
use_unpacked_api = True
test_runner = AOT_USMP_CORSTONE300_RUNNER
Expand Down Expand Up @@ -147,8 +145,10 @@ def test_op_int8(
)


# At least one of the inputs is a constant, both can't be variables, both can't be scalars
def parameterize_for_constant_inputs(test):
"""Generates parameters in such a way so that at least one of the inputs is a constant,
both can't be variables, both can't be scalars.
"""
op = [relay.qnn.op.mul, relay.qnn.op.add]
input_0 = [generate_variable("input_0"), generate_tensor_constant(), generate_scalar_constant()]
input_1 = [generate_variable("input_1"), generate_tensor_constant(), generate_scalar_constant()]
Expand Down Expand Up @@ -178,6 +178,7 @@ def parameterize_for_constant_inputs(test):
@tvm.testing.requires_cmsisnn
@parameterize_for_constant_inputs
def test_constant_input_int8(op, input_0, input_1):
"""Tests binary ops where one of the operands is a constant"""
interface_api = "c"
use_unpacked_api = True
test_runner = AOT_USMP_CORSTONE300_RUNNER
Expand Down Expand Up @@ -231,9 +232,9 @@ def test_constant_input_int8(op, input_0, input_1):
def test_both_scalar_inputs_int8(
op,
):
"""Tests binary ops where both operands are scalars"""
input_scale = 0.256
input_zero_point = 33
dtype = "int8"
model = make_model(
op,
generate_scalar_constant(),
Expand All @@ -257,6 +258,7 @@ def test_invalid_parameters(
op,
input_dtype,
):
"""Tests binary ops for non int8 dtypes"""
input_scale = 0.256
input_zero_point = 33
model = make_model(
Expand Down
25 changes: 15 additions & 10 deletions tests/python/contrib/test_cmsisnn/test_conv2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@
from tvm.testing.aot import generate_ref_data, AOTTestModel, compile_models, compile_and_run

from tvm.micro.testing.aot_test_utils import AOT_USMP_CORSTONE300_RUNNER
from utils import (
skip_if_no_reference_system,
from .utils import (
make_module,
get_range_for_dtype_str,
get_same_padding,
Expand Down Expand Up @@ -76,15 +75,15 @@ def make_model(
shape = (shape[0], shape[1] + p[0] + p[2], shape[2] + p[1] + p[3], shape[3])

rng = np.random.default_rng(12321)
w = tvm.nd.array(
weight = tvm.nd.array(
rng.integers(
np.iinfo(kernel_dtype).min,
high=np.iinfo(kernel_dtype).max,
size=kernel_shape,
dtype=kernel_dtype,
)
)
weight_const = relay.const(w, kernel_dtype)
weight_const = relay.const(weight, kernel_dtype)
conv = relay.qnn.op.conv2d(
invar,
weight_const,
Expand All @@ -102,8 +101,8 @@ def make_model(
padding=p,
out_dtype="int32",
)
b = tvm.nd.array(rng.integers(0, high=10, size=(out_channels,), dtype="int32"))
bias_const = relay.const(b, "int32")
bias = tvm.nd.array(rng.integers(0, high=10, size=(out_channels,), dtype="int32"))
bias_const = relay.const(bias, "int32")
last_op = relay.nn.bias_add(conv, bias_const, axis=3) if enable_bias else conv
requant_input_sc = [sc * input_scale for sc in kernel_scale]
last_op = relay.qnn.op.requantize(
Expand All @@ -115,7 +114,7 @@ def make_model(
out_dtype=dtype,
)
last_op = make_qnn_relu(last_op, relu_type, output_scale, output_zero_point, dtype)
params = {"w": w, "b": b}
params = {"w": weight, "b": bias}
return last_op, params


Expand All @@ -134,9 +133,9 @@ def test_conv2d_number_primfunc_args(
kernel_scale,
out_channels,
):
"""Tests number of arguments in Conv2D primfunc"""
interface_api = "c"
use_unpacked_api = True
test_runner = AOT_USMP_CORSTONE300_RUNNER

ifm_shape = (1, 64, 100, 4)
kernel_size = (3, 3)
Expand Down Expand Up @@ -204,7 +203,7 @@ def test_conv2d_number_primfunc_args(
expected_num_params = 6 if enable_bias else 5
cmsisnn_tir_mod = None
for target, mod in compiled_models[0].executor_factory.lowered_ir_mods.items():
if "cmsis-nn" == target.kind.name:
if target.kind.name == "cmsis-nn":
cmsisnn_tir_mod = mod

cmsisnn_func = cmsisnn_tir_mod["tvmgen_default_cmsis_nn_main_0"]
Expand All @@ -230,6 +229,7 @@ def test_conv2d_symmetric_padding_int8(
kernel_scale,
out_channels,
):
"""Tests QNN Conv2D where the padding is symmetric on both sides of input"""
interface_api = "c"
use_unpacked_api = True
test_runner = AOT_USMP_CORSTONE300_RUNNER
Expand Down Expand Up @@ -319,6 +319,7 @@ def test_conv2d_asymmetric_padding_int8(
kernel_scale,
out_channels,
):
"""Tests QNN Conv2D where the padding is asymmetric on different sides of input"""
interface_api = "c"
use_unpacked_api = True
test_runner = AOT_USMP_CORSTONE300_RUNNER
Expand Down Expand Up @@ -390,13 +391,15 @@ def test_conv2d_asymmetric_padding_int8(
)


# pylint: disable=import-outside-toplevel
@tvm.testing.requires_cmsisnn
@pytest.mark.parametrize("ifm_shape", [(1, 55, 55, 3)])
@pytest.mark.parametrize("kernel_shape", [(3, 2), (1, 3)])
@pytest.mark.parametrize("strides, dilation", [((3, 2), (1, 1))])
@pytest.mark.parametrize("padding", ["SAME", "VALID"])
@pytest.mark.parametrize("activation", ["NONE", "RELU"])
def test_conv2d_int8_tflite(ifm_shape, kernel_shape, strides, dilation, padding, activation):
"""Compares TVM output against TFLite output"""
interface_api = "c"
use_unpacked_api = True
test_runner = AOT_USMP_CORSTONE300_RUNNER
Expand Down Expand Up @@ -460,6 +463,7 @@ def test_depthwise_int8(
out_channels,
depth_multiplier,
):
"""Tests QNN Depthwise int8 op via CMSIS-NN"""
interface_api = "c"
use_unpacked_api = True
test_runner = AOT_USMP_CORSTONE300_RUNNER
Expand Down Expand Up @@ -537,6 +541,7 @@ def test_depthwise_int8(


def parameterize_for_invalid_model(test):
"""Generates non int8 inputs"""
in_dtype = ["uint8", "int8"]
kernel_dtype = ["uint8", "int8"]
kernel_zero_point = [-33, 10, 0]
Expand All @@ -560,12 +565,12 @@ def test_invalid_parameters(
kernel_dtype,
kernel_zero_point,
):
"""Tests Depthwise op for non int8 inputs"""
ifm_shape = (1, 28, 28, 12)
out_channels = 2
input_scale = 1
input_zero_point = 24
kernel_scale = [0.11, 0.0237]
in_min, in_max = get_range_for_dtype_str(in_dtype)

kernel_layout = "HWIO"
kernel_shape = [3, 3, ifm_shape[3], out_channels]
Expand Down
Loading