-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Add Example for Cross Compilers #2909
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
|
I feel it might be more proper to have a new builder, e.g., |
|
You don’t have to pass these argument in. A growing number of args is exactly what we want to prevent from happening here. Instead, you can direct pass in a callable which is a functor that has those options baked in |
|
Maybe we can just create more built-in build_func and register them with proper name. |
|
We can add some of them if they are common. if there is still a lot of things to be configured, my guess is passing in a custom callback will be much cleaner |
19638f5 to
48007cc
Compare
|
@tqchen , @kevinthesun, @yzhliu Thank you for your quick feedbacks!
That solutions allows me to replace |
|
Let us stick with the original API and not introducing the new arguments. So with the existing API, you can already define a function The reason why we do not want to add new options to the Builder, is that these options only carry a few cases and sometimes users want more. Because build_func can already be functors, they can be customized to contain arbitrary code. For example, we can just define def my_cross_build(measure_input, tmp_dir, **kwargs):
tic = time.time()
try:
filename = os.path.join(tmp_dir, "tmp_func_%0x.so" % getrandbits(64))
func, arg_info = _build_func_common(measure_input, **kwargs)
func.export_library(filename, cc, **extra_options)
except Exception as e:
return BuildResult(None, None, e, time.time() - tic)
return BuildResult(filename, arg_info, None, time.time() - tic)If we want to complain that this is still too complicated, then we should do something to make it easier to do clean callback functional specification. Or perhaps create a functor that builds the functions |
|
@tqchen Can you look at the second (2nd) revision of the PR I posted on Mar 27? I just replaced |
|
My way is to |
48007cc to
55ae182
Compare
|
@tqchen I just submitted 3rd revision of the PR
This PR just replaces two identical methods |
| except Exception as e: # pylint: disable=broad-except | ||
| return BuildResult(None, None, e, time.time() - tic) | ||
| return BuildResult(filename, arg_info, None, time.time() - tic) | ||
| class DefaultBuilder: |
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.
Since we already have LocalBuilder and RPCBuilder, which work on a different level, this name is very confusing.
We can remove this class and implement it as a function create_build_func
def create_build_func(file_ext, fcompile, ...):
def build_func_(...):
...
return build_funcThere 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.
Agree on the name issue. I renamed DefaultBuilder to BuildFuncFactory. I think that using Class should be fine here. It incapsulates class params and build_func method.
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.
replaced class BuildFuncFactory with function make_build_func
293edd8 to
a0bf0e8
Compare
| return BuildResult(filename, arg_info, None, time.time() - tic) | ||
| class BuildFuncFactory: | ||
| def __init__(self, file_ext="tar", fcompile=None, **export_library_kwargs): | ||
| """ |
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.
put this doc string below the line of class BuildFuncFactory: to fix the lint error.
Typically, we put the doc string of __init__ function below class rather than the __init__ function
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.
Fixed the docs
a0bf0e8 to
5fdadf0
Compare
|
OK. You don't really need to have BuildFactory as a class. In python you can return closures, which means you can do things functionally. def make_build_func(args):
def my_build_func():
# code
return my_build_funcThis being said, we actually can get a better solution to this problem. What is a better solutionThe real reason why we are doing such a level of indirection was really due to the fact that the Consider the following code, which is much cleaner import tvm
from tvm.contrib import cc
def my_build_func(output, objects):
cc.create_shared(output, objects, cc="myg++", **mykwargs)
# annotate the library output format
my_build_func.lib_format = "so"
builder=autotvm.LocalBuilder(my_build_func)And we enhance the export_library to support the following case # notice no suffix here
# the default lib_format suffix will be attached if hasattr(my_build_func, "lib_format")
# otherwise a ValueError is raised.
lib.export_library("mylib", my_build_func)Now we can even get rid of the build_common, because we can just take cc.create_shared as the build_func (assuming we also set the right lib_format). What is even better, we can enhance create_shared to return a partial functor if you do not specify output and objects(this might go a bit far but may worth the effort) builder=autotvm.LocalBuilder(cc.create_shared(cc="myg++", options=myopts))Since this will require some changes to AutoTVM API, cc @merrymercy for thoughts |
5fdadf0 to
93a4522
Compare
|
@tqchen @merrymercy I replaced class |
|
If possible, it would be great if we can directly go with the better solution as per https://docs.tvm.ai/contribute/code_review.html#hold-the-highest-standard Mainly because the better solution is not too hard to get and we don't have to change the solution twice. perhaps @merrymercy can also coordinate/help on this. |
|
BTW, I find that there are useful design lessons that can be highlighted through the conversations of this PR. Mainly on
It would be really great we can learn from this, and summarize the lessons, and contribute that into design docs. |
|
@merrymercy After looking at existing |
93a4522 to
d1434d0
Compare
|
It would be great to take a few days to get the better solution out:) while it might take a bit more time, but it is always good to go with the best design we have. New code changes always comes with technical debt and it is important to avoid it. The reason that we are doing code review and discussion(instead of directly send in another PR) is to find time to improve the design and make everyone learn. |
tqchen
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.
Additional comments on the tutorials, besides the design improvement mentioned in the set of discussions :)
|
|
||
| # Cross compiler which will be used to export library to shared object (.so file) for edge device | ||
| # Edge device does not need to have build-essential package (gcc, g++, ld, etc) to be installed | ||
| cc = 'aarch64-linux-gnu-g++' |
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 need to add more follow up instructions on how to install such cross compiler as a part of note block, set the following flags to use cross gcc and default to False(because the on device compiler is still the easiest in many cases)
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 updated the PR:
- set
use_cross_compiler_to_export_lib=Falseby default - added instructions on how to install armv7/8 cross-compilers
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.
Please use the reStructured-text comment block
d1434d0 to
2f7a2e9
Compare
|
@merrymercy Looks like I addressed all of the comment above except of code refactoring for |
|
|
||
| # Cross compiler which will be used to export library to shared object (.so file) for edge device | ||
| # Edge device does not need to have build-essential package (gcc, g++, ld, etc) to be installed | ||
| cc = 'aarch64-linux-gnu-g++' |
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.
Please use the reStructured-text comment block
|
For reference, I have created #2927 which implemented the proposed better solution. |
|
Let me explain a bit why we don't want to merge the proposed change before the refactor. New features(use cross-compiler) is always exciting but also brings technical debt(backward compatibility and how the developer is going to use it). Given that the refactored ver is better and will also change the way things are being used. It is better to not introduce the new feature and always aim for the best solution. |
|
@apivovarov please rebase against the master and update the tutorial comments with note and code blocks |
I tried to run autotvm for custom ARM device recently and found that current autotvm requires edge device to have build tools (gcc, g++, ld) in order to link
tar(.o)file to.sofile.It might be a situation when custom ARM devices has minimal linux installation which does not have
gcc, g++ and ldtools installed. Also it might be missing package managers likeapt.I found that it is possible to cross compile and export shared object (
.sofile) for edge device on tracker side usingccparameter inlib.export_library.This PR replaces
default_build_funcandandroid_ndk_build_funcidentical methods with functionmake_build_funcreturningbuild_func.I also updated
tune_relay_mobile_gpu.pytutorial to demonstrate the use ofmake_build_functo generatesofile instead of defaulttarfile