aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Hall <tim.hall@arm.com>2022-03-16 16:31:57 +0000
committertim.hall <tim.hall@arm.com>2022-03-21 18:50:48 +0000
commit3c5cfe9e110b402f60fa7e1cdd5aa5e1c31bd511 (patch)
treec5db3f145a097293cacaaee4112cc30be3670b4c
parent845e23200d471e44f274940846e400d170b5ff37 (diff)
downloadethos-u-vela-3c5cfe9e110b402f60fa7e1cdd5aa5e1c31bd511.tar.gz
MLBEDSW-6298: MLCE: Unable to find a valid block config
- Fixed a bug due to ResizeBilinear modifying the attributes of a shared IFM - The ifm_resampling_mode is now an attribute of an operator rather than a tensor - Changed all calls to try_block_config() to use the attribute rather than recalculating it in multiple places Signed-off-by: Tim Hall <tim.hall@arm.com> Change-Id: I4641e9cd6b049bd4186776d98e3e751c5e5bcc06
-rw-r--r--ethosu/vela/high_level_command_to_npu_op.py22
-rw-r--r--ethosu/vela/operation.py3
-rw-r--r--ethosu/vela/scheduler.py2
-rw-r--r--ethosu/vela/tensor.py3
-rw-r--r--ethosu/vela/tflite_graph_optimiser.py7
5 files changed, 17 insertions, 20 deletions
diff --git a/ethosu/vela/high_level_command_to_npu_op.py b/ethosu/vela/high_level_command_to_npu_op.py
index f7c91aa..c822132 100644
--- a/ethosu/vela/high_level_command_to_npu_op.py
+++ b/ethosu/vela/high_level_command_to_npu_op.py
@@ -49,6 +49,7 @@ from .architecture_features import ArchitectureFeatures
from .data_type import DataType
from .debug_database import DebugDatabase
from .errors import UnsupportedFeatureError
+from .ethos_u55_regs.ethos_u55_regs import resampling_mode
from .high_level_command_stream import Box
from .high_level_command_stream import Command
from .high_level_command_stream import DMA
@@ -104,6 +105,14 @@ elementwise_op_map = {
}
+# inverse of the resampling_mode_map in the register command stream generator
+resampling_mode_inv_map = {
+ resampling_mode.NONE: NpuResamplingMode.NONE,
+ resampling_mode.NEAREST: NpuResamplingMode.NEAREST,
+ resampling_mode.TRANSPOSE: NpuResamplingMode.TRANSPOSE,
+}
+
+
def ifm_ifm2_correct_order(ifm_shape: List[int], ifm2_shape: List[int]) -> bool:
if ifm_shape == []:
# Scalar needs to be in IFM2
@@ -193,17 +202,6 @@ def get_mem_limits_for_regions(arch: ArchitectureFeatures) -> Dict[int, int]:
return mem_limits
-def get_upscale(op: Operation) -> NpuResamplingMode:
- upscale = NpuResamplingMode.NONE
- if op.type == Op.ResizeBilinear:
- # perform nearest neighbor upscale
- upscale = NpuResamplingMode.NEAREST
- elif op.type == Op.Conv2DBackpropInputSwitchedBias:
- # perform insert zero upscale
- upscale = NpuResamplingMode.TRANSPOSE
- return upscale
-
-
def get_double_buffer_offset(arch: ArchitectureFeatures, range_index: int, core: int) -> int:
"""Returns 0 if the first half of a double buffer should be used, 1 if the second half should be used"""
return ((range_index - core) // arch.ncores) % 2
@@ -409,7 +407,7 @@ def set_common_op_fields(npu_op: NpuBlockOperation, cmd: NpuStripe, arch: Archit
if not op.type.is_elementwise_op():
npu_op.padding = create_padding(cmd, op)
npu_op.kernel = to_npu_kernel(op.kernel)
- npu_op.ifm_upscale = get_upscale(op)
+ npu_op.ifm_upscale = resampling_mode_inv_map[op.ifm_resampling_mode]
return npu_op
diff --git a/ethosu/vela/operation.py b/ethosu/vela/operation.py
index 5a6423d..d5b92d8 100644
--- a/ethosu/vela/operation.py
+++ b/ethosu/vela/operation.py
@@ -31,6 +31,7 @@ from typing import Union
from .api import NpuRoundingMode
from .errors import VelaError
+from .ethos_u55_regs.ethos_u55_regs import resampling_mode
from .numeric_util import full_shape
from .shape4d import Shape4D
@@ -488,6 +489,7 @@ class Operation:
"low_precision_scaling",
"write_offset",
"write_shape",
+ "ifm_resampling_mode",
)
def __init__(self, op_type: Op, name: str):
@@ -530,6 +532,7 @@ class Operation:
# E.g. an operation that only fills the bottom row of an OFM of size 1x10x8x1 would have
# write_offset 0,9,0,0, write_shape 1,1,8,1
self.write_shape: Optional[Shape4D] = None
+ self.ifm_resampling_mode: resampling_mode = resampling_mode.NONE
def clone(self, suffix="_clone"):
res = Operation(self.type, self.name + suffix)
diff --git a/ethosu/vela/scheduler.py b/ethosu/vela/scheduler.py
index 73133bc..e8e4909 100644
--- a/ethosu/vela/scheduler.py
+++ b/ethosu/vela/scheduler.py
@@ -170,7 +170,7 @@ class SchedulerOperation:
self.op_type = ps.primary_op.type
self.activation = ps.primary_op.activation
self.kernel = ps.primary_op.kernel
- self.resampling_mode = ps.primary_op.ifm.resampling_mode
+ self.resampling_mode = ps.primary_op.ifm_resampling_mode
self.uses_scalar = ps.primary_op.ifm2 is not None and (
ps.primary_op.ifm.shape == [] or ps.primary_op.ifm2.shape == []
)
diff --git a/ethosu/vela/tensor.py b/ethosu/vela/tensor.py
index 19016a0..783f459 100644
--- a/ethosu/vela/tensor.py
+++ b/ethosu/vela/tensor.py
@@ -36,7 +36,6 @@ from .data_type import BaseType
from .data_type import DataType
from .errors import UnsupportedFeatureError
from .errors import VelaError
-from .ethos_u55_regs.ethos_u55_regs import resampling_mode
from .numeric_util import full_shape
from .operation import Op
from .operation import Operation
@@ -367,7 +366,6 @@ class Tensor:
"element_size_bytes",
"block_traversal",
"equivalence_id",
- "resampling_mode",
"src_tensor",
"needs_linear_format",
"ifm_write_protected",
@@ -414,7 +412,6 @@ class Tensor:
# quantization parameters
self.quantization: Optional[QuantizationParameters] = None
self.block_traversal: TensorBlockTraversal = TensorBlockTraversal.Default
- self.resampling_mode: resampling_mode = resampling_mode.NONE
self.needs_linear_format = True
self.ifm_write_protected = False
diff --git a/ethosu/vela/tflite_graph_optimiser.py b/ethosu/vela/tflite_graph_optimiser.py
index 576ead0..fb8a08c 100644
--- a/ethosu/vela/tflite_graph_optimiser.py
+++ b/ethosu/vela/tflite_graph_optimiser.py
@@ -268,7 +268,7 @@ def fixup_conv2d_backprop(op, arch, nng):
# flip the inputs
op.inputs[0], op.inputs[2] = op.inputs[2], op.inputs[0]
op.type = Op.Conv2DBackpropInputSwitchedBias
- op.ifm.resampling_mode = resampling_mode.TRANSPOSE
+ op.ifm_resampling_mode = resampling_mode.TRANSPOSE
# Update strides
op.attrs.update({"stride_w": 1, "stride_h": 1, "strides": (1, 1, 1, 1)})
@@ -312,7 +312,7 @@ def convert_resizebilinear_to_nearest_neighbor_upscaling_and_pool(op):
else:
shape_modifier = 0
op.attrs["padding"] = Padding.SAME
- op.inputs[0].resampling_mode = resampling_mode.NEAREST
+ op.ifm_resampling_mode = resampling_mode.NEAREST
upscaled_shape = np.array(op.ifm_shapes[0].get_hw_as_list())
out_shape = np.array(op.ofm_shapes[0].get_hw_as_list())
@@ -1128,7 +1128,6 @@ def convert_pad(op: Operation, arch, nng):
def add_attrs_to_resizebilinear(op, arch, nng):
if op.type == Op.ResizeBilinear and op.run_on_npu:
- input_tensor = op.inputs[0]
input_shape = op.ifm_shapes[0]
upscaled_height = input_shape.height * 2
upscaled_width = input_shape.width * 2
@@ -1147,7 +1146,7 @@ def add_attrs_to_resizebilinear(op, arch, nng):
op.attrs["padding"] = Padding.VALID
else:
return op
- input_tensor.resampling_mode = resampling_mode.NEAREST
+ op.ifm_resampling_mode = resampling_mode.NEAREST
op.attrs.update({"strides": (1, 1, 1, 1), "ksize": (1, 2, 2, 1)})
return op