blob: 58376d8b614c611963666030c9bafd27f435447e [file]
# 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.
import pytest
pytest.importorskip("ethosu.vela")
import tvm
from tvm.relay.backend.contrib.ethosu.tir.scheduler import OperatorCompute
import tvm.relay.backend.contrib.ethosu.codegen as codegen
import tensorflow as tf
from . import infra
@pytest.mark.parametrize(
"axis, ifm_shape, pool_shape",
[
(1, (1, 12, 1, 2), (3, 1)),
(1, (1, 12, 12, 2), (3, 3)),
(2, (1, 1, 12, 2), (1, 3)),
(2, (1, 12, 12, 2), (3, 3)),
],
)
def test_rolling_buffer_2_layers(axis, ifm_shape, pool_shape):
accel_type = "ethos-u55-256"
strides = (1, 1)
@tf.function
def tf_model(x):
padding = "VALID"
pool_0 = tf.nn.max_pool(x, pool_shape, strides, padding)
pool_1 = tf.nn.max_pool(pool_0, pool_shape, strides, padding)
return pool_1
def _cascader(cached_func, const_dict, sch):
pool_b_out = cached_func.outputs[0]
pool_b_compute = OperatorCompute.from_output(pool_b_out)
pool_a_out = pool_b_compute.read.op.input_tensors[0]
pool_a_compute = OperatorCompute.from_output(pool_a_out)
outer = pool_b_compute.split(sch, axis=axis, val=4)
pool_a_compute.compute_at(sch, stage=sch[pool_b_out], axis=outer)
pool_a_compute.rolling_buffer(sch)
codegen.SCHEDULER = lambda: _cascader
infra.compare_tvm_with_tflite(tf_model, [ifm_shape], accel_type)
@pytest.mark.parametrize(
"axis, ifm_shape, pool_shape",
[
(1, (1, 12, 1, 2), (3, 1)),
(1, (1, 12, 1, 17), (3, 1)),
(1, (1, 12, 12, 2), (3, 3)),
(1, (1, 12, 12, 17), (3, 3)),
(2, (1, 1, 12, 2), (1, 3)),
(2, (1, 1, 12, 17), (1, 3)),
(2, (1, 12, 12, 2), (3, 3)),
(2, (1, 12, 12, 17), (3, 3)),
],
)
def test_rolling_buffer_3_layers(axis, ifm_shape, pool_shape):
accel_type = "ethos-u55-256"
strides = (1, 1)
@tf.function
def tf_model(x):
padding = "VALID"
pool_0 = tf.nn.max_pool(x, pool_shape, strides, padding)
pool_1 = tf.nn.max_pool(pool_0, pool_shape, strides, padding)
pool_2 = tf.nn.max_pool(pool_1, pool_shape, strides, padding)
return pool_2
def _cascader(cached_func, const_dict, sch):
pool_b_out = cached_func.outputs[0]
pool_b_compute = OperatorCompute.from_output(pool_b_out)
pool_a_out = pool_b_compute.read.op.input_tensors[0]
pool_a_compute = OperatorCompute.from_output(pool_a_out)
outer = pool_b_compute.split(sch, axis=axis, val=4)
pool_a_compute.compute_at(sch, stage=sch[pool_b_out], axis=outer)
pool_a_compute.rolling_buffer(sch)
codegen.SCHEDULER = lambda: _cascader
infra.compare_tvm_with_tflite(tf_model, [ifm_shape], accel_type)
if __name__ == "__main__":
tvm.testing.main()