-
Notifications
You must be signed in to change notification settings - Fork 3.7k
[Target] Add target host field for target specification #7462
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
Changes from all commits
940aeab
3c57ce6
a969fae
0d5d6d8
c395606
4c3a344
a1cc2c2
a1cb881
2f75e6c
3671378
71746c5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -376,7 +376,8 @@ inline TargetKindRegEntry& TargetKindRegEntry::set_name() { | |||
| .add_attr_option<String>("tag") \ | ||||
| .add_attr_option<String>("device") \ | ||||
| .add_attr_option<String>("model") \ | ||||
| .add_attr_option<Array<String>>("libs") | ||||
| .add_attr_option<Array<String>>("libs") \ | ||||
| .add_attr_option<Target>("host") | ||||
|
Comment on lines
+379
to
+380
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm just curious on how this plays with existing logic in tvm/python/tvm/relay/build_module.py Line 197 in b7e0cfb
Does this mean we now have two ways of declaring Also, in case the user declares both (doesn't make much sense, but can be done once this PR is meged), which one takes precedece, or, should we show an error? I'm referrin to something like cc @manupa-arm
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is super important question, so I answered on the thread below: #7462 (comment). Thank you Leandro for bringing this up! |
||||
|
|
||||
| } // namespace tvm | ||||
|
|
||||
|
|
||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,7 +46,7 @@ class Target(Object): | |
| - :py:func:`tvm.target.intel_graphics` create Intel Graphics target | ||
| """ | ||
|
|
||
| def __init__(self, tag_or_str_or_dict): | ||
| def __init__(self, tag_or_str_or_dict, host_tag_or_str_or_dict=None): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for the API, I would almost expect what would be the future path towards supporting multiple sub-targets? would there be a target_host object which contains all the sub-targets?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In terms of sub-targets, I think it will be better to converge to composite targets instead, where we can specify a list of targets as We can help create a short cut to construct the composite kind, like adding a static function @staticmethod
def composite(target, devices):
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In terms of API, that would be very good indeed! If internally we would convert that to represent the required
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @areusch as a follow-up to this, we've recently updated Check it out on #7304 for code and https://discuss.tvm.apache.org/t/byoc-partitioning-support-on-tvmc/8901 for discussion. |
||
| """Construct a TVM target object from | ||
| 1) Raw target string | ||
| 2) Target config dict | ||
|
|
@@ -86,10 +86,22 @@ def __init__(self, tag_or_str_or_dict): | |
| mfloat-abi : str (optional) | ||
| An llvm setting that is one of 'hard' or 'soft' indicating whether to use | ||
| hardware or software floating-point operations. | ||
| host : Union[str, Dict[str, Any]] (optional) | ||
| Description for target host. Can be recursive. Similar to tag_or_str_or_dict. | ||
| host_tag_or_str_or_dict : Optional[Union[str, Dict[str, Any]]] | ||
| Similar to tag_or_str_or_dict but for target host. Can be one of a literal | ||
| target host string, a json string describing a configuration, or a dictionary of | ||
| configuration options. When using a dictionary or json string to configure target, | ||
| the possible values are same as tag_or_str_or_dict. | ||
| """ | ||
| if not isinstance(tag_or_str_or_dict, (dict, str, Target)): | ||
| raise ValueError("target has to be a string or dictionary.") | ||
| self.__init_handle_by_constructor__(_ffi_api.Target, tag_or_str_or_dict) | ||
| if host_tag_or_str_or_dict is not None: | ||
| self.__init_handle_by_constructor__( | ||
| _ffi_api.Target, Target(tag_or_str_or_dict), Target(host_tag_or_str_or_dict) | ||
| ) | ||
| else: | ||
| self.__init_handle_by_constructor__(_ffi_api.Target, tag_or_str_or_dict) | ||
|
|
||
| def __enter__(self): | ||
| _ffi_api.TargetEnterScope(self) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,7 @@ | |
| # under the License. | ||
| import json | ||
| import tvm | ||
| import pytest | ||
| from tvm import te | ||
| from tvm.target import cuda, rocm, mali, intel_graphics, arm_cpu, vta, bifrost, hexagon | ||
|
|
||
|
|
@@ -113,18 +114,14 @@ def test_config_map(): | |
| attributes fails as expected. | ||
| """ | ||
| target_config = {"kind": "llvm", "libs": {"a": "b", "c": "d"}} | ||
| failed = False | ||
| try: | ||
| with pytest.raises(ValueError): | ||
| tvm.target.Target(target_config) | ||
| except ValueError: | ||
| failed = True | ||
| assert failed | ||
|
|
||
|
|
||
| def test_composite_target(): | ||
| tgt = tvm.target.Target("composite --target_host=llvm --devices=cuda,opencl") | ||
| tgt = tvm.target.Target("composite --host=llvm --devices=cuda,opencl") | ||
| assert tgt.kind.name == "composite" | ||
| assert tgt.attrs["target_host"].kind.name == "llvm" | ||
| assert tgt.attrs["host"].kind.name == "llvm" | ||
| assert len(tgt.attrs["devices"]) == 2 | ||
| cuda_device, opencl_device = tgt.attrs["devices"] | ||
| assert cuda_device.kind.name == "cuda" | ||
|
|
@@ -158,6 +155,70 @@ def test_list_kinds(): | |
| assert all(isinstance(target_name, str) for target_name in targets) | ||
|
|
||
|
|
||
| def test_target_host_tags(): | ||
| tgt = tvm.target.Target("nvidia/jetson-nano", "nvidia/geforce-rtx-2080-ti") | ||
| assert tgt.kind.name == "cuda" | ||
| assert tgt.attrs["arch"] == "sm_53" | ||
| assert tgt.attrs["shared_memory_per_block"] == 49152 | ||
| assert tgt.attrs["max_threads_per_block"] == 1024 | ||
| assert tgt.attrs["thread_warp_size"] == 32 | ||
| assert tgt.attrs["registers_per_block"] == 32768 | ||
| assert tgt.host.kind.name == "cuda" | ||
| assert tgt.host.attrs["arch"] == "sm_75" | ||
| assert tgt.host.attrs["shared_memory_per_block"] == 49152 | ||
| assert tgt.host.attrs["max_threads_per_block"] == 1024 | ||
| assert tgt.host.attrs["thread_warp_size"] == 32 | ||
| assert tgt.host.attrs["registers_per_block"] == 65536 | ||
|
|
||
|
|
||
| def test_target_host_tag_dict(): | ||
zxybazh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| tgt = tvm.target.Target("nvidia/jetson-nano", {"kind": "llvm"}) | ||
| assert tgt.kind.name == "cuda" | ||
| assert tgt.attrs["arch"] == "sm_53" | ||
| assert tgt.attrs["shared_memory_per_block"] == 49152 | ||
| assert tgt.attrs["max_threads_per_block"] == 1024 | ||
| assert tgt.attrs["thread_warp_size"] == 32 | ||
| assert tgt.attrs["registers_per_block"] == 32768 | ||
| assert tgt.host.kind.name == "llvm" | ||
|
|
||
|
|
||
| def test_target_host_single_dict(): | ||
| tgt = tvm.target.Target({"kind": "llvm", "host": "nvidia/jetson-nano"}) | ||
| assert tgt.kind.name == "llvm" | ||
| assert tgt.host.kind.name == "cuda" | ||
| assert tgt.host.attrs["arch"] == "sm_53" | ||
| assert tgt.host.attrs["shared_memory_per_block"] == 49152 | ||
| assert tgt.host.attrs["max_threads_per_block"] == 1024 | ||
| assert tgt.host.attrs["thread_warp_size"] == 32 | ||
| assert tgt.host.attrs["registers_per_block"] == 32768 | ||
|
|
||
|
|
||
| def test_target_host_single_string(): | ||
| tgt = tvm.target.Target("cuda --host llvm") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (putting this comment here, but this is not comment about this test, just wanted to pin it somewhere with a reference) I noticed there are some syntax changes in this. If this becomes (with this PR) our preferred way to declare the "target to target host" dependency, should we also update the tutorials to reflect that? |
||
| assert tgt.kind.name == "cuda" | ||
| assert tgt.host.kind.name == "llvm" | ||
|
|
||
|
|
||
| def test_target_host_single_string_with_tag(): | ||
| tgt = tvm.target.Target("cuda --host nvidia/jetson-nano") | ||
| assert tgt.kind.name == "cuda" | ||
| assert tgt.host.kind.name == "cuda" | ||
| assert tgt.host.attrs["arch"] == "sm_53" | ||
| assert tgt.host.attrs["shared_memory_per_block"] == 49152 | ||
| assert tgt.host.attrs["max_threads_per_block"] == 1024 | ||
| assert tgt.host.attrs["thread_warp_size"] == 32 | ||
| assert tgt.host.attrs["registers_per_block"] == 32768 | ||
|
|
||
|
|
||
| def test_target_host_warning(): | ||
| """ | ||
| Confirm that constructing a target with invalid | ||
| attributes fails as expected. | ||
| """ | ||
| with pytest.raises(ValueError): | ||
| tgt = tvm.target.Target("cuda --host nvidia/jetson-nano", "llvm") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| test_target_dispatch() | ||
| test_target_string_parse() | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.