Skip to content
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

[µTVM] Use standalone_crt build tree for all µTVM builds #7333

Merged
merged 15 commits into from
Feb 12, 2021

Conversation

areusch
Copy link
Contributor

@areusch areusch commented Jan 23, 2021

Right now due to historical reasons we sometimes build the CRT from build/standalone_crt and other times from src/runtime/crt. This PR consolidates building to always be from build/standalone_crt and updates several path computations to use that. Ultimately we'll need this if we expect microTVM to be useful when TVM has been pip installed rather than just built from source.

This is also helpful for autotuning, as we expect the autotvm runner to use standalone_crt to build the project. This PR also changes the default compiler options to reference the standalone_crt directory.

Finally, to properly separate the host main() and crt_config.h from the remaining reusable CRT libs, places these in a new directory standalone_crt/template along with the template crt_config.h.

@manupak
Copy link
Contributor

manupak commented Jan 29, 2021

Hi @areusch,

This is great!
Out of curiosity, the basic purpose of the PR is essentially move the crt sources to build directory right ? -- so that they get shipped with the wheel ?

@areusch
Copy link
Contributor Author

areusch commented Jan 29, 2021

@manupa-arm yeah correct--it revises all functions in tvm.micro to operate relative to either a default standalone_crt directory, which now resides in build, or to one you specify. for autotuning, this becomes more helpful as i've moved compilation to the runner, so the standalone_crt directory will be different than the default. but, it also will help in future cases where standalone_crt is included as a wheel data file and it is necessary to write it out to disk in a project-specific location.

areusch added a commit to areusch/tvm that referenced this pull request Feb 1, 2021
 * Make build/standalone_crt available to CI unit tests.
 * We could do this with stash but it's complex because we would need
   to use wildcards. Instead, rebuild standalone_crt source tree before testing.
areusch added a commit to areusch/tvm that referenced this pull request Feb 1, 2021
 * Make build/standalone_crt available to CI unit tests.
 * We could do this with stash but it's complex because we would need
   to use wildcards. Instead, rebuild standalone_crt source tree before testing.
areusch added a commit to areusch/tvm that referenced this pull request Feb 2, 2021
 * Make build/standalone_crt available to CI unit tests.
 * We could do this with stash but it's complex because we would need
   to use wildcards. Instead, rebuild standalone_crt source tree before testing.
tqchen pushed a commit that referenced this pull request Feb 8, 2021
@areusch
Copy link
Contributor Author

areusch commented Feb 9, 2021

@tqchen @manupa-arm @u99127 @gromero @tom-gall looks like this is ready for review

@gromero
Copy link
Contributor

gromero commented Feb 9, 2021

@areusch Hi Andrew. The change looks good (I'll differ the review of Jenkinsfile to others). I just suggest to fit docstrings of get_standalone_crt_dir and get_standalone_crt_lib() in 80 columns maximum. Also, a side note on the PR itself, if possible, I'd avoid merges in the middle of the incremental changes pushed to the branch to be reviewed, because it makes a tad difficult to squash the commits into the final change, in that sense I think rebasing on top of master is better. I tested micro_tflite.py against a disco board too and it's good. So, thumbs up from my side.

@areusch
Copy link
Contributor Author

areusch commented Feb 10, 2021

@gromero thanks for the review. unfortunately if you force-push (I.e. rebase) it loses the context around the previous comments, and I like that less :/. for line length, we're at 100 char, and pylint's enforcing that, so i'm keeping to that here.

Copy link
Contributor

@manupak manupak left a comment

Choose a reason for hiding this comment

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

Broadly looks fine. few clarifications and concerns.

@@ -55,15 +57,62 @@ def path(self):
CRT_RUNTIME_LIB_NAMES = ["utvm_rpc_server", "utvm_rpc_common", "common"]


TVM_ROOT_DIR = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..", ".."))
STANDALONE_CRT_DIR = None
Copy link
Contributor

Choose a reason for hiding this comment

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

Im not too sure whether we need this ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

do you mean that it's fine to just do the search every time?

Copy link
Contributor

Choose a reason for hiding this comment

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

oh you want to cache/memoize the function ... if thats the case, you might want to consider options to do that such using the memoize decorator, functools caches or maybe we can move variable inside of the function as it is not used by anyother ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we can, though functools.cache is new in 3.9 and lru_cache seems a bit complex. i think this way might almost be easier to debug. is there a different stdlib thing i'm missing?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm there is one other option you might want to consider -- you make it attr of the function -- thats python's way of having static variables. Anyway, Im not very fussed about it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok--I may opt to leave this as it's passing CI and there's a bunch of other pressing work.

The path to the standalone_crt
"""
global STANDALONE_CRT_DIR
if STANDALONE_CRT_DIR is None:
Copy link
Contributor

Choose a reason for hiding this comment

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

Again on the same question as above, however this kind of makes me think do we need something like an environment variable ? Maybe PassContext is a better option for that ? What do you think ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that ultimately these are going to become data dependencies of the tlcpack wheel and we don't have a standard facility to figure out where the data deps go. I think we should make such a thing in both Python and CMake and then it would reduce this function to: if not isdir(f'{data_dir}/standalone_crt'): raise CrtNotFoundError().

Copy link
Contributor

Choose a reason for hiding this comment

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

Ack

f"{TVM_ROOT_DIR}/include",
f"{TVM_ROOT_DIR}/3rdparty/dlpack/include",
f"{TVM_ROOT_DIR}/3rdparty/libcrc/include",
f"{TVM_ROOT_DIR}/3rdparty/dmlc-core/include",
Copy link
Contributor

Choose a reason for hiding this comment

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

[Clarification] do we not need them anymore or do they go inside build/crt/include ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

they go in build/standalone_crt/include according to cmake/modules/StandaloneCrt.cmake.

Copy link
Contributor

Choose a reason for hiding this comment

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

Alright!

_CRT_GENERATED_LIB_OPTIONS["cflags"].append("-Wno-unused-variable")
_CRT_GENERATED_LIB_OPTIONS["ccflags"].append("-Wno-unused-variable")
lib_opts = _build_default_compiler_options(standalone_crt_dir)
lib_opts["cflags"] = ["-Wno-error=incompatible-pointer-types"]
Copy link
Contributor

Choose a reason for hiding this comment

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

[Clarification] why is this needed suddenly ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it's on line 110 at main--I don't think it's a change here?

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh sorry I missed that!

@gromero
Copy link
Contributor

gromero commented Feb 10, 2021

@gromero thanks for the review. unfortunately if you force-push (I.e. rebase) it loses the context around the previous comments, and I like that less :/.

@areusch yeah.. I forgot about the "constraint" on push -f. Maybe the only thing we could do is to try to avoid merging in the middle of the incremental pushes (pushes due to the review process)? On the other hand that amounts to not doing a rebase on the top of the most fresh code in main, but I wonder if github and the CI is actually already covering what might go wrong if rebase is not done (github will check for merge conflicts on top of the main branch, but I'm not sure about the CI, I guess it only builds and tests the branch ones want to merge into main, i.e. it doesn't build the commits found in github's "Commits" tab on top of the main branch). Yep, tricky thing, merging in the middle of the incremental pushes for complicated changes might get really hard to review. I see.

@areusch
Copy link
Contributor Author

areusch commented Feb 10, 2021

@gromero easiest way to patch given merges might be something like:

$ git fetch origin main
$ git fetch areusch <pr>
$ git diff areusch/<pr>...origin/main >patch # NOTE 3 periods
$ git checkout $(merge-base areusch/<pr> origin/main)
$ git apply <patch

I think the rest is just limitations of this code-review system. I generally try to push -f until there's a comment on the thread

Copy link
Contributor Author

@areusch areusch left a comment

Choose a reason for hiding this comment

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

@manupa-arm thanks for the review!

@@ -55,15 +57,62 @@ def path(self):
CRT_RUNTIME_LIB_NAMES = ["utvm_rpc_server", "utvm_rpc_common", "common"]


TVM_ROOT_DIR = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..", ".."))
STANDALONE_CRT_DIR = None
Copy link
Contributor Author

Choose a reason for hiding this comment

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

do you mean that it's fine to just do the search every time?

The path to the standalone_crt
"""
global STANDALONE_CRT_DIR
if STANDALONE_CRT_DIR is None:
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that ultimately these are going to become data dependencies of the tlcpack wheel and we don't have a standard facility to figure out where the data deps go. I think we should make such a thing in both Python and CMake and then it would reduce this function to: if not isdir(f'{data_dir}/standalone_crt'): raise CrtNotFoundError().

f"{TVM_ROOT_DIR}/include",
f"{TVM_ROOT_DIR}/3rdparty/dlpack/include",
f"{TVM_ROOT_DIR}/3rdparty/libcrc/include",
f"{TVM_ROOT_DIR}/3rdparty/dmlc-core/include",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

they go in build/standalone_crt/include according to cmake/modules/StandaloneCrt.cmake.

_CRT_GENERATED_LIB_OPTIONS["cflags"].append("-Wno-unused-variable")
_CRT_GENERATED_LIB_OPTIONS["ccflags"].append("-Wno-unused-variable")
lib_opts = _build_default_compiler_options(standalone_crt_dir)
lib_opts["cflags"] = ["-Wno-error=incompatible-pointer-types"]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it's on line 110 at main--I don't think it's a change here?

@gromero
Copy link
Contributor

gromero commented Feb 10, 2021

@gromero easiest way to patch given merges might be something like:

$ git fetch origin main
$ git fetch areusch <pr>
$ git diff areusch/<pr>...origin/main >patch # NOTE 3 periods
$ git checkout $(merge-base areusch/<pr> origin/main)
$ git apply <patch

@areusch I see. I imagine that's the flow the committer will follow when squashing for the final commit to get merged into main? Because if one does a git rebase -i straight to the branch related to the PR with the incremental changes "intertwined" with the commits brought by the merges it would kind of a nightmare to squash afaics?

Now, I've just made a quick test and I see that the review comments (even the comments related to a line of code) haven't disappeared after a git push -f, so it does really keep the review history. What I did on the experiment for a PR under review was simply the following, whilst checked out in the PR branch (pr) and with an incremental change already committed to the branch:

git pull --rebase origin main
git push -f <my_repo> pr

The forced push and the new incremental change (plus the changes merged / pushed into main meanwhile) were all correctly displayed below the review comments posted previously to it.

Feel free to ping for a few tests if you want :)

I generally try to push -f until there's a comment on the thread

Yeah, that's what I do too.

@areusch
Copy link
Contributor Author

areusch commented Feb 10, 2021

@gromero yes, I think that's roughly what GH does when someone hits merge.

the review comments do stick around, but the context is usually obliterated, which is usually pretty crucial to understanding what they meant. maybe see if the old sha is still available after a few hours--GH may do a cleanup task internally

@gromero
Copy link
Contributor

gromero commented Feb 10, 2021

@gromero yes, I think that's roughly what GH does when someone hits merge.

Got it 👍

the review comments do stick around, but the context is usually obliterated, which is usually pretty crucial to understanding what they meant. maybe see if the old sha is still available after a few hours--GH may do a cleanup task internally

@areusch Amazing, indeed, after some time, when clicking on "View Changes" related to a commit that was rebased (and git pushed -f) I get:

We went looking everywhere, but couldn’t find those commits.
Sometimes commits can disappear after a force-push. Head back to the latest changes here.

The best part is "Sometimes commits can disappear... ". OK, I give up :P

@areusch
Copy link
Contributor Author

areusch commented Feb 11, 2021

Copy link
Contributor

@manupak manupak left a comment

Choose a reason for hiding this comment

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

LGTM

alexwong pushed a commit to alexwong/tvm that referenced this pull request Feb 11, 2021
@areusch
Copy link
Contributor Author

areusch commented Feb 12, 2021

@tmoreau89 @tqchen to merge

Copy link
Contributor

@tmoreau89 tmoreau89 left a comment

Choose a reason for hiding this comment

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

LGTM

@tmoreau89 tmoreau89 merged commit b8a8340 into apache:main Feb 12, 2021
@tmoreau89
Copy link
Contributor

Thank you @areusch @gromero @manupa-arm - the PR has been merged

Lokiiiiii pushed a commit to Lokiiiiii/tvm that referenced this pull request Mar 2, 2021
Lokiiiiii pushed a commit to Lokiiiiii/tvm that referenced this pull request Mar 2, 2021
* Build microTVM using standalone_crt in build tree.

* black format

* pylint

* try stashing entire standalone_crt in hopes it will not upset jenkins

* Put standalone_crt in correct Jenkinsfile stash bundle

* include build prefix

* switch to python script for expanding globs

* revert attempt to use globs in pack_libs, switch to building standalone_crt

* properly revert pack_lib changes

* fix typo

* retrigger CI

* revert pyproject.toml

* update Jenkinsfile approach to use task_ci_setup.sh
trevor-m pushed a commit to neo-ai/tvm that referenced this pull request Mar 2, 2021
trevor-m pushed a commit to neo-ai/tvm that referenced this pull request Mar 2, 2021
* Build microTVM using standalone_crt in build tree.

* black format

* pylint

* try stashing entire standalone_crt in hopes it will not upset jenkins

* Put standalone_crt in correct Jenkinsfile stash bundle

* include build prefix

* switch to python script for expanding globs

* revert attempt to use globs in pack_libs, switch to building standalone_crt

* properly revert pack_lib changes

* fix typo

* retrigger CI

* revert pyproject.toml

* update Jenkinsfile approach to use task_ci_setup.sh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants