Skip to content

Conversation

@melsonlai
Copy link
Contributor

This commit implements the basic structure of Android NNAPI codegen with the BYOC mechanism:

  • Basic graph partition using pattern-based rules
  • RPC-based graph partition
  • relay.ext.android_nnapi BYOC codegen

[RFC][BYOC] Android NNAPI Integration

Thanks for contributing to TVM! Please refer to guideline https://tvm.apache.org/docs/contribute/ for useful information and tips. After the pull request is submitted, please request code reviews from Reviewers by @ them in the pull request thread.

@melsonlai
Copy link
Contributor Author

cc @comaniac @zhiics

Copy link
Contributor

@comaniac comaniac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late review. In general as I mentioned in the RFC, this PR is too large for people to review and I believe this is the major reason why it's hard to collect feedbacks. I just reviewed the high-level Python parts and will try to review the rest parts when I got time. Meanwhile, It would be better to remove most non-infra parts such as operators first and send follow-up PRs.

In addition, I'm still not very comfortable with the way of verifying the generated C++ code using text comparison. After the NNAPI compiler is available in the CI, we could just verify if the generated code can be successfully compiled, but we probably cannot verify its run time functionality as other BYOC backends.

cc @zhiics

Comment on lines 36 to 37
Note
----
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Note
----
Notes
-----

from .converter import Converter


def convert_relayir_to_nnapi(func):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I won't call this "convert". Following the naming convention of existing BYOC backends, this is the codegen/compiler of NNAPI, so I'll probably just call it nnapi_compiler. Also, can you register it like the following?

@tvm._ffi.register_func("relay.ext.nnapicompiler")
def nnapi_compiler(func):

Meanwhile, the directory name relayir_to_nnapi_converter should also be improved. Maybe just name it compiler or codegen.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I plan to name it "codegen" if that's OK. (I don't want to collide with the Python built-in function "compile")
As an extra explanation that matters, the external compiler is actually a C++ stub in src/relay/backend/contrib/android_nnapi/codegen.cc, and it's that thing that gets registered as relay.ext.android_nnapi.
The existence of the C++ stub is a historical issue, however, it's not a complex file after all, so would you agree if I completely remove the C++ stub and make all of relay.ext.android_nnapi pythonic?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We actually prefer a reverse way that makes most of the implementations in C++ instead of Python for better performance. However, given that would be a huge effort, it should be fine for this specific backend to be all in Python IMHO.

-------
dtype: str
dtype of the queried operand

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove empty line. (ditto to other functions in all Python files).

"""Converts a Relay IR Function into Android NNAPI C++ class

Parameters
----------------------
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
----------------------
----------


"""

DEFAULT_OPTIONS = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add more comments to explain each fields, such as name and api_level.

Comment on lines 100 to 102
if value_dict["type"] == "memory_ptr":
return value_dict["value"]
assert False, "Unreachable"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if value_dict["type"] == "memory_ptr":
return value_dict["value"]
assert False, "Unreachable"
assert value_dict["type"] == "memory_ptr":
return value_dict["value"]

So that you don't need to disable inconsistent-return-statements.


Returns
-------
obj:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type?

return None
return self._export_obj["constants"][value_dict["value"]]

def is_FuseCode(self, idx): # pylint: disable=invalid-name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def is_FuseCode(self, idx): # pylint: disable=invalid-name
def is_fuse_code(self, idx):

Comment on lines 144 to 151
if value not in {
"ANEURALNETWORKS_FUSED_NONE",
"ANEURALNETWORKS_FUSED_RELU",
"ANEURALNETWORKS_FUSED_RELU1",
"ANEURALNETWORKS_FUSED_RELU6",
}:
return False
return True
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if value not in {
"ANEURALNETWORKS_FUSED_NONE",
"ANEURALNETWORKS_FUSED_RELU",
"ANEURALNETWORKS_FUSED_RELU1",
"ANEURALNETWORKS_FUSED_RELU6",
}:
return False
return True
return value in {
"ANEURALNETWORKS_FUSED_NONE",
"ANEURALNETWORKS_FUSED_RELU",
"ANEURALNETWORKS_FUSED_RELU1",
"ANEURALNETWORKS_FUSED_RELU6",
}


def convert(self, func):
"""Converts a Relay IR Function into Android NNAPI C++ class source code
Parameters
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add an empty line.

@melsonlai
Copy link
Contributor Author

Hey Cody, thank you for taking time to review this. I really appreciate this.

For the suggestion of removing operator implementations in this PR, I would agree that this would make the PR smaller, but please do take note that the main body of this PR is already infrastructure, so removing operators would not help much.

The tests can be made to test for compilability only instead of text comparing, and I'll do this on the next commit to this branch.

Apart from these, it looks like there's a few coding style/document suggestions, so I'll keep working on the refactor.

melsonlai added 11 commits July 31, 2021 22:25
This commit implements the basic structure of Android NNAPI
codegen with the BYOC mechanism:

* Basic graph partition using pattern-based rules
* RPC-based graph partition
* relay.ext.android_nnapi BYOC codegen
               for operator testing of Android NNAPI BYOC

s.a. PR #8076
               all of Android NNAPI BYOC Pythonic

s.a. PR #8076
               costs between TVM and Android NNAPI in the RPC
               partitioner

s.a. PR #8076
@melsonlai melsonlai requested a review from comaniac August 9, 2021 03:19
@masahi
Copy link
Member

masahi commented Jan 9, 2022

what's the status of this PR?

@comaniac
Copy link
Contributor

comaniac commented Jan 9, 2022

Thanks for reminding. I'm closing this PR for now as @melsonlai is no longer working on this RFC. The guy that takes over his work will file a new one later.

@FabianSchuetze
Copy link

May I ask how this PR is going and with what it has been replaced, @comaniac ?

Is there still interested in implenting and NnApi backend for TVM? If so, what would the next steps have to be for it?

@comaniac
Copy link
Contributor

comaniac commented Nov 5, 2023

Unfortunately the group of authors worked on this PR was no longer contributing due to their own reason, so AFAIK there's no plan for NNAPI upstreaming ATM. You are welcome to propose one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants