-
Notifications
You must be signed in to change notification settings - Fork 3.8k
[microNPU] Add unary elementwise operator infrastructure with ABS #9530
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
lhutton1
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| params = self.params_class(post.op.body) | ||
| params.ifm.tensor = post.args[0] | ||
|
|
||
| if str(params.ofm.layout) != "NHWC": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC we agreed to remove these checks, please ignore if not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the other operators still have these checks so maybe we can remove them in a follow-up patch for all of the operators (or to be precise, I think we need to add some guards into the is_valid() checks to prevent attempting offloading graphs with non-NHWC layout...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries, I was referring to #9508 (comment) but didn't realize the other operators still had this check, I think a follow up would be fine :)
| while len(unary_input_shape) < 4: | ||
| unary_input_shape = [1] + unary_input_shape |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| while len(unary_input_shape) < 4: | |
| unary_input_shape = [1] + unary_input_shape | |
| pad_size = 4 - len(unary_input_shape) | |
| unary_input_shape = ([1] * pad_size) + unary_input_shape |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| ) -> vapi.NpuElementWiseOperation: | ||
| """This function will translate a tir extern_call | ||
| as produced by Relay to TIR compilation. | ||
| Parameters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: insert blank line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| quantize arguments | ||
| """ | ||
|
|
||
| ifm = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we missed this for binary elementwise also... should we follow convention here and use capitals?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done (i.e. changed both to use capitals)
| int ifm_index = 0; | ||
| int result_index = 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to make these const
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| << operator_type; | ||
|
|
||
| auto ifm_dtype = ifm->dtype; | ||
| ICHECK(ifm_dtype == DataType::UInt(8) || ifm_dtype == DataType::Int(8)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we use the TypeReporter here instead, similar to other operators?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well spotted :)
| attrs->ifm_zero_point = ifm_zero_point; | ||
| attrs->ofm_scale = ofm_scale; | ||
| attrs->ofm_zero_point = ofm_zero_point; | ||
| attrs->ofm_channels = ofm_channels; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| attrs->ofm_channels = ofm_channels; | |
| attrs->ofm_channels = std::move(ofm_channels); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| int clip_max, String ifm_layout, String ofm_layout) { | ||
| auto attrs = make_object<EthosuUnaryElementwiseAttrs>(); | ||
|
|
||
| attrs->operator_type = operator_type; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| attrs->operator_type = operator_type; | |
| attrs->operator_type = std::move(operator_type); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| mod, _ = relay.frontend.from_tflite( | ||
| tflite_model, | ||
| shape_dict={"input": ifm_shape}, | ||
| dtype_dict={"x": dtype}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| dtype_dict={"x": dtype}, | |
| dtype_dict={"input": dtype}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| f = run_opt_pass(f, relay.transform.InferType()) | ||
| assert tuple(f.body.checked_type.shape) == ofm_shape | ||
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also test invalid dtypes/shapes etc here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should ABS have a rounding mode as implemented in #9514?
Yes, well spotted, I added the rounding_mode attribute :)
| ethosu_unary_elementwise operators | ||
| """ | ||
|
|
||
| def __init__(self, params_class, pattern): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| def __init__(self, params_class, pattern): | |
| def __init__(self, params_class: Type, pattern: CallPattern): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| activation: str = "NONE", | ||
| clip_min: int = 0, | ||
| clip_max: int = 0, | ||
| ifm_layout: str = "NHWC", | ||
| ofm_layout: str = "NHWC", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| activation: str = "NONE", | |
| clip_min: int = 0, | |
| clip_max: int = 0, | |
| ifm_layout: str = "NHWC", | |
| ofm_layout: str = "NHWC", | |
| activation: Optional[str] = "NONE", | |
| clip_min: Optional[int] = 0, | |
| clip_max: Optional[int] = 0, | |
| ifm_layout: Optional[str] = "NHWC", | |
| ofm_layout: Optional[str] = "NHWC", |
The docstring says that they are optional.
Actually, we can get the same behaviour with the default values and the None value. Maybe in a future pr we should have only one way to archive that (for the other operators too).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the type hints for the unary elementwise operator, maybe in the follow-up patch we can unify the use for all the operators?
| """ | ||
| A class to extract and store parameters of Abs in an NPU friendly way | ||
| """ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring should follow the same convention adopted with the other *Parms classes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| << ifm_dtype; | ||
|
|
||
| // Assign ofm type | ||
| auto ofm_shape = EthosuInferBinaryElementwiseOutputShape(ifm->shape, param->ifm_layout, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should rename the function EthosuInferBinaryElementwiseOutputShape if it is used for the unary operators too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| import tvm | ||
| import tvm.script | ||
| from tvm import relay | ||
| from tvm.relay.testing import run_opt_pass | ||
| from tvm.relay.backend.contrib.ethosu.tir import spec | ||
| from tvm.relay.backend.contrib.ethosu.tir.compiler import lower_to_tir | ||
| from .infra import make_ethosu_unary_elementwise | ||
|
|
||
| import pytest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| import tvm | |
| import tvm.script | |
| from tvm import relay | |
| from tvm.relay.testing import run_opt_pass | |
| from tvm.relay.backend.contrib.ethosu.tir import spec | |
| from tvm.relay.backend.contrib.ethosu.tir.compiler import lower_to_tir | |
| from .infra import make_ethosu_unary_elementwise | |
| import pytest | |
| import pytest | |
| pytest.importorskip("ethosu.vela") | |
| import tvm | |
| import tvm.script | |
| from tvm import relay | |
| from tvm.relay.testing import run_opt_pass | |
| from tvm.relay.backend.contrib.ethosu.tir import spec | |
| from tvm.relay.backend.contrib.ethosu.tir.compiler import lower_to_tir | |
| from .infra import make_ethosu_unary_elementwise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
Should ABS have a rounding mode as implemented in #9514? |
* Added unary elementwise ABS legalization support and tests * Added unary_elementwise Relay to TIR lowering and tests * Added TIR to Vela translation and tests * Added codegen tests Co-authored-by: Rishabh Jain <rishabh.jain2@arm.com>
Change-Id: Ic963f1237bdbb493006fbb7e02dc1e5949c7ba46
bfdf1f4 to
415826e
Compare
NicolaLancellotti
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks, @ekalda.
lhutton1
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
manupak
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
|
Thanks all! |
…ache#9530) * [microNPU] Add unary elementwise operator infrastructure with ABS * Added unary elementwise ABS legalization support and tests * Added unary_elementwise Relay to TIR lowering and tests * Added TIR to Vela translation and tests * Added codegen tests Co-authored-by: Rishabh Jain <rishabh.jain2@arm.com>
…ache#9530) * [microNPU] Add unary elementwise operator infrastructure with ABS * Added unary elementwise ABS legalization support and tests * Added unary_elementwise Relay to TIR lowering and tests * Added TIR to Vela translation and tests * Added codegen tests Co-authored-by: Rishabh Jain <rishabh.jain2@arm.com>
…ache#9530) * [microNPU] Add unary elementwise operator infrastructure with ABS * Added unary elementwise ABS legalization support and tests * Added unary_elementwise Relay to TIR lowering and tests * Added TIR to Vela translation and tests * Added codegen tests Co-authored-by: Rishabh Jain <rishabh.jain2@arm.com>
…ache#9530) * [microNPU] Add unary elementwise operator infrastructure with ABS * Added unary elementwise ABS legalization support and tests * Added unary_elementwise Relay to TIR lowering and tests * Added TIR to Vela translation and tests * Added codegen tests Co-authored-by: Rishabh Jain <rishabh.jain2@arm.com>
…ache#9530) * [microNPU] Add unary elementwise operator infrastructure with ABS * Added unary elementwise ABS legalization support and tests * Added unary_elementwise Relay to TIR lowering and tests * Added TIR to Vela translation and tests * Added codegen tests Co-authored-by: Rishabh Jain <rishabh.jain2@arm.com>
Co-authored-by: Rishabh Jain rishabh.jain2@arm.com