diff options
author | Tim Hall <tim.hall@arm.com> | 2020-10-20 18:54:20 +0100 |
---|---|---|
committer | Tim Hall <tim.hall@arm.com> | 2020-10-21 15:23:33 +0100 |
commit | 4ed38bce498e1b9a5ae917316323de444792521a (patch) | |
tree | f3721d7131eeafa14c33cf0339d579de99a3c66a /ethosu/vela/operation.py | |
parent | 9358296a51b9186335304a53bd7ea5dfbe5322d8 (diff) | |
download | ethos-u-vela-4ed38bce498e1b9a5ae917316323de444792521a.tar.gz |
vela: Refactor operators to use Kernel objects
- Normalise kernel availability by requiring all operators offer a kernel
describing how much data they consume from the source, per OFM element,
regardless of whether kernels are relevant to the operation.
Signed-off-by: Tim Hall <tim.hall@arm.com>
Change-Id: Idbcff64879fc2eccf292b6208a7d2038eb388017
Diffstat (limited to 'ethosu/vela/operation.py')
-rw-r--r-- | ethosu/vela/operation.py | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/ethosu/vela/operation.py b/ethosu/vela/operation.py index 6e5b4820..cc52ff4b 100644 --- a/ethosu/vela/operation.py +++ b/ethosu/vela/operation.py @@ -18,6 +18,11 @@ from collections import namedtuple from enum import Enum +from .numeric_util import full_shape + +PointXY = namedtuple("PointXY", "x y") +PointXYZ = namedtuple("PointXYZ", "x y z") + class NpuBlockType(Enum): Default = 0 @@ -29,6 +34,26 @@ class NpuBlockType(Enum): ReduceSum = 6 +class Kernel: + def __init__(self, w, h, sx=1, sy=1, dx=1, dy=1): + assert sx > 0 and sy > 0 + assert dx > 0 and dy > 0 + self.width = w + self.height = h + self.stride = PointXY(sx, sy) + self.dilation = PointXY(dx, dy) + self.upscale = 1 + + def elements_wh(self): + return self.width * self.height + + def area_width(self): + return (self.width - 1) * self.dilation.x + 1 + + def area_height(self): + return (self.height - 1) * self.dilation.y + 1 + + # Classifies operators of type Custom class CustomType(Enum): ThirdPartyOp = 0 # Third party custom op @@ -330,6 +355,7 @@ class Operation: "memory_function", "forced_output_quantization", "activation_lut", + "_kernel", ) def __init__(self, op_type, name): @@ -350,6 +376,7 @@ class Operation: self.scheduled_pass = None self.op_index = None # input network operator index self.activation_lut = None + self._kernel = None def clone(self, suffix="_clone"): res = Operation(self.type, self.name + suffix) @@ -372,6 +399,21 @@ class Operation: __repr__ = __str__ + @property + def kernel(self): + strides = self.attrs.get("strides", (1, 1, 1, 1)) + dilation = self.attrs.get("dilation", (1, 1, 1, 1)) + weights = self.weights + if weights and self.type.npu_block_type in (NpuBlockType.ConvolutionDepthWise, NpuBlockType.ConvolutionMxN): + weight_shape = full_shape(4, weights.shape, 1) + k_h = weight_shape[-4] + k_w = weight_shape[-3] + else: + k_h = self.attrs.get("filter_height", 1) + k_w = self.attrs.get("filter_width", 1) + self._kernel = Kernel(k_w, k_h, strides[2], strides[1], dilation[2], dilation[1]) + return self._kernel + def get_ifm_ifm2_weights_ofm(self): return self.ifm, self.ifm2, self.weights, self.ofm |