You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tvm.apache.org by GitBox <gi...@apache.org> on 2021/11/05 13:50:59 UTC

[GitHub] [tvm] NicolaLancellotti commented on a change in pull request #9457: Add the Arm(R) Ethos(TM)-U NPU identity operator

NicolaLancellotti commented on a change in pull request #9457:
URL: https://github.com/apache/tvm/pull/9457#discussion_r743598504



##########
File path: python/tvm/relay/backend/contrib/ethosu/te/dma.py
##########
@@ -67,63 +67,72 @@ def _pad(*indices):
     return _pad
 
 
-def read_compute(tensor: te.Tensor, layout: str, zero_point: int, scale: float) -> te.Tensor:
+def read_compute(tensor: te.Tensor, zero_point: int, scale: float, layout: str = None) -> te.Tensor:

Review comment:
       ```suggestion
   def read_compute(tensor: te.Tensor, zero_point: int, scale: float, layout: Optional[str] = None) -> te.Tensor:
   ```

##########
File path: src/relay/op/contrib/ethosu/identity.cc
##########
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+/*!
+ * \file src/relay/op/contrib/ethosu/identity.cc
+ * \brief Property def of the Arm Ethos-U identity op.

Review comment:
       ```suggestion
    * \brief Identity operator definition for the Arm(R) Ethos(TM)-U NPU.
   ```

##########
File path: python/tvm/relay/backend/contrib/ethosu/op/identity.py
##########
@@ -0,0 +1,98 @@
+# 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.
+# pylint: disable=unused-argument
+"""Relay identity operator"""

Review comment:
       ```suggestion
   """Relay operator for identity for Arm(R) Ethos(TM)-U NPU"""
   ```

##########
File path: python/tvm/relay/backend/contrib/ethosu/legalize.py
##########
@@ -123,6 +123,108 @@ def __call__(self, *args, **kwargs):
         pass
 
 
+class StridedSliceRewriter(DFPatternCallback):
+    """This pass brings the strided slice out of the partitioned function"""
+
+    def __init__(self):
+        super().__init__(require_type=True, rewrite_once=True)
+        self.pattern = (wildcard().has_attr({"Composite": "ethosu.strided_slice"}))(wildcard())
+
+    def callback(
+        self, pre: tvm.relay.Expr, post: tvm.relay.Expr, node_map: tvm.ir.container.Map
+    ) -> tvm.relay.Expr:
+        input = post.args[0]
+        attrs = post.op.body.attrs
+        begin = attrs.begin
+        end = attrs.end
+        strides = attrs.strides
+        axes = attrs.axes
+        slice_mode = attrs.slice_mode
+        strided_slice = relay.op.strided_slice(
+            input, begin, end, strides=strides, axes=axes, slice_mode=slice_mode
+        )
+        return strided_slice
+
+
+@ir.transform.module_pass(opt_level=1)
+class LegalizeStridedSlice:
+    """This is the pass that wraps StridedSliceRewriter"""
+
+    def transform_module(
+        self, mod: tvm.ir.IRModule, ctx: tvm.ir.transform.PassContext
+    ) -> tvm.ir.IRModule:
+        for global_var, func in mod.functions.items():
+            func = rewrite(StridedSliceRewriter(), func)
+            mod.update_func(global_var, func)
+        return mod
+
+    def __call__(self, *args, **kwargs):
+        pass
+
+
+class ReshapeRewriter(DFPatternCallback):
+    """This pass brings the reshape out of the partitioned function"""
+
+    def __init__(self):
+        super().__init__(require_type=True, rewrite_once=True)
+        self.pattern = (wildcard().has_attr({"Composite": "ethosu.reshape"}))(wildcard())
+
+    def callback(
+        self, pre: tvm.relay.Expr, post: tvm.relay.Expr, node_map: tvm.ir.container.Map
+    ) -> tvm.relay.Expr:
+        reshape_input = post.args[0]
+        new_shape = post.op.body.attrs.newshape
+        reshape = relay.op.reshape(reshape_input, newshape=new_shape)
+        return reshape
+
+
+@ir.transform.module_pass(opt_level=1)
+class LegalizeReshape:
+    """This is the pass that wraps ReshapeRewriter"""
+
+    def transform_module(
+        self, mod: tvm.ir.IRModule, ctx: tvm.ir.transform.PassContext
+    ) -> tvm.ir.IRModule:
+        for global_var, func in mod.functions.items():
+            func = rewrite(ReshapeRewriter(), func)
+            mod.update_func(global_var, func)
+        return mod
+
+    def __call__(self, *args, **kwargs):
+        pass
+
+
+class NoOpRewriter(DFPatternCallback):
+    """This pass adds and idenity operator to reshape and strided slice to avoid a no op without a consumer"""

Review comment:
       ```suggestion
       """This pass adds an identity operator to reshape and strided slice to avoid a no op without a consumer"""
   ```

##########
File path: src/relay/op/contrib/ethosu/identity.cc
##########
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+/*!
+ * \file src/relay/op/contrib/ethosu/identity.cc
+ * \brief Property def of the Arm Ethos-U identity op.
+ */
+#include <tvm/relay/op.h>
+
+#include "common.h"
+
+namespace tvm {
+namespace relay {
+namespace op {
+namespace contrib {
+namespace ethosu {
+
+/*! \brief Attributes used by the Ethos(TM)-U NPU identity operator */
+struct EthosuIdentityAttrs : public tvm::AttrsNode<EthosuIdentityAttrs> {
+  double ifm_scale;
+  int ifm_zero_point;
+  double ofm_scale;
+  int ofm_zero_point;
+  String activation;
+
+  TVM_DECLARE_ATTRS(EthosuIdentityAttrs, "relay.attrs.EthosuIdentityAttrs") {
+    TVM_ATTR_FIELD(ifm_scale).describe("The quantization scale for the Input Feature Map tensor.");
+    TVM_ATTR_FIELD(ifm_zero_point)
+        .describe("The quantization zero point for the Input Feature Map tensor.");
+    TVM_ATTR_FIELD(ofm_scale).describe("The quantization scale for the Output Feature Map tensor.");
+    TVM_ATTR_FIELD(ofm_zero_point)
+        .describe("The quantization zero point for the Output Feature Map tensor.");
+    TVM_ATTR_FIELD(activation)
+        .describe(
+            "The activation function to use. "
+            "'NONE' - no activation function. "
+            "'TANH' - tanh activation function. "
+            "'SIGMOID' - sigmoid activation function. "
+            "'LUT' - use a look-up table to perform the activation function.")
+        .set_default("NONE");
+  }
+};
+
+TVM_REGISTER_NODE_TYPE(EthosuIdentityAttrs);
+
+bool EthosuIdentityRel(const Array<Type>& types, int num_inputs, const Attrs& attrs,
+                       const TypeReporter& reporter) {
+  int ifm_index = 0;
+  int result_index = 2;
+  ICHECK_EQ(types.size(), result_index + 1);
+
+  const auto* ifm = types[ifm_index].as<TensorTypeNode>();
+  if (ifm == nullptr) return false;
+
+  const auto* param = attrs.as<EthosuIdentityAttrs>();
+
+  ICHECK(param != nullptr) << "EthosuIdentityAttrs cannot be nullptr.";
+
+  if (ifm->dtype != DataType::UInt(8) && ifm->dtype != DataType::Int(8)) {
+    reporter->GetDiagCtx().EmitFatal(
+        Diagnostic::Error(reporter->GetSpan())
+        << "Invalid operator: Expected type(uint8) or type(int8) for ifm but was " << ifm->dtype);
+    return false;
+  }
+
+  if (ifm->shape.size() > 4) {
+    reporter->GetDiagCtx().EmitFatal(
+        Diagnostic::Error(reporter->GetSpan())
+        << "Invalid operator: Input Feature Map should be at most 4 dimensional, but was "
+        << ifm->shape);
+    return false;
+  }
+
+  // Assign ofm type
+  auto ofm_shape = ifm->shape;
+  reporter->Assign(types[result_index], TensorType(ofm_shape, ifm->dtype));
+  return true;
+}
+
+Expr MakeEthosuIdentity(Expr ifm, Expr lut, double ifm_scale, int ifm_zero_point, double ofm_scale,
+                        int ofm_zero_point, String activation) {
+  auto attrs = make_object<EthosuIdentityAttrs>();
+  attrs->ifm_scale = ifm_scale;
+  attrs->ifm_zero_point = ifm_zero_point;
+  attrs->ofm_scale = ofm_scale;
+  attrs->ofm_zero_point = ofm_zero_point;
+  attrs->activation = std::move(activation);
+  static const Op& op = Op::Get("contrib.ethosu.identity");
+  return Call(op, {ifm, lut}, Attrs(attrs), {});
+}
+
+TVM_REGISTER_GLOBAL("relay.op._make.ethosu_identity").set_body_typed(MakeEthosuIdentity);
+
+RELAY_REGISTER_OP("contrib.ethosu.identity")
+    .describe(R"code(Identity operator for Ethos-U NPUs.

Review comment:
       ```suggestion
       .describe(R"code(Arm(R) Ethos(TM)-U NPU identity operator.
   ```

##########
File path: python/tvm/relay/backend/contrib/ethosu/te/dma.py
##########
@@ -67,63 +67,72 @@ def _pad(*indices):
     return _pad
 
 
-def read_compute(tensor: te.Tensor, layout: str, zero_point: int, scale: float) -> te.Tensor:
+def read_compute(tensor: te.Tensor, zero_point: int, scale: float, layout: str = None) -> te.Tensor:
     """A tensor expression which represents a read.
 
     Parameters
     ----------
     tensor : te.Tensor
         The tensor to read.
-    layout : str
-        The layout of the tensor, either NHWC or NHCWB16.
     zero_point : int
         The zero point of the tensor.
     scale : float
         The scale of the tensor.
+    layout : Optional[str]
+        The layout of the tensor, either NHWC or NHCWB16.
 
     Returns
     -------
     te.Tensor
         The tensor having been read.
 
     """
-    assert layout in {"NHWC", "NHCWB16"}
     read_attrs = {
         "op": "ethosu_read",
-        "layout": layout,
         "zero_point": zero_point,
         "scale": scale,
     }
+
+    if layout:
+        assert layout in {"NHWC", "NHCWB16"}
+        read_attrs["layout"] = layout
+
     return te.compute(tensor.shape, lambda *i: tensor(*i), name="ethosu_read", attrs=read_attrs)
 
 
-def write_compute(tensor: te.Tensor, layout: str, zero_point: int, scale: float) -> te.Tensor:
+def write_compute(
+    tensor: te.Tensor, zero_point: int, scale: float, layout: str = None

Review comment:
       ```suggestion
       tensor: te.Tensor, zero_point: int, scale: float, layout: Optional[str] = None
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@tvm.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org